Tujuan dari artikel ini adalah untuk menggambarkan beberapa pengalaman dalam pengembangan strategi, serta beberapa tips, yang akan memungkinkan pembaca untuk dengan cepat memahami titik kunci pengembangan strategi perdagangan.
Ketika Anda menemukan rincian serupa dalam beberapa desain strategi, Anda dapat segera datang dengan solusi yang masuk akal.
Kami menggunakan platform FMZ Quant sebagai contoh untuk penjelasan, pengujian, dan latihan.
Strategi Bahasa pemrograman kita akan menggunakan JavaScript
Untuk target perdagangan, kami mengambil pasar aset blockchain (BTC, ETH, dll) sebagai objek kami
Biasanya, tergantung pada logika strategi, dapat menggunakan antarmuka yang berbeda berikut untuk mendapatkan data pasar, sebagian besar logika strategi didorong oleh data pasar (tentu saja, beberapa strategi tidak peduli dengan data harga, seperti strategi investasi tetap).
GetTicker: Dapatkan kutipan tik secara real time.
Umumnya digunakan untuk cepat mendapatkan harga terbaru saat ini,
Dapatkan kedalaman pesanan dari buku pesanan. Umumnya digunakan untuk mendapatkan harga setiap lapisan dari kedalaman buku pesanan dan ukuran pesanan yang tertunda. Digunakan untuk strategi lindung nilai, strategi pembuatan pasar, dll.
GetTrade: Dapatkan catatan transaksi terbaru dari pasar. Umumnya digunakan untuk menganalisis perilaku pasar dalam siklus waktu yang singkat dan menganalisis perubahan mikroskopis di pasar.
GetRecords: Dapatkan data K-line pasar. Biasanya digunakan untuk strategi pelacakan tren dan untuk menghitung indikator.
Pada saat merancang strategi, pemula biasanya mengabaikan berbagai kesalahan dan secara intuitif percaya bahwa hasil dari setiap bagian dalam strategi telah ditetapkan.
Misalnya, beberapa antarmuka pasar mengembalikan data yang belum dieksekusi:
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 langsung exchange.GetDepth() mengembalikan nilai nol.
Ada banyak situasi aneh seperti itu. Oleh karena itu, perlu untuk menangani masalah yang dapat diprediksi ini. Skema perawatan seperti ini disebut pemrosesan toleransi kesalahan.
Cara normal untuk menangani kesalahan adalah membuang data dan mendapatkannya kembali.
Misalnya:
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 dapat digunakan untuk proses toleransi kesalahan yang dapat diprediksi lainnya.
Prinsip desain adalah bahwa Anda tidak pernah bisa menggunakan logika yang salah untuk mendorong logika strategi.
Akuisisi 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 dapat melihat bahwa setiap kurung keriting berisi waktu, harga pembukaan, harga tertinggi, harga terendah, harga penutupan, dan volume.
Ini adalah garis K. Data garis K umum digunakan untuk menghitung indikator seperti moving average, MACD dan sebagainya.
Data K-line diteruskan sebagai parameter (data bahan baku), dan kemudian parameter indikator ditetapkan untuk menghitung fungsi dari data indikator, yang kita sebut fungsi indikator.
Ada banyak fungsi indikator di platform perdagangan kuantitatif FMZ Quant.
Sebagai contoh, kita menghitung indikator rata-rata bergerak. Menurut siklus data K-line yang dilewati, kita menghitung rata-rata bergerak dari siklus yang sesuai.
Misalnya, data K-line yang melewati (satu batang K-line mewakili satu hari), menghitung garis rata-rata harian, hal yang sama, jika data K-line dari fungsi indikator rata-rata yang melewati adalah siklus 1 jam, maka indikator yang dihitung adalah rata-rata bergerak 1 jam.
Biasanya kita sering mengabaikan masalah ketika menghitung indikator. jika saya ingin menghitung indikator rata-rata bergerak 5 hari, maka pertama kita mempersiapkan 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 dapat menghitung indikator moving average. jika kita ingin menghitung rata-rata bergerak 5 hari, maka kita harus mengatur parameter indikator fungsi indikator menjadi 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.
Kita telah mengabaikan masalah potensial. jika jumlah garis K bar dalam data K-line kurang dari 5, apa yang bisa kita lakukan untuk menghitung rata-rata bergerak 5 hari yang valid?
Jawabannya adalah tidak ada yang bisa kau lakukan.
Karena indikator rata-rata bergerak adalah rata-rata harga penutupan dari sejumlah bar K-line.
Oleh karena itu, sebelum menggunakan data garis K dan fungsi indikator untuk menghitung data indikator, perlu untuk menentukan apakah jumlah batang garis K dalam data garis K memenuhi persyaratan untuk perhitungan indikator (parameter indikator).
Jadi sebelum menghitung rata-rata bergerak 5 hari, Anda harus 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)
}
Tampilan backtest:
[null,null,null,null,4228.7,4402.9400000000005, ... ]
Anda dapat melihat indikator rata-rata bergerak 5 hari yang dihitung. empat pertama adalah nol, karena jumlah garis K kurang dari 5, dan rata-rata tidak dapat dihitung. ketika Anda mencapai garis K ke-5, Anda dapat menghitungnya.
Ketika kita menulis strategi, sering memiliki skenario seperti, seperti strategi perlu memproses beberapa operasi ketika setiap siklus K-line selesai, atau mencetak beberapa log.
Bagaimana kita menerapkan fungsi tersebut? Untuk pemula yang tidak memiliki pengalaman pemrograman, ini mungkin menjadi masalah yang merepotkan.
Cara menilai siklus bar K-line selesai. Kita dapat mulai dengan atribut waktu dalam data K-line. Setiap kali kita mendapatkan data K-line, kita akan menilai atribut waktu bar K-line terakhir dari data K-line ini berubah atau tidak. Jika diubah, itu berarti bahwa ada bar K-line baru yang dihasilkan (membuktikan bahwa siklus bar K-line sebelumnya dari bar K-line yang baru dihasilkan selesai), jika tidak ada perubahan, itu berarti tidak ada bar K-line baru yang dihasilkan (siklus bar K-line terakhir saat ini belum selesai).
Jadi kita perlu variabel untuk merekam waktu garis K terakhir dari 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 prakteknya, ini biasanya terjadi:
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)
}
}
Anda dapat melihat bahwa dalam backtest, siklus garis K ditetapkan untuk harian (parameter tidak ditentukan ketikaexchange.GetRecords
fungsi disebut, dan siklus garis K yang ditetapkan sesuai dengan backtest adalah parameter default). Setiap kali bar garis K baru muncul, ia mencetak log.
Jika Anda ingin memiliki tampilan tertentu atau kontrol atas waktu yang dibutuhkan untuk strategi untuk mengakses antarmuka pertukaran, Anda dapat menggunakan kode 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, waktu yang tercatat setelah meneleponGetTicker
fungsi dikurangi dari timestamp sebelum panggilan, dan jumlah milidetik yang dialami dihitung, yaitu waktu yang dibutuhkan olehGetTicker
fungsi dari eksekusi untuk kembali.
Misalnya, dalam proses penempatan pesanan penjualan, jumlah pesanan penjualan tidak boleh lebih besar dari jumlah koin di akun. Karena jika jumlahnya lebih besar dari jumlah koin yang tersedia di akun, urutan akan menyebabkan kesalahan.
Kita mengontrolnya seperti ini:
Sebagai contoh, kita berencana untuk short sell 0.2 koin.
var planAmount = 0.2
var account = _C(exchange.GetAccount)
var amount = Math.min(account.Stocks, planAmount)
Hal ini memastikan bahwa jumlah pesanan yang ditempatkan tidak akan melebihi jumlah koin yang tersedia di akun.
Untuk alasan yang sama,Math.max
digunakan untuk memastikan batas bawah suatu nilai.
Umumnya, pertukaran normal memiliki batas pesanan pengiriman minimum untuk pasangan perdagangan tertentu. Jika lebih rendah dari jumlah minimum, pesanan akan ditolak. Ini juga akan menyebabkan kegagalan program.
Dengan asumsi bahwa BTC biasanya memiliki jumlah pesanan minimum 0.01.
Strategi perdagangan kadang-kadang dapat menghasilkan kurang dari 0,01 jumlah pesanan, sehingga kita dapat menggunakanMath.max
untuk memastikan jumlah pesanan minimum.
Keakuratan dapat dikontrol dengan menggunakan_N()
fungsi atauSetPrecision
function.
PeraturanSetPrecision()
fungsi hanya perlu diatur sekali, dan jumlah tempat desimal dalam jumlah pesanan dan nilai harga secara otomatis dipotong dalam sistem.
Peraturan_N()
fungsi adalah untuk melakukan truncasi titik desimal (kontrol presisi) untuk nilai tertentu.
Misalnya:
var pi = _N(3.141592653, 2)
Log(pi)
Nilai pi dipotong dengan tempat desimal, dan 2 tempat desimal disediakan, yaitu: 3.14
Lihat dokumentasi API untuk rincian.
Anda dapat menggunakan mekanisme seperti itu untuk menggunakan metode deteksi time stamp untuk menentukan time stamp saat ini dikurangi time stamp terakhir kali tugas yang dijadwalkan dijalankan, dan menghitung waktu yang telah berlalu secara real time.
Misalnya, digunakan dalam strategi investasi 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 adalah contoh sederhana.
Menggunakan FMZ Quant_G()
fungsi, dan keluar dari fungsi menyimpan, nyaman untuk merancang strategi untuk keluar dari kemajuan menyimpan dan memulai kembali keadaan pemulihan otomatis.
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))
}
Hal ini dapat dilihat bahwa data dalamhold
objek disimpan setiap kali robot dihentikan. dan ketika setiap kali data dihidupkan kembali, data dibaca dan nilai darihold
dikembalikan ke keadaan sebelum berhenti.
Tentu saja, di atas adalah contoh sederhana. Jika digunakan dalam strategi perdagangan yang sebenarnya, itu harus dirancang sesuai dengan data kunci yang perlu dipulihkan dalam strategi (umumnya adalah informasi akun, posisi, nilai keuntungan, arah perdagangan dan sebagainya.).
Selanjutnya, Anda juga dapat menetapkan beberapa kondisi lain untuk mengembalikan.
Ini adalah beberapa tips untuk mengembangkan strategi trading, dan saya harap itu bisa membantu pemula!
Latihan praktis adalah cara tercepat untuk meningkatkan diri! Saya berharap Anda semua beruntung.