Apabila menulis strategi perdagangan kuantitatif, menggunakan data K-line, sering terdapat kes-kes di mana data K-line kitaran bukan standard diperlukan. contohnya, data K-line kitaran 12 minit dan data kitaran K-line 4 jam diperlukan. Biasanya kitaran bukan standard seperti itu tidak tersedia secara langsung. Jadi bagaimana kita menangani keperluan seperti itu?
Data garis K kitaran bukan standard boleh diperolehi dengan menggabungkan data kitaran yang lebih kecil. Gambar ini, harga tertinggi dalam beberapa kitaran dikira sebagai harga tertinggi selepas sintesis garis K kitaran berbilang, dan harga terendah dikira sebagai harga terendah selepas sintesis, dan harga pembukaan tidak berubah. Harga pembukaan pertama data bahan mentah K-garis disintesis. Harga penutupan sepadan dengan harga penutupan data bahan mentah terakhir K-garis. Masa menggunakan masa harga pembukaan k garis. Volume transaksi menggunakan data bahan mentah yang dijumlahkan dan dikira.
Seperti yang ditunjukkan dalam gambar:
Mari kita ambil aset blockchain BTC_USDT sebagai contoh dan sintesis 1 jam menjadi 4 jam.
Masa | Paling tinggi | Terbuka | Terendah | Tutup |
---|---|---|---|---|
2019.8.12 00:00 | 11447.07 | 11382.57 | 11367.2 | 11406.92 |
2019.8.12 01:00 | 11420 | 11405.65 | 11366.6 | 11373.83 |
2019.8.12 02:00 | 11419.24 | 11374.68 | 11365.51 | 11398.19 |
2019.8.12 03:00 | 11407.88 | 11398.59 | 11369.7 | 11384.71 |
Data dari empat kitaran 1 jam digabungkan ke dalam satu data kitaran 4 jam.
Harga pembukaan adalah harga pembukaan baris K pertama pada 00:00 masa: 11382.57 Harga penutupan adalah harga penutupan k baris terakhir pada 03:00: 11384.71 Harga tertinggi adalah untuk mencari harga tertinggi di antara mereka: 11447.07 Harga terendah adalah untuk mencari harga terendah di antara mereka: 11365.51
Nota: Pasaran niaga hadapan komoditi China ditutup pada pukul 3:00 petang pada hari dagangan biasa
Masa permulaan kitaran 4 jam adalah masa permulaan K-line 1 jam pertama, iaitu 2019.8.12 00:00
Jumlah jumlah semua 1 jam k baris digunakan sebagai ini 4 jam k baris jumlah.
Garis K 4 jam disintesis:
High: 11447.07
Open: 11382.57
Low: 11365.51
Close: 11384.71
Time: 209.8.12 00:00
Anda boleh lihat bahawa data adalah konsisten.
Selepas memahami idea awal, anda boleh menulis kod secara manual untuk merealisasikan keperluan.
Kod ini hanya untuk rujukan:
function GetNewCycleRecords (sourceRecords, targetCycle) { // K line synthesis function
var ret = []
// First get the source K line data cycle
if (!sourceRecords || sourceRecords.length < 2) {
Return null
}
var sourceLen = sourceRecords.length
var sourceCycle = sourceRecords[sourceLen - 1].Time - sourceRecords[sourceLen - 2].Time
if (targetCycle % sourceCycle != 0) {
Log("targetCycle:", targetCycle)
Log("sourceCycle:", sourceCycle)
throw "targetCycle is not an integral multiple of sourceCycle."
}
if ((1000 * 60 * 60) % targetCycle != 0 && (1000 * 60 * 60 * 24) % targetCycle != 0) {
Log("targetCycle:", targetCycle)
Log("sourceCycle:", sourceCycle)
Log((1000 * 60 * 60) % targetCycle, (1000 * 60 * 60 * 24) % targetCycle)
throw "targetCycle cannot complete the cycle."
}
var multiple = targetCycle / sourceCycle
var isBegin = false
var count = 0
var high = 0
var low = 0
var open = 0
var close = 0
var time = 0
var vol = 0
for (var i = 0 ; i < sourceLen ; i++) {
// Get the time zone offset value
var d = new Date()
var n = d.getTimezoneOffset()
if ((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) {
isBegin = true
}
if (isBegin) {
if (count == 0) {
High = sourceRecords[i].High
Low = sourceRecords[i].Low
Open = sourceRecords[i].Open
Close = sourceRecords[i].Close
Time = sourceRecords[i].Time
Vol = sourceRecords[i].Volume
count++
} else if (count < multiple) {
High = Math.max(high, sourceRecords[i].High)
Low = Math.min(low, sourceRecords[i].Low)
Close = sourceRecords[i].Close
Vol += sourceRecords[i].Volume
count++
}
if (count == multiple || i == sourceLen - 1) {
Ret.push({
High : high,
Low : low,
Open : open,
Close : close,
Time : time,
Volume : vol,
})
count = 0
}
}
}
Return ret
}
// test
function main () {
while (true) {
var r = exchange.GetRecords() // Raw data, as the basic K-line data of the synthesize K line. for example, to synthesize a 4-hour K-line, you can use the 1-hour K-line as the raw data.
var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4) // Pass the original K-line data r through the GetNewCycleRecords function, and the target cycles, 1000 * 60 * 60 * 4, ie the target synthesis cycle is 4 hours K-line data .
$.PlotRecords(r2, "r2") // The strategy class library bar can be selected by check the line class library, and calling the $.PlotRecords line drawing class library to export the function drawing.
Sleep(1000) // Each cycle is separated by 1000 milliseconds, preventing access to the K-line interface too much, resulting in transaction restrictions.
}
}
Sebenarnya, untuk menyintesis garis K, anda memerlukan dua perkara. yang pertama adalah data bahan mentah, iaitu data garis K kitaran yang lebih kecil. dalam contoh ini, ia adalahvar r = exchange.GetRecords()
untuk mendapatkan data garis kitaran K yang lebih kecil.
Yang kedua adalah untuk mengetahui saiz kitaran sintesis, kita menggunakan algoritma fungsi GetNewCycleRecords untuk melakukan ini, maka anda akhirnya boleh mengembalikan data struktur array K-line yang disintesis.
Sila ambil perhatian:
Kitaran sasaran tidak boleh lebih kecil daripada kitaran garis K yang anda lulus dalam fungsi GetNewCycleRecords sebagai bahan mentah untuk data. kerana anda tidak boleh menyintesis data kitaran yang lebih kecil dengan kitaran yang lebih besar. hanya sebaliknya.
Kitaran sasaran mesti ditetapkan kepada
contohnya:
K-garis kitaran 12 minit bermula dari 0:0 setiap jam, kitaran pertama adalah 00:00:00 ~ 00:12:00, dan kitaran kedua adalah 00:12: 00 ~ 00: 24:00, kitaran ketiga adalah 00:24: 00 ~ 00:36:00, kitaran keempat adalah 00:36:00 ~ 00:48:00, kitaran kelima adalah 00:48 :00 ~ 01:00:00, yang tepat satu jam selesai.
jika ia adalah kitaran 13 minit, ia akan menjadi kitaran yang tidak ditutup. Data yang dikira oleh kitaran tersebut tidak unik kerana data yang disintesis berbeza bergantung pada titik permulaan data yang disintesis.
Jalankan di pasaran sebenar:
Carta pertukaran kontras
Saya mahu mengira purata bergerak harga tertinggi untuk semua garis K. Apa yang perlu saya lakukan?
Biasanya, kita mengira purata bergerak dengan menggunakan purata harga penutupan, tetapi kadang-kadang terdapat permintaan untuk menggunakan harga tertinggi, harga terendah, harga pembukaan dan sebagainya.
untuk permintaan tambahan ini, data baris K yang dikembalikan oleh fungsi exchange.GetRecords() tidak boleh dihantar terus ke fungsi pengiraan penunjuk.
Contohnya:
Peraturantalib.MA
Fungsi pengiraan penunjuk purata bergerak mempunyai dua parameter, yang pertama adalah data yang perlu dihantar, dan yang kedua adalah parameter kitaran penunjuk.
Sebagai contoh, kita perlu mengira penunjuk seperti yang ditunjukkan di bawah.
Kitaran garis K adalah 4 jam.
Pada carta harga pasaran pertukaran, garis purata telah ditetapkan dengan parameter kitaran 9.
Sumber data yang dikira menggunakan harga tertinggi setiap Bar.
Iaitu, garis purata bergerak ini terdiri daripada purata harga purata tertinggi sembilan bar K-line berpusat 4 jam.
Mari kita membina data sendiri untuk melihat jika ia adalah sama dengan data pertukaran.
var highs = []
for (var i = 0 ; i < r2.length ; i++) {
highs.push(r2[i].High)
}
Oleh kerana kita perlu mengira harga tertinggi setiap Bar untuk mendapatkan nilai penunjuk purata bergerak, kita perlu membina array di mana setiap elemen data mempunyai harga tertinggi untuk setiap Bar.
Anda boleh lihat bahawahighs
Variabel pada mulanya merupakan array kosong, kemudian kita melintasi variabel data r2 k-garis (jangan ingat r2? Lihat kod dalam fungsi utama yang menyintesis garis K 4 jam di atas).
Baca harga tertinggi setiap Bar r2 (iaitu r2[i].High, i berkisar dari 0 hingga r2.panjang - 1), kemudian tekan kehighs
Dengan cara ini kita hanya membina struktur data yang sepadan satu ke satu dengan Bar data K-garis.
Pada masa ini,highs
boleh lulustalib.MA
fungsi untuk mengira purata bergerak.
Contoh lengkap:
function main () {
while (true) {
var r = exchange.GetRecords()
var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)
if (!r2) {
Continue
}
$.PlotRecords(r2, "r2") // Draw the K line
var highs = []
for (var i = 0 ; i < r2.length ; i++) {
Highs.push(r2[i].High)
}
var ma = talib.MA(highs, 9) // use the moving average function "talib.MA" to calculate the moving average indicator
$.PlotLine("high_MA9", ma[ma.length - 2], r2[r2.length - 2].Time) // Use the line drawing library to draw the moving average indicator on the chart
Sleep(1000)
}
}
Ujian belakang:
Anda boleh melihat bahawa nilai indikator purata kedudukan titik tetikus dalam gambar adalah 11466.9289
Kod di atas boleh disalin ke strategi untuk menjalankan ujian, ingat untuk memeriksa
Platform FMZ Quant sudah mempunyai antara muka yang dikemas, iaitu
exchange.GetRecords
fungsi, untuk mendapatkan data K-garis.
Berikut memberi tumpuan kepada akses langsung ke pertukaranGetRecords
antara muka biasanya mengembalikan 100 k baris. jika anda menghadapi strategi yang pada mulanya memerlukan lebih daripada 100 K-garis, anda perlu menunggu proses pengumpulan.
Untuk membuat strategi berfungsi secepat mungkin, anda boleh merangkumi fungsi, terus mengakses antara muka garis K pertukaran, dan menentukan parameter untuk mendapatkan lebih banyak data garis K.
Menggunakan pasangan dagangan BTC_USDT di bursa Huobi sebagai contoh, kami melaksanakan keperluan ini:
Cari dokumentasi API pertukaran dan lihat penerangan antara muka K-line:
https://huobiapi.github.io/docs/spot/v1/en/#get-klines-candles
parameter:
Nama | Jenis | Adakah perlu? | Penerangan | Nilai |
---|---|---|---|---|
simbol | senar | betul | Pasangan Dagangan | Btcusdt, ethbtc... |
tempoh | senar | betul | Mengembalikan granulariti masa data, yang merupakan selang masa setiap baris k | 1 minit, 5 minit, 15 minit, 30 minit, 60 minit, 1 hari, 1 bulan, 1 minggu, 1 tahun |
saiz | bilangan bulat | palsu | Mengembalikan bilangan K baris data | [1, 2000] |
Kod ujian:
function GetRecords_Huobi (period, size, symbol) {
var url = "https://api.huobi.pro/market/history/kline?" + "period=" + period + "&size=" + size + "&symbol=" + symbol
var ret = HttpQuery(url)
try {
var jsonData = JSON.parse(ret)
var records = []
for (var i = jsonData.data.length - 1; i >= 0 ; i--) {
records.push({
Time : jsonData.data[i].id * 1000,
High : jsonData.data[i].high,
Open : jsonData.data[i].open,
Low : jsonData.data[i].low,
Close : jsonData.data[i].close,
Volume : jsonData.data[i].vol,
})
}
return records
} catch (e) {
Log(e)
}
}
function main() {
var records = GetRecords_Huobi("1day", "300", "btcusdt")
Log(records.length)
$.PlotRecords(records, "K")
}
Anda boleh lihat di log, cetakanrecords.length
adalah 300, iaitu, bilanganrecords
Bar data garis K adalah 300.