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
, SMA
telah digunakan:
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 adalahSMA
penunjuk, 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.
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:
Ia boleh dilihat bahawatalib.SMA
adalah 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:
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
}
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.
Mari kita mengambil bahagian ini MyLanguage satu ayat pada satu masa, fungsi oleh fungsi:
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)
ESA:=EMA(AP,N1);
:Di sini, kita akan menggunakan data AP yang dikira dalam langkah sebelumnya untuk mengira ESA. sebenarnya, ESA adalah
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)
}
D:=EMA(ABS(AP-ESA),N1);
Gunakan yang dikiraAP
, ESA
untuk 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).
}
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
}
function CalcTCI (ci, n2) { // TCI:=EMA(CI,N2);
if (ci.length <= n2) {
return false
}
return TA.EMA(ci, n2)
}
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:
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:
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.
Konfigurasi Ujian Kembali:
Backtest dalam MyLanguage:
Backtest dalam versi JavaScript:
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