Pengalaman pembangunan strategi dagangan

Penulis:Kebaikan, Dicipta: 2019-09-05 11:49:31, Dikemas kini: 2023-11-07 20:48:06

img

Tujuan artikel ini adalah untuk menerangkan beberapa pengalaman dalam pembangunan strategi, serta beberapa petua, yang akan membolehkan pembaca dengan cepat memahami titik utama pembangunan strategi perdagangan.

Apabila anda menghadapi butiran yang sama dalam reka bentuk strategi, anda boleh segera datang dengan penyelesaian yang munasabah.

Kami menggunakan platform FMZ Quant sebagai contoh untuk penjelasan, ujian, dan latihan.

Strategi Bahasa pengaturcaraan kita akan menggunakan JavaScript

Untuk sasaran dagangan, kami mengambil pasaran aset blockchain (BTC, ETH, dll) sebagai objek kami

Pengumpulan dan pemprosesan data

Biasanya, bergantung kepada logik strategi, ia boleh menggunakan antara muka yang berbeza berikut untuk mendapatkan data pasaran, kebanyakan logik strategi didorong oleh data pasaran (tentu saja, beberapa strategi tidak peduli dengan data harga, seperti strategi pelaburan tetap).

  • GetTicker: Dapatkan kutipan tik masa nyata. Biasanya digunakan untuk mendapatkan harga terkini dengan cepat, Beli 1 harga, Jual 1 harga.

  • Dapatkan kedalaman pesanan buku pesanan. Biasanya digunakan untuk mendapatkan harga setiap lapisan kedalaman buku pesanan dan saiz pesanan yang menunggu. Digunakan untuk strategi lindung nilai, strategi pembuatan pasaran, dll.

  • GetTrade: Dapatkan rekod transaksi terkini pasaran. Biasanya digunakan untuk menganalisis tingkah laku pasaran dalam kitaran masa yang singkat dan menganalisis perubahan mikroskopik di pasaran. Biasanya digunakan untuk strategi frekuensi tinggi dan strategi algoritma.

  • GetRecords: Dapatkan data K-line pasaran. Biasanya digunakan untuk strategi penjejakan trend dan untuk mengira penunjuk.

Toleransi ralat

Apabila merancang strategi, pemula biasanya mengabaikan pelbagai kesilapan dan secara intuitif percaya bahawa hasil setiap bahagian dalam strategi ditubuhkan. Tetapi itu tidak benar, dalam operasi program strategi, ketika meminta data pasaran, anda akan menghadapi pelbagai situasi yang tidak dijangka.

Sebagai contoh, beberapa antara muka pasaran mengembalikan data yang tidak dilaksanakan:

var depth = exchange.GetDepth()

// depth.Asks[0].Price < depth.Bids[0].Price "Selling 1" price is lower than "buying 1" price, this situation cannot exist on the market.
// Because the selling price is lower than the buying price, the order must have been executed.
// depth.Bids[n].Amount = 0 Order book buying list "nth" layer, order quantity is 0
// depth.Asks[m].Price = 0 Order book selling list "mth" layer, the order price is 0

Atau secara langsung exchange.GetDepth() mengembalikan nilai sifar.

Terdapat banyak situasi aneh seperti itu. Oleh itu, adalah perlu untuk menangani masalah yang dapat diramalkan ini. Skema rawatan sedemikian dipanggil pemprosesan toleransi ralat.

Cara biasa untuk menangani kesalahan adalah membuang data dan mendapatkannya semula.

Contohnya:

function main () {
     while (true) {
         onTick()
         Sleep(500)
     }
}

function GetTicker () {
     while (true) {
         var ticker = exchange.GetTicker()
         if (ticker.Sell > ticker.Buy) { // Take the example of fault-tolerant processing that detects whether the "Selling 1" price is less than the "Buying 1" price.
                                               // Exclude this error, the current function returns "ticker".
             Return ticker
         }
         Sleep(500)
     }
}

function onTick () {
     var ticker = GetTicker() // Make sure the "ticker" you get doesn't exist the situation that "Selling 1" price is less than the "Buying 1" price.
     // ... specific strategy logic
}

Pendekatan yang sama boleh digunakan untuk proses toleransi ralat yang boleh diramalkan.

Prinsip reka bentuk adalah bahawa anda tidak boleh menggunakan logik yang salah untuk memandu logik strategi.

Penggunaan data K-line

Pemerolehan data garis K, panggilan:

var r = exchange.GetRecords()

Data garis K yang diperoleh adalah array, seperti ini:

[
    {"Time":1562068800000,"Open":10000.7,"High":10208.9,"Low":9942.4,"Close":10058.8,"Volume":6281.887000000001},
    {"Time":1562072400000,"Open":10058.6,"High":10154.4,"Low":9914.5,"Close":9990.7,"Volume":4322.099},
    ...
    {"Time":1562079600000,"Open":10535.1,"High":10654.6,"Low":10383.6,"Close":10630.7,"Volume":5163.484000000004}
]

Anda boleh melihat bahawa setiap brace keriting {} mengandungi masa, harga pembukaan, harga tertinggi, harga terendah, harga penutupan, dan jumlah.

Ini adalah garis K. Data garis K umum digunakan untuk mengira penunjuk seperti purata bergerak, MACD dan sebagainya.

Data K-line diteruskan sebagai parameter (data bahan mentah), dan kemudian parameter penunjuk ditetapkan untuk mengira fungsi data penunjuk, yang kita panggil fungsi penunjuk.

Terdapat banyak fungsi penunjuk pada platform perdagangan kuantitatif FMZ Quant.

Sebagai contoh, kita mengira penunjuk purata bergerak. Menurut kitaran data K-line yang dilalui, kita mengira purata bergerak kitaran yang sepadan.

Sebagai contoh, data K-garis yang berlalu (satu bar K-garis mewakili satu hari), mengira garis purata harian, perkara yang sama, jika data K-garis fungsi indikator purata yang berlalu adalah kitaran 1 jam, maka penunjuk yang dikira adalah purata bergerak 1 jam.

Biasanya kita sering mengabaikan masalah semasa mengira penunjuk. jika saya mahu mengira penunjuk purata bergerak 5 hari, maka kita mula-mula menyediakan data K-line harian:

var r = exchange.GetRecords(PERIOD_D1) // Pass parameters to the "GetRecords" function "PERIOD_D1" specifies the day K line to be acquired.
                                       // Specific function using method can be seen at: https://www.fmz.com/api#GetRecords

Dengan data K-line harian, kita boleh mengira penunjuk purata bergerak. jika kita mahu mengira purata bergerak 5 hari, maka kita perlu menetapkan parameter penunjuk fungsi penunjuk kepada 5.

var ma = TA.MA(r, 5) // "TA.MA()" is the indicator function used to calculate the moving average indicator. The first parameter sets the daily K-line data r just obtained.
                             // The second parameter is set to 5. The calculated 5-day moving average is the same as the other indicators.

Jika bilangan bar garis K dalam data garis K adalah kurang daripada 5, apa yang boleh kita lakukan untuk mengira purata bergerak 5 hari yang sah?

Jawapannya adalah tiada apa yang boleh anda lakukan.

Kerana penunjuk purata bergerak adalah purata harga penutupan sejumlah bar K-line.

img

Oleh itu, sebelum menggunakan data garis K dan fungsi penunjuk untuk mengira data petunjuk, adalah perlu untuk menentukan sama ada bilangan bar garis K dalam data garis K memenuhi syarat untuk pengiraan petunjuk (parameter petunjuk).

Jadi sebelum mengira purata bergerak 5 hari, anda perlu memeriksanya terlebih dahulu.

function CalcMA () {
     var r = _C(exchange.GetRecords, PERIOD_D1) // _C() is a fault-tolerant function, the purpose is to avoid r being null, you can get more information at: https://www.fmz.com/api#_C
     if (r.length > 5) {
         Return TA.MA(r, 5) // Calculate the moving average data with the moving average indicator function "TA.MA", return it as a function return value.
     }

     Return false
}

function main () {
     var ma = CalcMA()
     Log(ma)
}

img

Paparan ujian belakang:

[null,null,null,null,4228.7,4402.9400000000005, ... ]

Anda boleh melihat indikator purata bergerak 5 hari yang dikira. empat yang pertama adalah sifar, kerana bilangan bar K-garis kurang daripada 5, dan purata tidak boleh dikira. apabila anda mencapai bar K-garis ke-5, anda boleh mengira.

Petua untuk menilai kemas kini K-line

Apabila kita menulis strategi, sering mempunyai senario sedemikian, seperti strategi perlu memproses beberapa operasi apabila setiap kitaran K-garis selesai, atau mencetak beberapa log.

Bagaimana kita melaksanakan fungsi tersebut? Bagi pemula yang tidak mempunyai pengalaman pengaturcaraan, ia mungkin masalah yang menyusahkan.

Bagaimana menilai kitaran bar K-garis telah selesai. Kita boleh bermula dengan atribut masa dalam data K-garis. Setiap kali kita mendapatkan data K-garis, kita akan menilai atribut masa bar K-garis terakhir data K-garis ini berubah atau tidak. Jika ia diubah, ini bermakna bahawa terdapat bar K-garis baru yang dihasilkan (membuktikan bahawa kitaran bar K-garis K-garis yang baru dihasilkan telah selesai), jika tidak ada perubahan, ini bermakna tiada bar K-garis baru dihasilkan (kitaran bar K-garis terakhir semasa belum selesai).

Jadi kita memerlukan pembolehubah untuk merakam masa bar K-line terakhir data K-line.

var r = exchange.GetRecords()
var lastTime = r[r.length - 1].Time // "lastTime" used to record the last K-line bar time.

Dalam amalan, ini biasanya berlaku:

function main () {
     var lastTime = 0
     while (true) {
         var r = _C(exchange.GetRecords)
         if (r[r.length - 1].Time != lastTime) {
             Log ("New K-line bar generated")
             lastTime = r[r.length - 1].Time // Be sure to update "lastTime", this is crucial.

             // ... other processing logic
             // ...
         }

         Sleep(500)
     }
}

img

Anda boleh melihat bahawa dalam backtest, kitaran garis K ditetapkan kepada harian (parameter tidak ditentukan apabilaexchange.GetRecordsfungsi dipanggil, dan kitaran garis K yang ditetapkan mengikut backtest adalah parameter lalai). Setiap kali bar K-garis baru muncul, ia mencetak log.

Pengiraan Nilai Bilangan

  • Mengira masa yang dihabiskan untuk mengakses antara muka pertukaran

Jika anda ingin mempunyai paparan tertentu atau kawalan terhadap masa yang diperlukan untuk strategi untuk mengakses antara muka pertukaran, anda boleh menggunakan kod berikut:

function main () {
     while (true) {
         var beginTime = new Date().getTime()
         var ticker = exchange.GetTicker()
         var endTime = new Date().getTime()

         LogStatus(_D(), "GetTicker() function time-consuming:", endTime - beginTime, "millisecond")
         Sleep(1000)
     }
}

Sederhananya, cap masa yang direkodkan selepas memanggilGetTickerfungsi dikurangkan dari stempel masa sebelum panggilan, dan bilangan milidetik yang dialami dikira, iaitu masa yang diambil olehGetTickerfungsi dari pelaksanaan untuk kembali.

  • Gunakan Math.min / Math.max untuk mengehadkan had atas dan bawah nilai

Sebagai contoh, dalam proses meletakkan pesanan jualan, jumlah pesanan jualan tidak boleh lebih besar daripada jumlah syiling di akaun. Kerana jika lebih besar daripada jumlah syiling yang ada dalam akaun, pesanan akan menyebabkan kesilapan.

Kami mengawalnya seperti ini:

Sebagai contoh, kita merancang untuk menjual pendek 0.2 syiling.

var planAmount = 0.2
var account = _C(exchange.GetAccount)
var amount = Math.min(account.Stocks, planAmount)

Ini memastikan bahawa jumlah pesanan yang diletakkan tidak akan melebihi jumlah syiling yang tersedia di akaun.

Atas sebab yang sama,Math.maxdigunakan untuk memastikan had bawah nilai.

  • Keadaan seperti apa ini biasanya berlaku?

Secara amnya, pertukaran biasa mempunyai had pesanan penghantaran minimum untuk pasangan perdagangan tertentu. Jika ia lebih rendah daripada jumlah minimum, pesanan akan ditolak. Ini juga akan menyebabkan kegagalan program.

Dengan mengandaikan bahawa BTC biasanya mempunyai kuantiti pesanan minimum 0.01.

Strategi perdagangan kadang-kadang boleh mengakibatkan kurang daripada 0.01 kuantiti pesanan, jadi kita boleh menggunakanMath.maxuntuk memastikan kuantiti pesanan minimum.

  • Jumlah pesanan, kawalan ketepatan harga

Ketepatan boleh dikawal menggunakan_N()fungsi atauSetPrecision function.

PeraturanSetPrecision()fungsi hanya perlu ditetapkan sekali, dan bilangan tempat perpuluhan dalam kuantiti pesanan dan nilai harga secara automatik dipotong dalam sistem.

Peraturan_N()Fungsi adalah untuk melakukan pemotongan titik perpuluhan (kawal ketepatan) untuk nilai tertentu.

Contohnya:

var pi = _N(3.141592653, 2)
Log(pi)

Nilai pi dipotong dengan tempat perpuluhan, dan 2 tempat perpuluhan dikhaskan, iaitu: 3.14

Lihat dokumentasi API untuk butiran.

Beberapa tetapan logik

  • Masa, melakukan beberapa operasi untuk tempoh masa tertentu

Anda boleh menggunakan mekanisme sedemikian untuk menggunakan kaedah pengesanan cap masa untuk menentukan cap masa semasa dikurangkan cap masa kali terakhir tugas yang dijadualkan dilaksanakan, dan mengira masa yang berlalu dalam masa nyata. Apabila masa yang berlalu melebihi panjang masa tertentu. Selepas itu, operasi baru dilakukan.

Sebagai contoh, digunakan dalam strategi pelaburan tetap.

var lastActTime = 0
var waitTime = 1000 * 60 * 60 * 12 // number of milliseconds a day
function main () {
     while (true) {
         var nowTime = new Date().getTime()
         if (nowTime - lastActTime > waitTime) {
             Log ("Execution Fixed")
             // ... specific fixed investment operation, buying operation.


             lastActTime = nowTime
         }

         Sleep(500)
     }
}

Ini contoh yang mudah.

  • Merancang mekanisme pemulihan automatik untuk strategi

Menggunakan FMZ Quant_G()fungsi, dan keluar fungsi simpan, adalah mudah untuk merancang strategi untuk keluar daripada kemajuan simpan dan memulakan semula keadaan pemulihan automatik.

var hold = {
     Price : 0,
     Amount : 0,
}

function main () {
     if (_G("hold")) {
         var ret = _G("hold")
         hold.price = ret.price
         hold.amount = ret.amount
         Log("restore hold:", hold)
     }

     var count = 1
     while (true) {
         // ... strategy logic
         // ... In the strategy operation, it is possible that when opening a position, then assign the position price of the open position to "hold.price", and the amount of open positions is assigned to "hold.amount" to record the position information.

         hold.price = count++ // simulate some values
         hold.amount = count/10 // Simulate some values

         Sleep(500)
     }
}

function onexit () { // Click the stop button on the robot to trigger the execution of this function. After the execution, the robot stops.
     _G("hold", hold)
     Log("save hold:", JSON.stringify(hold))
}

img

Ia dapat dilihat bahawa data dalamholdobjek disimpan setiap kali robot dihentikan. dan apabila setiap kali data dimulakan semula, data dibaca dan nilaiholddikembalikan ke keadaan sebelum berhenti.

Sudah tentu, di atas adalah contoh yang mudah. Jika ia digunakan dalam strategi perdagangan sebenar, ia harus direka mengikut data utama yang perlu dipulihkan dalam strategi (umumnya adalah maklumat akaun, kedudukan, nilai keuntungan, arah perdagangan dan sebagainya.).

Selain itu, anda juga boleh menetapkan beberapa syarat lain untuk memulihkan.

Ini adalah beberapa petua untuk membangunkan strategi perdagangan, dan saya harap ia boleh membantu pemula!

Latihan praktikal adalah cara terpantas untuk memperbaiki diri! Saya berharap anda semua bertuah.


Berkaitan

Lebih lanjut