Handschuh lehrt Sie, wie man eine Ma-Sprache-Strategie transplantiert (fortschrittlich)

Schriftsteller:Kleine Träume, Erstellt: 2019-11-13 09:15:56, aktualisiert: 2023-10-17 21:23:21

img

Handschuh lehrt Sie, wie man eine Ma-Sprache-Strategie transplantiert (fortschrittlich)

Vorheriger ArtikelDie Hand lehrt dich Strategien zu schreiben - eine My-Sprache-Strategie zu transplantieren.Wie kann man eine einfache Sprachstrategie in JavaScript transferieren, wenn es sich um eine etwas komplizierte Sprachstrategie handelt?

Wir wollen uns zunächst die Transplantationsstrategie anschauen:

(*backtest
start: 2019-05-01 00:00:00
end: 2019-11-12 00:00:00
period: 1d
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
args: [["SlideTick",10,126961],["ContractType","quarter",126961]]
*)

N1:=10;
N2:=21;
AP:=(HIGH+LOW+CLOSE)/3;
ESA:=EMA(AP,N1);
D:=EMA(ABS(AP-ESA),N1);
CI:=(AP-ESA)/(0.015*D);
TCI:=EMA(CI,N2);
WT1:TCI;
WT2:SMA(WT1,4,1);
AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;

Der erste Teil dieser Ma-Sprachstrategie(*backtest...*)Es handelt sich um die Konfigurationscode für die Wiederholungssysteme, um eine einheitliche Wiederholungskonfiguration zu erstellen. Diese Strategie ist auch eine Strategie zur zufälligen Suche und ist nicht zu kompliziert (verglichen mit dem vorherigen Artikel ein wenig komplizierter), ist jedoch eine eher repräsentative Strategie.EMASMA

Ein neues Rad

  • Die EMA Die Indikatorfunktion ist eine bereits vorhandene Indikatorbankfunktion, die direkt bei der Erstellung von Strategien in der JavaScript-Sprache der FMZ-Plattform zur Verfügung steht.TA.MA

  • SMA Was wir tun müssen, ist:SMADieser Indikator, den wir in FMZ's TA-Datei nicht unterstützen, unterscheidet sich auch von dem SMA-Indikator in der Talib-Datei:imgWie man sieht, gibt es einen Gewichtungsparameter neben dem Parameterbereich.

    Die Beschreibung der SMA-Indikatorfunktion in der talib-Bibliothek in der FMZ API-Dokumentation lautet:img

    Sie sehen.talib.SMADas ist ein einfacher gleitender Durchschnitt. Sie können sich nur selbst anfangen, eine Lösung zu finden.SMAAls Entwickler, der mit JavaScript Strategien schreibt, ist das eine der notwendigen Fähigkeiten, denn wenn man keine Fertigräder hat, dann muss man einfach einen bauen.

    Die Wahrheit ist, dass es nicht viel Forschung über Indikatoren gibt, und die meisten Menschen wissen nicht, was sie suchen.img

    Ich habe das Gefühl, dass dieser Algorithmus sehr zuverlässig ist, und ich habe versucht, ihn zu realisieren:

    function SMA (arr, n, m) {
        var sma = []
        var currSMA = null
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] && !isNaN(arr[i])) {
                if (!currSMA) {
                    currSMA = arr[i]
                    sma.push(currSMA)
                    continue
                }  
    
                // [M*C2+(N-M)*S1]/N
                currSMA = (m * arr[i] + (n - m) * currSMA) / n
                sma.push(currSMA)
            } else {
                sma.push(NaN)
            }
        }  
    
        return sma
    }
    

Schreiben Sie den Füllteil

Strategische RahmennutzungDie Hand lehrt dich Strategien zu schreiben - eine My-Sprache-Strategie zu transplantieren.Der Artikel ist in demselben Rahmen und besteht hauptsächlich aus zwei Teilen:img

Zunächst geht es um die Berechnung von Marktdaten und Indikatoren.img

Wir haben die Funktionen dieses Teils der Sprache Satz für Satz behandelt:

  • 1、AP:=(HIGH+LOW+CLOSE)/3;

    Dies kann verstanden werden, indem man die höchsten, niedrigsten und schließenden Preise für jede BAR in der K-Strangdatenmenge addiert und dann durch 3 dividiert, den Durchschnitt berechnet und als eine Array gespeichert wird, die für jede BAR eine Korrespondenz hat. Das kann man so machen:

    function CalcAP (r) {   // AP:=(HIGH+LOW+CLOSE)/3;
        var arrAP = []      // 声明一个空数组
    
        for (var i = 0; i < r.length; i++) {      // r为传入的K线数据,是一个数组,用for遍历这个数组
            v = (r[i].High + r[i].Low + r[i].Close) / 3      // 计算 平均值
            arrAP.push(v)                                    // 添加在 arrAP数组的尾部,arrAP是空的时候尾部就是第一个。
        }  
    
        return arrAP     // 返回 这个平均值数组,即麦语言中计算的 AP 
    }
    

    Sie können diese Funktion in der OnTick-Funktion im Hauptlauf aufrufen, z. B.:

    // 计算指标
    // AP
    var ap = CalcAP(records)
    
  • 2. Wenn die AP-Berechnung abgeschlossen ist, berechnen Sie weiter.ESA:=EMA(AP,N1);:

    Hier wird die ESA berechnet, indem man die AP-Daten verwendet, die in der letzten Stufe berechnet wurden, und die ESA ist der "index moving average" von AP, also der EMA-Indikator, also können wir die EMA berechnen, indem wir AP als Daten verwenden und N1 als Parameter des EMA-Indikators.

    function CalcESA (ap, n1) {   // ESA:=EMA(AP,N1);
        if (ap.length <= n1) {    // 如果AP的长度小于指标参数,是无法计算出有效数据的,这个时候让函数返回false。
            return false
        }  
    
        return TA.EMA(ap, n1)
    }
    
  • 3、D:=EMA(ABS(AP-ESA),N1);

    Mit Hilfe der BerechnungAPESABerechnungenDIch bin nicht derjenige. Hier finden Sie die Code-Anmerkungen und einige Tipps für die Berechnung von Indikatoren.

    function CalcD (ap, esa, n1) {    // D:=EMA(ABS(AP-ESA),N1);
        var arrABS_APminusESA = []
        if (ap.length != esa.length) {
            throw "ap.length != esa.length"
        }  
    
        for (var i = 0; i < ap.length; i++) {
            // 计算指标数值时,必须判断一下数据的有效性,因为前几次EMA计算可能数组中的开始部分的数据是NaN,或者null
            // 所以必须判断,参与计算的数据都是有效数值才能进行,如果有任何无效数值,就用NaN向arrABS_APminusESA填充
            // 这样计算得到的数据,每个位置和之前的数据都是一一对应的,不会错位。
            if (ap[i] && esa[i] && !isNaN(ap[i]) && !isNaN(esa[i])) {
                v = Math.abs(ap[i] - esa[i])     // 根据ABS(AP-ESA) , 具体计算数值,然后放入arrABS_APminusESA数组
                arrABS_APminusESA.push(v)
            } else {
                arrABS_APminusESA.push(NaN)
            }
        }  
    
        if (arrABS_APminusESA.length <= n1) {
            return false
        }  
    
        return TA.EMA(arrABS_APminusESA, n1)    // 计算数组arrABS_APminusESA的EMA指标,得到数据D(数组结构)
    }
    
  • 4、CI:=(AP-ESA)/(0.015*D);Diese Methode ist ähnlich wie in Schritt 1, indem man den Code direkt auslässt.

    function CalcCI (ap, esa, d) {    // CI:=(AP-ESA)/(0.015*D);
        var arrCI = []
        if (ap.length != esa.length || ap.length != d.length) {
            throw "ap.length != esa.length || ap.length != d.length"
        }
        for (var i = 0; i < ap.length; i++) {
            if (ap[i] && esa[i] && d[i] && !isNaN(ap[i]) && !isNaN(esa[i]) && !isNaN(d[i])) {
                v = (ap[i] - esa[i]) / (0.015 * d[i])
                arrCI.push(v)
            } else {
                arrCI.push(NaN)
            }
        }  
    
        if (arrCI.length == 0) {
            return false
        }  
    
        return arrCI
    }
    
  • TCI: = EMA ((CI, N2)); Die EMA-Anzeige für die CI-Array wird nur berechnet.

    function CalcTCI (ci, n2) {   // TCI:=EMA(CI,N2);
        if (ci.length <= n2) {
            return false
        }  
    
        return TA.EMA(ci, n2)
    }
    
  • WT2:SMA(WT1,4,1);

    Der letzte Schritt, den wir machen, ist ein Rad, das wir vorher gemacht haben.SMADie Funktion.

    function CalcWT2 (wt1) {    // WT2:SMA(WT1,4,1);
        if (wt1.length <= 4) {
            return false 
        }  
    
        return SMA(wt1, 4, 1)   // 使用我们自己实现的SMA函数计算出wt1的SMA指标。
    }
    

Das Transportieren von Transaktionssignalen ist sehr einfach.

AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;

Wenn man diese Code-Sätze lesen kann, kann man erkennen, dass die beiden Indikatorlinien WT1 und WT2 als Gold- und Toten-Fenkel beurteilt werden. Es ist wichtig zu beachten, dass das erste Kreuzsignal verwendet wird. In den letzten Jahren hat sich die Sprache in den meisten Ländern der Welt verändert.img

Durch die praktische Ausführung der Ma-Sprache-Strategie kann beobachtet werden, dass bei der Detektion des Signals des Öffnungspunktes tatsächlich die Position des Öffnungspunktes BAR vor den vorherigen 2 BARs als Goldvierk erkannt wird.img img

Der Füllcode für den Signal-Detection-Teil kann geschrieben werden:

if ((_State == IDLE || _State == SHORT) && wt1[wt1.length - 4] < wt2[wt2.length - 4] && wt1[wt1.length - 3] > wt2[wt2.length - 3]) {
    if (_State == IDLE) {
        _State = OPENLONG
        Log("OPENLONG")    // 测试
    }
    if (_State == SHORT) {
        _State = COVERSHORT
        Log("COVERSHORT")  // 测试
    }
    isOK = false  
}

if ((_State == IDLE || _State == LONG) && wt1[wt1.length - 4] > wt2[wt2.length - 4] && wt1[wt1.length - 3] < wt2[wt2.length - 3]) {
    if (_State == IDLE) {
        _State = OPENSHORT
        Log("OPENSHORT")  // 测试
    }
    if (_State == LONG) {
        _State = COVERLONG
        Log("COVERLONG")  // 测试
    }
    isOK = false   
}

Hier kann man darüber nachdenken, warum die SPK- und BPK-Instruktionen in der Maisch-Sprache mit diesem Code realisiert werden können.

Wiederholung

Die Konfiguration wird überprüft:img

Der Ma-Sprache-Version:img

JavaScript-Version überprüft:img img

Der Code am Anfang der OnTick-Funktion, der verwendet wird, um die Wiederholungsgeschwindigkeit ein wenig zu beschleunigen, ist, um die Strategie in einem Schlusspreismodell zu betreiben, was interessant ist.

function OnTick(){
    // 驱动策略的行情处理部分
    var records = _C(exchange.GetRecords)
    if (records[records.length - 1].Time == preTime) {
        if (isOK) {
            Sleep(500)
            return 
        }
    } else {
        preTime = records[records.length - 1].Time
    }
    ...
    ..
    .

Der vollständige Code der Lehrstrategie:https://www.fmz.com/strategy/174457

Danke fürs Lesen.


Verwandt

Mehr