[PYTHON] FX automatischer Handel mit genetischem Algorithmus Teil 2 Implementierung der sich entwickelnden Handels-KI

Vorheriger Artikel

Automatisches FX-Handelssystem mit Python und genetischem Algorithmus Teil 1

Dinge, die diesmal zu machen sind

In Teil 1 des letzten Males habe ich die grundlegende KI und den gesamten Mechanismus geschrieben, und diesmal habe ich eine komplizierte Kauf- und Verkaufs-KI und einen tatsächlich genetischen Algorithmus definiert Ich werde mich weiterentwickeln mit.

Definieren Sie komplexe Kauf- und Verkaufs-KI

■ Technische Daten Der aktuelle Marktpreis ist nach dem aktuellen Kurs, dem 4-Stunden-Durchschnittskurs, dem 24-Stunden-Durchschnittskurs, den höchsten und niedrigsten Preisen in den letzten 25 Geschäftstagen sowie den höchsten und niedrigsten Preisen in den letzten 25 Geschäftstagen in Muster unterteilt. Geben Sie eine entsprechende Bestellung aus 10 Jahren Handelsdaten auf (der entsprechende Wert wird durch einen genetischen Algorithmus berechnet und aus früheren Daten erhalten).

■ Betriebsbeispiel Währung: Dollar Yen Aktuelle Zeit: 1. Oktober 2015, 10:00:00 Uhr Aktueller Kurs: 120,00 Yen 4-Stunden-Durchschnittskurs: 119,80 Yen 24-Stunden-Durchschnittskurs: 119,40 Yen Höchster Preis in den letzten 25 Werktagen: 121,75 Yen Niedrigster Preis in den letzten 25 Werktagen: 117,25 Yen Seit dem höchsten Preis der letzten 25 Werktage sind Tage vergangen: 2 Tage Verstrichene Tage ab dem niedrigsten Preis in den letzten 25 Werktagen: 8 Tage Bestelldetails: 120 Yen für 100 Einheiten KAUFEN, Gewinnmitnahme 120,60 Yen, Verlustreduzierung 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)  #Tageskurs
    h4 = float(119.80)  #Durchschnittspreis für die letzten 4 Stunden
    h24 = float(119.40)  #Durchschnittspreis für die letzten 24 Stunden
    low_25d = float(117.25)  #Niedrigster Preis in den letzten 25 Werktagen
    high_25d = float(121.75)  #Höchster Preis in den letzten 25 Werktagen
    low_25d_passed_day = 8  #Wie viele Tage sind seit dem niedrigsten Preis in den letzten 25 Werktagen vergangen?
    high_25d_passed_day = 2  #Wie viele Tage sind seit dem höchsten Preis in den letzten 25 Werktagen vergangen?
    base_tick = float(0.01)  #Mindesthandelseinheit pro 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):
        """
Gibt einen Schlüssel zurück, der die Differenz zwischen der aktuellen Rate und dem Durchschnitt der letzten 24 Stunden darstellt
Beispiel) 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):
        """
Gibt den Schlüssel zurück, der die Differenz zwischen der aktuellen Rate und dem Durchschnitt der letzten 4 Stunden darstellt
Beispiel) 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):
        """
Gibt den Schlüssel zurück, der die Diskrepanz zwischen dem aktuellen Kurs und dem niedrigsten Preis in den letzten 25 Werktagen darstellt
Beispiel) 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):
        """
Gibt den Schlüssel zurück, der die Diskrepanz zwischen dem aktuellen Kurs und dem höchsten Preis in den letzten 25 Werktagen darstellt
Beispiel) 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):
        """
Wie viele Tage sind seit dem niedrigsten Preis in den letzten 25 Werktagen vergangen?
Beispiel) LOW_PASSED_DAY:10
        :rtype: str
        """
        return 'LOW_PASSED_DAY:{}'.format(self.rate.low_25d_passed_day)

    def get_key_high_passed_day(self):
        """
Wie viele Tage sind seit dem höchsten Preis in den letzten 25 Werktagen vergangen?
Beispiel) HIGH_PASSED_DAY:1
        :rtype: str
        """
        return 'HIGH_PASSED_DAY:{}'.format(self.rate.high_25d_passed_day)


class AIParamValue(object):
    """
Klasse, die AI-Betriebsdaten definiert
    """
    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):
    """
Klasse, die die Operation zum Zeitpunkt der Bestellung in den Operationsdaten von AI definiert
    """
    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
    #Speichern Sie die AI-Betriebsdaten
    param = {
        'DEFAULT_STANDARD_TICK': AIParamValue(DEFAULT_STANDARD_TICK, DEFAULT_MIN, DEFAULT_MAX)
    }

    def __init__(self, rate):
        self.rate = rate

    def order(self):
        """
Auftrag.
        """
        order(self._get_order())

    def get_key(self):
        """
Analysieren und klassifizieren Sie die Rate und generieren Sie den entsprechenden SCHLÜSSEL

        # 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):
        """
Auftragsklasse zurückgeben
        rtype: AIOrder
        """
        #Rate analysieren
        key = self.get_key()
        _o = self.param.get(key, None)
        if _o is None:
            #Nach dem Zufallsprinzip generieren und speichern, wenn keine AI-Bestelldaten vorhanden sind
            _o = self._get_random_order()
            self.param[key] = _o

        #Generierung von Auftragsdaten
        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):
        """
Generieren Sie nach dem Zufallsprinzip Anfangsdaten, wenn keine AI-Auftragsdaten vorhanden sind
        """
        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


#Rate erhalten
rate = Rate.get(currency='USDJPY', start_at=datetime.datetime.now())

#KI-Generation
ai = AI(rate)

#Auftrag
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}

Dieses Programm enthält zwei Punkte.

  1. AI implementiert den aktuellen Marktpreis nur durch Musterung
  2. Wenn die KI selbst keine Handelsdaten hat, definiert die Funktion _get_random_order das zufällige Verhalten von selbst.

Wenn Sie diese beiden Punkte unterdrücken, können Sie die sich selbst entwickelnde Logik mit dem genetischen Algorithmus im nächsten Abschnitt einfach und schön schreiben.

Seit 10 Jahren mit der erstellten Handels-KI zurückgetestet

Da der Kauf und Verkauf der KI abgeschlossen ist, werden wir einen Backtest mit den Daten der letzten 10 Jahre durchführen. Da es sich bei der KI der ersten Generation um eine zufällige Suche handelt, wurde eine traurige KI, die 1 Million Yen pro Jahr hauptsächlich gegen eine Gebühr verliert, bei Transaktionen in Einheiten von 10.000 Dollar geboren.

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, 
...
}

Der Inhalt der KI besteht aus Metadaten, die für den Menschen schwer zu handhaben sind. Wir werden diese KI mit einem genetischen Algorithmus weiterentwickeln.

Generieren Sie KI der nächsten Generation mit genetischen Algorithmen

■ Was ist ein genetischer Algorithmus? Der genetische Algorithmus geht ungefähr in den folgenden Fluss über. In diesem Abschnitt generieren wir die nächste Generation, indem wir 3 kreuzen.

  1. Anfängliche Bevölkerungsgenerierung
  2. Bewertung
  3. Generation der nächsten Generation durch Kreuzung
  4. Schleife in 2-3, um Generationen zu wiederholen.

■ Generation der nächsten Generation durch Kreuzung Für die Frequenzweiche wurden verschiedene Methoden vorgeschlagen, aber ich habe die Methode gewählt, die relativ bekannt ist und eine gute Berechnungseffizienz aufweist.

■ Spezifikationen für Kreuzungen und Generationen der nächsten Generation

  1. Verwenden Sie keinen Eliteismus (eine Auswahlmethode, bei der immer die besten Personen dieser Generation für die nächste Generation übrig bleiben).
  2. Eltern wählen nach Roulette-Auswahlmethode
  3. Kreuzen Sie zwei Eltern, um zwei Kinder zu zeugen
  4. Wenden Sie einen Zweipunkt-Crossover-Algorithmus für die Crossover an
  5. Es besteht eine 1% ige Wahrscheinlichkeit, dass Mutationen auftreten, wenn sich jedes Gen kreuzt
  6. Wenn jedes Gen kreuzt, besteht eine 85% ige Wahrscheinlichkeit, dass eine Zweipunktkreuzung auftritt.
  7. Es besteht eine Wahrscheinlichkeit von 14%, dass nichts passiert, wenn sich jedes Gen kreuzt
  8. Stellen Sie sicher, dass Sie 20 nächste Generation haben

■ Informationen zur Roulette-Auswahlmethode Beispiel) AI-1 macht einen Gewinn von 1 Million Yen AI-2 macht einen Gewinn von 500.000 Yen AI-3 macht einen Gewinn von 100.000 Yen Wann

Die Wahrscheinlichkeit, dass AI-1 als Elternteil ausgewählt wird, beträgt 100 / (100 + 50 + 10) = 62,5% Die Wahrscheinlichkeit, dass AI-2 als Elternteil ausgewählt wird, beträgt 50 / (100 + 50 + 10) = 31,25% Die Wahrscheinlichkeit, dass AI-3 als Elternteil ausgewählt wird, beträgt 10 / (100 + 50 + 10) = 6,55%

■ Informationen zum Zweipunkt-Crossover-Algorithmus Ich habe es unter Bezugnahme auf Einführung in genetische Algorithmen implementiert.

スクリーンショット 2015-10-02 14.47.51.png

■ Bitte seien Sie vorsichtig! Elternauswahl-, Crossover- und Mutationsmethoden haben einen erheblichen Einfluss auf die Leistung genetischer Algorithmen. Bitte wählen Sie die Methode mit großer Sorgfalt.

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):
    """
Zweipunktüberquerung
    :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)

    #Wenn es unter dem Minimalwert oder über dem Maximalwert liegt, wird es auf jeden Wert gerundet.
    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):
    """
Genetischen Algorithmus
Roulette-Auswahlmethode Wählen Sie die Punktzahl als Gewicht
    :param ai_group: list of AI
    :rtype : AI
    """
    #Verwenden Sie den Korrekturwert, wenn die Punktzahl negativ ist
    correct_value = min([ai.score(0) for ai in ai_group])
    if correct_value > 0:
        correct_value = 0

    #Berechnen Sie nach der Roulette-Auswahlmethode
    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):
        """
Kreuz
        :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):
    """
Klasse, die AI-Betriebsdaten definiert
    """
    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):
        """
Zweipunktüberquerung
        """
        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):
    """
Klasse, die die Operation zum Zeitpunkt der Bestellung in den Operationsdaten von AI definiert
    """
    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):
        """
Zweipunktüberquerung
        """
        a = self
        # order_Kreuztyp
        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

        #Grenzwert überschreiten
        limit_a, limit_b = cross_2point(a.limit, b.limit, a._min, a._max)
        a.limit = limit_a
        b.limit = limit_b

        # stop_Grenzwert überschreiten
        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):
        """
Genetischen Algorithmus
Cross-Blend
        """
        #Größe muss gerade sein
        if size % 2 != 0:
            raise AssertionError

        #Eliteismus(Verlasse die oberen 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]

        #Wählen Sie die Eltern nach der Roulette-Auswahlmethode aus und kreuzen Sie sie an
        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):
        """
Kreuzen Sie zwei Eltern und generieren Sie zwei Kinder
        :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)
            #Kreuz durch Gen.
            _a, _b = cls._cross_value(_value_a, _value_b)
            child_a_param[key] = _a
            child_b_param[key] = _b

        #Kind erzeugen
        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):
        """
Generieren Sie die nächste 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):
        """
Gene kreuzen
        :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:
            #Zweipunktüberquerung
            return value_a.cross_2point(value_b)
        else:
            #nichts tun
            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 "Nein.{}Generation AI PARAM:{}".format(self.generation, str(self.param))

    def score(self, correct_value):
        """
Geben Sie die Punktzahl des Back-Testergebnisses zurück
Vorteile während des gesamten Zeitraums

        :param correct_value: float
        :rtype : int
        """
        return self.profit - correct_value

    def get_random_order(self):
        """
Generieren Sie nach dem Zufallsprinzip Anfangsdaten, wenn keine AI-Auftragsdaten vorhanden sind
        """
        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

#Anfangsdaten testen
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 der KI der nächsten Generation
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~~~~~~~~~~~~~
AI PARAM der 1. Generation:{'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}
AI PARAM der 1. Generation:{'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}
AI PARAM der 1. Generation:{'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}
AI PARAM der 1. Generation:{'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~~~~~~~~~~~~~
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}
AI PARAM der 2. Generation:{'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}

Die Ergebnisse werden immer komplizierter. Der Test wird mit Ihren Augen schwieriger, also schreiben wir den Testcode richtig.

Spalte: KI, die Gewinn macht, auch wenn sie fehlerhaft ist

Was ist, wenn bei der Implementierung des Kauf- und Verkaufsteils ein Fehler vorliegt? Wenn Sie die Punktzahl des genetischen Algorithmus auf Handelsumsätze einstellen, werden die Parameter so optimiert, dass Sie mit Fehlern kaufen und verkaufen und mit Fehlern Gewinne erzielen können. In der Tat, KI, die einen Gewinn macht, selbst wenn es einen Fehler gibt. Anfangs war ich nicht ganz überzeugt. Und als ich den Fehler behoben habe, hat sich das Handelsergebnis geändert, sodass ich das Produktionssystem nicht stoppen konnte und in Schwierigkeiten war.

abschließend

In diesem Beitrag haben wir die Definition der komplexen Kauf- und Verkaufs-KI und die Entwicklung genetischer Algorithmen implementiert. Implementierung des automatischen Handels, Implementierung von Oanda-API-Aufrufen, Speicherung von KI, Aufzeichnung von Berechnungsergebnissen für jede Generation usw. Ich habe es noch nicht fertig geschrieben und möchte es in Teil 3 vorstellen.

Teil 3 habe ich geschrieben

Automatischer FX-Handel mit genetischem Algorithmus Teil 3 Tatsächlicher Handel mit Oanda API

In Verbindung stehender Artikel

Automatisches FX-Handelssystem mit Python und genetischem Algorithmus Teil 1 FX automatischer Handel mit genetischem Algorithmus Teil 2 Implementierung der sich entwickelnden Handels-KI Automatischer FX-Handel mit genetischem Algorithmus Teil 3 Tatsächlicher Handel mit Oanda API

Recommended Posts

FX automatischer Handel mit genetischem Algorithmus Teil 2 Implementierung der sich entwickelnden Handels-KI
FX automatischer Handel mit genetischem Algorithmus Teil 3 Tatsächlicher Handel mit Oanda API
Automatisches FX-Handelssystem mit Python und genetischem Algorithmus Teil 1
Finden Sie den optimalen Wert der Funktion mit einem genetischen Algorithmus (Teil 2)
Implementierung der Dyxtra-Methode durch Python
[Einfach] AI automatische Erkennung mit einer Webkamera!