FX automatic trading system made with python and genetic algorithm part 1
In Part 1 of the last time, I wrote the basic AI and the whole mechanism, so this time I defined a complicated trading AI and actually genetic algorithm I will evolve it with.
■ Specifications The current market price is divided into patterns according to the current rate, 4-hour average rate, 24-hour average rate, highest and lowest prices in the last 25 business days, and the highest and lowest prices in the last 25 business days. Place an appropriate order from 10 years of trading data (appropriate value is calculated by genetic algorithm and obtained from past data).
■ Operation example Currency: Dollar Yen Current time: October 1, 2015 10:00:00 Current rate: 120.00 yen 4-hour average rate: 119.80 yen 24-hour average rate: 119.40 yen Highest price in the last 25 business days: 121.75 yen Lowest price in the last 25 business days: 117.25 yen Days elapsed from the highest price in the last 25 business days: 2 days Elapsed days from the lowest price in the last 25 business days: 8 days Order details: 120 yen for 100 units BUY, profit taking 120.60 yen, loss cut 119.75 yen
genetic.py
# -*- coding: utf-8 -*-
import random
import datetime
from enum import Enum
def order(ai_order):
_base = "OrderDone:{}, Limit:{}, Stop-Limit:{}"
print _base.format(ai_order.order_type,
ai_order.limit,
ai_order.stop_limit)
class OrderType(Enum):
Buy = 1
Wait = 0
Sell = -1
class Rate(object):
start_at = datetime.datetime(2015, 10, 1, 10, 0, 0)
bid = float(120.00) #Current rate
h4 = float(119.80) #Average rate for the last 4 hours
h24 = float(119.40) #Average rate for the last 24 hours
low_25d = float(117.25) #Lowest price in the last 25 business days
high_25d = float(121.75) #Highest price in the last 25 business days
low_25d_passed_day = 8 #How many days have passed since the lowest price in the last 25 business days
high_25d_passed_day = 2 #How many days have passed since the highest price in the last 25 business days
base_tick = float(0.01) #Minimum trading unit per tick
@classmethod
def get(cls, currency=None, start_at=None):
return Rate()
def get_rate(self, tick, is_add):
if is_add:
return self.bid + float(tick * self.base_tick)
else:
return self.bid - float(tick * self.base_tick)
class AIOrder(object):
def __init__(self, order_type, limit, stop_limit):
self.order_type = order_type
self.limit = limit
self.stop_limit = stop_limit
class MarketKeyMixin(object):
def get_key_h24(self):
"""
Returns a key that represents the difference between the current rate and the average over the last 24 hours
Example) H24:5
:rtype: str
"""
point = (self.rate.bid - self.rate.h24) / self.rate.base_tick
return 'H24:{}'.format(int(point / self.standard_tick))
def get_key_h4(self):
"""
Returns a key that represents the difference between the current rate and the average of the last 4 hours
Example) H4:0
:rtype: str
"""
point = (self.rate.bid - self.rate.h4) / self.rate.base_tick
return 'H4:{}'.format(int(point / self.standard_tick))
def get_key_low_25d(self):
"""
Returns a key that represents the discrepancy between the current rate and the lowest price in the last 25 business days
Example) LOW:3
:rtype: str
"""
point = (self.rate.bid - self.rate.low_25d) / self.rate.base_tick
return 'LOW:{}'.format(int(point / self.standard_tick))
def get_key_high_25d(self):
"""
Returns the key that represents the discrepancy between the current rate and the highest price in the last 25 business days
Example) HIGH:2
:rtype: str
"""
point = (self.rate.bid - self.rate.high_25d) / self.rate.base_tick
return 'HIGH:{}'.format(int(point / self.standard_tick))
def get_key_low_passed_day(self):
"""
How many days have passed since the lowest price in the last 25 business days
Example) LOW_PASSED_DAY:10
:rtype: str
"""
return 'LOW_PASSED_DAY:{}'.format(self.rate.low_25d_passed_day)
def get_key_high_passed_day(self):
"""
How many days have passed since the highest price in the last 25 business days
Example) HIGH_PASSED_DAY:1
:rtype: str
"""
return 'HIGH_PASSED_DAY:{}'.format(self.rate.high_25d_passed_day)
class AIParamValue(object):
"""
Class that defines AI operation data
"""
def __init__(self, value, _min, _max):
self.value = value
self._min = _min
self._max = _max
def __repr__(self):
return "VALUE:{},MIN:{},MAX:{}".format(self.value,
self._min,
self._max)
def mutation(self):
"""
mutation
"""
self.value = random.randint(self._min, self._max)
return self
class AIParamOrder(object):
"""
Class that defines the operation at the time of ordering in the AI operation data
"""
def __init__(self, order_type, limit, stop_limit, _min, _max):
self.order_type = order_type
self.limit = limit
self.stop_limit = stop_limit
self._min = _min
self._max = _max
def __repr__(self):
_base = "ORDER-TYPE:{},LIMIT:{},STOP-LIMIT:{},MIN:{},MAX:{}"
return _base.format(self.order_type,
self.limit,
self.stop_limit,
self._min,
self._max)
def mutation(self):
"""
mutation
"""
self.order_type = random.choice(list(OrderType))
self.limit = random.randint(self._min, self._max)
self.stop_limit = random.randint(self._min, self._max)
return self
class AI(MarketKeyMixin):
DEFAULT_STANDARD_TICK = 30
DEFAULT_MIN = 15
DEFAULT_MAX = 120
#Save AI operation data
param = {
'DEFAULT_STANDARD_TICK': AIParamValue(DEFAULT_STANDARD_TICK, DEFAULT_MIN, DEFAULT_MAX)
}
def __init__(self, rate):
self.rate = rate
def order(self):
"""
Order.
"""
order(self._get_order())
def get_key(self):
"""
Analyze and classify Rate and generate appropriate KEY
# sample
'H24:5,H4:0,LOW:4,LOW_PASSED_DAY:3,HIGH:3,HIGH_PASSED_DAY:6'
"""
_base = [self.get_key_h24(),
self.get_key_h4(),
self.get_key_low_25d(),
self.get_key_high_25d(),
self.get_key_low_passed_day(),
self.get_key_high_passed_day()]
return ",".join(_base)
def _get_order(self):
"""
Return order class
rtype: AIOrder
"""
#Analyze Rate
key = self.get_key()
_o = self.param.get(key, None)
if _o is None:
#Randomly generate and save when AI order data does not exist
_o = self._get_random_order()
self.param[key] = _o
#Generation of order data
limit_rate = self.rate.get_rate(_o.limit, True)
stop_limit_rate = self.rate.get_rate(_o.stop_limit, False)
return AIOrder(_o.order_type, limit_rate, stop_limit_rate)
def _get_random_order(self):
"""
Randomly generate initial data when AI order data does not exist
"""
return AIParamOrder(random.choice(list(OrderType)),
0,
0,
self.DEFAULT_MIN,
self.DEFAULT_MAX).mutation()
def _get_order_type(self):
if self.rate.bid > self.rate.h24:
return OrderType.Buy
if self.rate.h24 > self.rate.bid:
return OrderType.Sell
return OrderType.Wait
@property
def standard_tick(self):
return self.param.get('DEFAULT_STANDARD_TICK').value
#Get rate
rate = Rate.get(currency='USDJPY', start_at=datetime.datetime.now())
#AI generation
ai = AI(rate)
#Order
ai.order()
print ai.param
>>python genetic.py
>>OrderDone:OrderType.Sell, Limit:122.37, Stop-Limit:117.22
>>{'DEFAULT_STANDARD_TICK': VALUE:30,MIN:10,MAX:400, 'H24:1,H4:0,LOW:9,HIGH:-5,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:237,STOP-LIMIT:278,MIN:10,MAX:400}
There are two points in this program.
If you suppress these two points, you will be able to easily and beautifully write the self-evolving logic by the genetic algorithm in the next section.
Since the trading AI has been completed, we will carry out a back test with the data for the past 10 years. Since the first generation AI will be a random search, a sad AI that will lose 1 million yen per year mainly for commissions has been born in transactions in units of 10,000 dollars.
genetic.py
print ai.param
{
'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Wait,LIMIT:66,STOP-LIMIT:71,MIN:15,MAX:120,
'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:29,STOP-LIMIT:23,MIN:15,MAX:120,
'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:86,STOP-LIMIT:35,MIN:15,MAX:120,
'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:98,STOP-LIMIT:76,MIN:15,MAX:120,
'H24:-3,H4:0,LOW:12,HIGH:-2,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:78,STOP-LIMIT:64,MIN:15,MAX:120,
'H24:0,H4:0,LOW:9,HIGH:-5,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:92,STOP-LIMIT:62,MIN:15,MAX:120,
'H24:-3,H4:0,LOW:5,HIGH:-9,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:82,STOP-LIMIT:115,MIN:15,MAX:120,
'H24:0,H4:-3,LOW:0,HIGH:-15,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:108,STOP-LIMIT:109,MIN:15,MAX:120,
'H24:3,H4:-3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:100,STOP-LIMIT:42,MIN:15,MAX:120,
'H24:-3,H4:0,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:63,STOP-LIMIT:72,MIN:15,MAX:120,
'H24:3,H4:0,LOW:9,HIGH:-5,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Wait,LIMIT:64,STOP-LIMIT:89,MIN:15,MAX:120,
'H24:0,H4:0,LOW:5,HIGH:-9,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:94,STOP-LIMIT:16,MIN:15,MAX:120,
'H24:3,H4:-3,LOW:5,HIGH:-9,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Wait,LIMIT:50,STOP-LIMIT:117,MIN:15,MAX:120,
'H24:0,H4:3,LOW:9,HIGH:-5,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:112,STOP-LIMIT:24,MIN:15,MAX:120,
'H24:3,H4:0,LOW:-10,HIGH:-25,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:74,STOP-LIMIT:50,MIN:15,MAX:120,
'H24:3,H4:3,LOW:-10,HIGH:-25,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:20,STOP-LIMIT:111,MIN:15,MAX:120,
...
}
The contents of AI are composed of meta data that is difficult for humans to handle. We will evolve this AI with a genetic algorithm.
■ What is a genetic algorithm? The genetic algorithm roughly transitions in the following flow. In this section, we will generate the next generation by crossing 3.
■ Generation of the next generation by crossing Various methods have been proposed for crossover, but I chose the method that is relatively famous and has good calculation efficiency.
■ Specifications for crossover and next-generation generation
■ About roulette selection method Example) AI-1 makes a profit of 1 million yen AI-2 makes a profit of 500,000 yen AI-3 makes a profit of 100,000 yen When
The probability that AI-1 will be selected as a parent is 100 / (100 + 50 + 10) = 62.5% The probability that AI-2 will be selected as a parent is 50 / (100 + 50 + 10) = 31.25% The probability that AI-3 will be selected as a parent is 10 / (100 + 50 + 10) = 6.55%
■ About the two-point crossover algorithm I implemented it by referring to Introduction to Genetic Algorithms.
■ Please be careful! Parent selection, crossover, and mutation methods have a significant impact on the performance of genetic algorithms. Please choose the method with great care.
genetic_mixin.py
# -*- coding: utf-8 -*-
import random
import datetime
from enum import Enum
def mutation(_min, _max):
"""
mutation
:param _min: int
:param _max: int
"""
return random.randint(_min, _max)
def cross_2point(a, b, _min, _max):
"""
Two-point crossing
:param a: int
:param b: int
"""
a = format(a, 'b')
b = format(b, 'b')
max_length = max([len(a), len(b)])
if len(a) < max_length:
a = '0' * (max_length - len(a)) + a
if len(b) < max_length:
b = '0' * (max_length - len(b)) + b
point1 = random.randint(1, max_length)
point2 = random.randint(1, max_length)
point_max = max(point1, point2)
point_min = min(point1, point2)
_a = a[:point_min] + b[point_min:point_max] + a[point_max:]
_b = b[:point_min] + a[point_min:point_max] + b[point_max:]
_a_point = int(_a, 2)
_b_point = int(_b, 2)
#Round to each value when it is below the minimum value or above the maximum value
def adjust(value, _min, _max):
if value > _max:
return _max
if value < _min:
return _min
return value
_a_point = adjust(_a_point, _min, _max)
_b_point = adjust(_b_point, _min, _max)
return _a_point, _b_point
def roulette_selection(ai_group):
"""
Genetic algorithm
Roulette selection method Select score as weight
:param ai_group: list of AI
:rtype : AI
"""
#Use the correction value when the score is negative
correct_value = min([ai.score(0) for ai in ai_group])
if correct_value > 0:
correct_value = 0
#Calculate with the roulette selection method
total = sum([ai.score(correct_value) for ai in ai_group])
r = random.randint(0, total)
_total = 0
for ai in ai_group:
_total += ai.score(correct_value)
if r <= _total:
return ai
raise ValueError
class OrderType(Enum):
Buy = 1
Wait = 0
Sell = -1
@classmethod
def cross_2point(cls, a, b):
"""
Cross
:param a: OrderType
:param b: OrderType
"""
value_a, value_b = cross_2point(a.value + 1, b.value + 1, 0, 2)
a_value = cls(value_a - 1)
b_value = cls(value_b - 1)
return a_value, b_value
class AIParamValue(object):
"""
Class that defines AI operation data
"""
def __init__(self, value, _min, _max):
self.value = value
self._min = _min
self._max = _max
def __repr__(self):
return "VALUE:{},MIN:{},MAX:{}".format(self.value,
self._min,
self._max)
def cross_2point(self, b):
"""
Two-point crossing
"""
a = self
value_a, value_b = cross_2point(a.value, b.value, a._min, a._max)
a.value = value_a
b.value = value_b
return a, b
def mutation(self):
"""
mutation
"""
self.value = random.randint(self._min, self._max)
return self
class AIParamOrder(object):
"""
Class that defines the operation at the time of ordering in the AI operation data
"""
def __init__(self, order_type, limit, stop_limit, _min, _max):
self.order_type = order_type
self.limit = limit
self.stop_limit = stop_limit
self._min = _min
self._max = _max
def __repr__(self):
_base = "ORDER-TYPE:{},LIMIT:{},STOP-LIMIT:{},MIN:{},MAX:{}"
return _base.format(self.order_type,
self.limit,
self.stop_limit,
self._min,
self._max)
def cross_2point(self, b):
"""
Two-point crossing
"""
a = self
# order_Cross type
order_type_a, order_type_b = OrderType.cross_2point(a.order_type, b.order_type)
a.order_type = order_type_a
b.order_type = order_type_b
#Cross limit
limit_a, limit_b = cross_2point(a.limit, b.limit, a._min, a._max)
a.limit = limit_a
b.limit = limit_b
# stop_Cross limit
stop_limit_a, stop_limit_b = cross_2point(a.stop_limit, b.stop_limit, a._min, a._max)
a.stop_limit = stop_limit_a
b.stop_limit = stop_limit_b
return a, b
def mutation(self):
"""
mutation
"""
self.order_type = random.choice(list(OrderType))
self.limit = random.randint(self._min, self._max)
self.stop_limit = random.randint(self._min, self._max)
return self
class GeneticMixin(object):
@classmethod
def cross_over(cls, size, ai_group):
"""
Genetic algorithm
Cross-blend
"""
#size must be even
if size % 2 != 0:
raise AssertionError
#Elitism(Leave the top 3)
# elite_group = sorted(ai_group, key=lambda x: x.score(0), reverse=True)[:3]
# elite_group = copy.deepcopy(elite_group)
# elite_group = [ai.incr_generation() for ai in elite_group]
#Select parents by roulette selection method and cross
next_ai_group = []
while len(next_ai_group) != size:
next_ai_group += cls._cross(roulette_selection(ai_group),
roulette_selection(ai_group))
return next_ai_group
@classmethod
def _cross(cls, ai_a, ai_b):
"""
Crossing two parents to produce two children
:param ai_a: AI
:param ai_b: AI
:return: list of AI
"""
#Incr generation
generation = ai_a.generation + 1
child_a_param = {}
child_b_param = {}
for key in ai_a.param:
_value_a = ai_a.param.get(key)
_value_b = ai_b.param.get(key)
#Cross for each gene
_a, _b = cls._cross_value(_value_a, _value_b)
child_a_param[key] = _a
child_b_param[key] = _b
#Generate child
child_a = cls.create_child(child_a_param, generation)
child_b = cls.create_child(child_b_param, generation)
return [child_a, child_b]
@classmethod
def create_child(cls, param, generation):
"""
Generate the next generation
:param param: dict
:param generation: int
:rtype: cls
"""
ai = cls()
ai.param = param
ai.generation = generation
return ai
@classmethod
def _cross_value(cls, value_a, value_b):
"""
Cross genes
:param value_a: AIParamValue or AIParamOrder
:param value_b: AIParamValue or AIParamOrder
:return: int or list
"""
if random.randint(1, 100) == 1:
#mutation
return value_a.mutation(), value_a.mutation()
elif random.randint(1, 100) <= 85:
#Two-point crossing
return value_a.cross_2point(value_b)
else:
#do nothing
return value_a, value_b
class AI(GeneticMixin):
DEFAULT_STANDARD_TICK = 30
DEFAULT_MIN = 15
DEFAULT_MAX = 120
param = {}
generation = 0 #generation
def __repr__(self):
return "No.{}Generation AI PARAM:{}".format(self.generation, str(self.param))
def score(self, correct_value):
"""
Return the score of the back test result
Profit throughout the period
:param correct_value: float
:rtype : int
"""
return self.profit - correct_value
def get_random_order(self):
"""
Randomly generate initial data when AI order data does not exist
"""
return AIParamOrder(random.choice(list(OrderType)),
0,
0,
self.DEFAULT_MIN,
self.DEFAULT_MAX).mutation()
def gen_random_ai_parame():
param = {
'DEFAULT_STANDARD_TICK': AIParamValue(AI.DEFAULT_STANDARD_TICK, AI.DEFAULT_MIN, AI.DEFAULT_MAX),
'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': AI().get_random_order(),
'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': AI().get_random_order(),
'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': AI().get_random_order(),
'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': AI().get_random_order(),
}
return param
#Test initial data
print '~~~~~~~~~~~~~TEST DATA~~~~~~~~~~~~~'
ai1 = AI.create_child(gen_random_ai_parame(), 1)
ai1.profit = 100 * 10000
print ai1
ai2 = AI.create_child(gen_random_ai_parame(), 1)
ai2.profit = 50 * 10000
print ai2
ai3 = AI.create_child(gen_random_ai_parame(), 1)
ai3.profit = -100 * 10000
print ai3
ai4 = AI.create_child(gen_random_ai_parame(), 1)
ai4.profit = -500 * 10000
print ai4
ai_group = [ai1, ai2, ai3, ai4]
#Generation of next-generation AI
print '~~~~~~~~~~~~~RESULT~~~~~~~~~~~~~'
ai_group_next_generation = AI.cross_over(20, ai_group)
for ai in ai_group_next_generation:
print ai
>>python genetic_mixin.py
~~~~~~~~~~~~~TEST DATA~~~~~~~~~~~~~
1st generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:32,STOP-LIMIT:120,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:99,STOP-LIMIT:25,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Wait,LIMIT:30,STOP-LIMIT:20,MIN:15,MAX:120}
1st generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:94,STOP-LIMIT:112,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Wait,LIMIT:24,STOP-LIMIT:101,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:66,STOP-LIMIT:79,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:78,STOP-LIMIT:81,MIN:15,MAX:120}
1st generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Wait,LIMIT:94,STOP-LIMIT:35,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:103,STOP-LIMIT:112,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:18,STOP-LIMIT:38,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:20,STOP-LIMIT:89,MIN:15,MAX:120}
1st generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Wait,LIMIT:42,STOP-LIMIT:20,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:46,STOP-LIMIT:76,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:104,STOP-LIMIT:43,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:40,STOP-LIMIT:109,MIN:15,MAX:120}
~~~~~~~~~~~~~RESULT~~~~~~~~~~~~~
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Wait,LIMIT:92,STOP-LIMIT:48,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:111,STOP-LIMIT:113,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:15,STOP-LIMIT:38,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:15,STOP-LIMIT:89,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:94,STOP-LIMIT:99,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:15,STOP-LIMIT:120,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:98,STOP-LIMIT:79,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:86,STOP-LIMIT:81,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:94,STOP-LIMIT:99,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:15,STOP-LIMIT:120,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:98,STOP-LIMIT:79,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:86,STOP-LIMIT:81,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:94,STOP-LIMIT:99,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:15,STOP-LIMIT:120,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:98,STOP-LIMIT:79,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:86,STOP-LIMIT:81,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:94,STOP-LIMIT:99,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:15,STOP-LIMIT:120,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:98,STOP-LIMIT:79,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:86,STOP-LIMIT:81,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:94,STOP-LIMIT:99,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:15,STOP-LIMIT:120,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:98,STOP-LIMIT:79,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:86,STOP-LIMIT:81,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:94,STOP-LIMIT:99,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:15,STOP-LIMIT:120,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:98,STOP-LIMIT:79,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:86,STOP-LIMIT:81,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Wait,LIMIT:92,STOP-LIMIT:48,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:111,STOP-LIMIT:113,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:15,STOP-LIMIT:38,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:15,STOP-LIMIT:89,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:94,STOP-LIMIT:99,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:15,STOP-LIMIT:120,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:98,STOP-LIMIT:79,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:86,STOP-LIMIT:81,MIN:15,MAX:120}
2nd generation AI PARAM:{'H24:-3,H4:3,LOW:-7,HIGH:-22,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:30,STOP-LIMIT:83,MIN:15,MAX:120, 'H24:3,H4:3,LOW:-4,HIGH:-19,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:55,STOP-LIMIT:96,MIN:15,MAX:120, 'DEFAULT_STANDARD_TICK': VALUE:30,MIN:15,MAX:120, 'H24:0,H4:3,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Buy,LIMIT:83,STOP-LIMIT:31,MIN:15,MAX:120, 'H24:0,H4:0,LOW:2,HIGH:-12,LOW_PASSED_DAY:8,HIGH_PASSED_DAY:2': ORDER-TYPE:OrderType.Sell,LIMIT:28,STOP-LIMIT:20,MIN:15,MAX:120}
The results are getting more complicated. The test will be tougher with your eyes, so let's write the test code properly.
What if the trading part implementation has a bug? If you set the score of the genetic algorithm to trading revenue, the parameters will be optimized so that you can buy and sell with bugs and earn profits with bugs. In fact, AI that makes a profit even if there is a bug. At first, I wasn't quite convinced. And when I fixed the bug, the trading result changed, so I couldn't stop the production system and I was in trouble.
In this post, we have implemented the definition of complex trading AI and the evolution of genetic algorithms. Implementation of automatic trading, implementation of Oanda API call, saving of AI, recording of calculation results for each generation, etc. I haven't written it yet, so I'd like to introduce it in Part 3.
Forex automatic trading with genetic algorithm Part 3 Actual trading with Oanda API
FX automatic trading system made with python and genetic algorithm part 1 Forex automatic trading with genetic algorithm Part 2 Evolving trading AI implementation Forex automatic trading with genetic algorithm Part 3 Actual trading with Oanda API
Recommended Posts