Sumber dimuat naik... memuat...

Mengajar anda untuk menulis strategi - pemindahan strategi MyLanguage (Advanced)

Penulis:FMZ~Lydia, Dicipta: 2022-12-26 18:56:00, Dikemas kini: 2023-09-20 09:46:34

img

Mengajar anda menulis strategi menanam strategi MyLanguage (Langsung)

Dalam artikel sebelumnyaMengajar anda untuk menulis strategi - menanam strategi MyLanguage, strategi MyLanguage yang mudah telah diuji untuk pemindahan. Jika ia adalah MyLanguage yang lebih kompleks, bagaimana ia boleh dipindahkan ke dalam strategi bahasa JavaScript?

Mari kita lihat strategi untuk dipindahkan terlebih dahulu:

(*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;

Peraturan(* backtest... *)pada permulaan strategi MyLanguage adalah kod konfigurasi untuk tetapan backtesting. Untuk memudahkan perbandingan, konfigurasi backtesting bersatu ditetapkan. Strategi ini juga rawak, yang tidak terlalu kompleks (lebih kompleks daripada yang dalam artikel sebelumnya). Ini adalah strategi perwakilan. Untuk memindahkan strategi MyLanguage, anda harus melihat keseluruhan strategi terlebih dahulu. Kod strategi ringkas, dan anda boleh mempunyai pemahaman tertentu tentang keseluruhan strategi. Untuk strategi ini, kita telah melihat bahawa beberapa fungsi penunjukEMA, SMAtelah digunakan:

Buat roda dulu.

  • EMA Fungsi penunjuk, terdapat fungsi perpustakaan penunjuk siap sedia yang tersedia secara langsung di platform FMZ apabila menulis strategi dalam bahasa JavaScript.TA.MA.

  • SMA Apa yang kita perlu lakukan adalahSMApenunjuk, yang kami dapati dalam perpustakaan TA FMZ tidak menyokong fungsi penunjuk SMA, dan terdapat perbezaan antara penunjuk SMA dalam perpustakaan talib dan yang dalam MyLanguage.

img

Seperti yang kita lihat, bahagian parameter mempunyai parameter berat selain parameter tempoh.

Fungsi penunjuk SMA dalam perpustakaan talib dalam dokumentasi FMZ API digambarkan sebagai berikut:

img

Ia boleh dilihat bahawatalib.SMAadalah penunjuk purata bergerak yang mudah. Dengan cara ini, kita hanya boleh melaksanakan SMA sendiri. Sebagai pemaju yang menggunakan bahasa JavsScript untuk menulis strategi, ini juga merupakan salah satu kemahiran yang diperlukan. Lagipun, jika tidak ada roda siap, program masih perlu dijalankan, hanya membina satu.

Sebenarnya, tidak banyak penyelidikan mengenai penunjuk dan sebagainya.Secara amnya, orang mencari maklumat jika mereka tidak memahaminya.Untuk SMA mencari ini:

img

Nampaknya proses algoritma teori ini agak boleh dipercayai, dan pelaksanaannya adalah seperti berikut:

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
}

Menulis bahagian penuh

Rangka strategi menggunakan kerangka yang sama seperti dalam artikelMengajar anda untuk menulis strategi - menanam strategi MyLanguagedan terutamanya diisi dalam dua bahagian:

Pertama, buat pemprosesan data ticker dan pengiraan indeks.

img

Mari kita mengambil bahagian ini MyLanguage satu ayat pada satu masa, fungsi oleh fungsi:

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

Ia boleh difahami bahawa harga tertinggi, harga terendah dan harga penutupan setiap BAR dalam data baris K harus ditambahkan dan kemudian dibahagikan dengan 3 untuk mengira nilai purata, dan kemudian disimpan sebagai array, yang sepadan dengan setiap BAR satu demi satu. Ia boleh diproses seperti berikut:

function CalcAP (r) {   // AP:=(HIGH+LOW+CLOSE)/3;
    var arrAP = []      // Declare an empty array

    for (var i = 0; i < r.length; i++) {      // r is the incoming K-line data, which is an array, use for to traverse this array.
        v = (r[i].High + r[i].Low + r[i].Close) / 3      // Calculate the average value.
        arrAP.push(v)                                    // Add to the end of the arrAP array, the end is the first when arrAP is empty.
    }  

    return arrAP     // Returns this average array, i.e., the AP calculated in the MyLanguage 
}

Fungsi ini boleh dipanggil dalam fungsi OnTick gelung utama, sebagai contoh:

// Calculation of indicators
// AP
var ap = CalcAP(records)
    1. Selepas pengiraan AP selesai, teruskan untuk mengiraESA:=EMA(AP,N1);:

Di sini, kita akan menggunakan data AP yang dikira dalam langkah sebelumnya untuk mengira ESA. sebenarnya, ESA adalah peratus bergerak eksponensial AP, iaitu penunjuk EMA. jadi kita akan menggunakan AP sebagai data dan N1 sebagai parameter penunjuk EMA untuk mengira penunjuk EMA.

function CalcESA (ap, n1) {   // ESA:=EMA(AP,N1);
    if (ap.length <= n1) {    // If the AP length is less than the indicator parameter, valid data cannot be calculated. At this time, let the function return false.
        return false
    }  

    return TA.EMA(ap, n1)
}
    1. D:=EMA(ABS(AP-ESA),N1);

Gunakan yang dikiraAP, ESAuntuk mengira dataD- Tidak. Komen kod di sini boleh dibaca untuk beberapa petua tentang cara mengira penunjuk.

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++) {
        // When calculating the value of the indicator, it is necessary to determine the validity of the data, because the first few EMA calculations may be the beginning of the array of data is NaN, or null.
        // So it must be judged that the data involved in the calculation are all valid values to proceed, and if there are any invalid values, they are filled with NaN to arrABS_APminusESA.
        // The data thus calculated, each position corresponds to the previous data one by one, without misalignment.
        if (ap[i] && esa[i] && !isNaN(ap[i]) && !isNaN(esa[i])) {
            v = Math.abs(ap[i] - esa[i])     // According to ABS(AP-ESA), the specific value is calculated and put into the arrABS_APminusESA array.
            arrABS_APminusESA.push(v)
        } else {
            arrABS_APminusESA.push(NaN)
        }
    }  

    if (arrABS_APminusESA.length <= n1) {
        return false
    }  

    return TA.EMA(arrABS_APminusESA, n1)    // Calculate the EMA indicator of the array arrABS_APminusESA and get the data D (array structure).
}
    1. CI:=(AP-ESA)/(0.015*D);Kaedah pengiraan adalah sama dengan langkah 1, dan kod dikeluarkan secara langsung.
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); Hanya mengira penunjuk EMA untuk array CI.
function CalcTCI (ci, n2) {   // TCI:=EMA(CI,N2);
    if (ci.length <= n2) {
        return false
    }  

    return TA.EMA(ci, n2)
}
  • WT2:SMA(WT1,4,1);

Dalam langkah terakhir ini, fungsi SMA roda yang kita bina sebelum ini digunakan.

function CalcWT2 (wt1) {    // WT2:SMA(WT1,4,1);
    if (wt1.length <= 4) {
        return false 
    }  

    return SMA(wt1, 4, 1)   // The SMA indicator for wt1 is calculated by using our own implementation of the SMA function.
}

Translating isyarat perdagangan adalah sangat mudah.

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

Selepas membaca kod MyLanguage ini, kita dapat melihat bahawa Golden Cross dan Bearish Crossover dari WT1 dan WT2 digunakan sebagai syarat pembukaan. Menggunakan backtest strategi MyLanguage secara langsung, kita melihat bahawa:

img

Ia dapat dilihat dari pemerhatian operasi sebenar strategi MyLanguage bahawa apabila isyarat dikesan di kedudukan pembukaan, ia sebenarnya untuk mengesan sama ada kedudukan BAR di titik pembukaan yang mengira 2 BAR ke hadapan adalah Salib Emas. Rajah di atas menunjukkan dengan jelas bahawa:

img img

Kod pengisian bahagian pengesanan isyarat boleh ditulis sebagai berikut:

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")    // test
    }
    if (_State == SHORT) {
        _State = COVERSHORT
        Log("COVERSHORT")  // test
    }
    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")  // test
    }
    if (_State == LONG) {
        _State = COVERLONG
        Log("COVERLONG")  // test
    }
    isOK = false   
}

Di sini anda boleh berfikir tentang mengapa arahan SPK dan BPK MyLanguage boleh dilaksanakan dengan kod di atas.

Ujian belakang

Konfigurasi Ujian Kembali:

img

Backtest dalam MyLanguage:

img

Backtest dalam versi JavaScript:

img img

Kod pada permulaan fungsi OnTick digunakan untuk membuat backtesting lebih cepat. Ia digunakan untuk menjalankan strategi berdasarkan model Bar. Jika anda berminat, anda boleh menganalisisnya secara terperinci.

function OnTick(){
    // The ticker processing part of the driving strategy.
    var records = _C(exchange.GetRecords)
    if (records[records.length - 1].Time == preTime) {
        if (isOK) {
            Sleep(500)
            return 
        }
    } else {
        preTime = records[records.length - 1].Time
    }
    ...
    ..
    .

Kod strategi pengajaran lengkap:https://www.fmz.com/strategy/174457

Terima kasih kerana membaca.


Lebih lanjut