Dalam menulis strategi dagangan terprogram, terdapat keperluan untuk menggunakan beberapa data K-line tidak standard, seperti data K-line 12 minit, data K-line 4 jam, yang biasanya tidak dapat diperoleh secara langsung. Jadi bagaimana kita menangani keperluan tersebut? Jawapannya pasti ada. Siklus bukan standard boleh diperoleh melalui data dari kitaran yang lebih kecil, menggabungkan gabungan, anda boleh membayangkan, harga tertinggi dalam beberapa kitaran, dikira sebagai harga tertinggi selepas pengumpulan, harga minimum dikira sebagai harga minimum selepas pengumpulan, harga pembukaan tidak berubah, dengan menggunakan data bahan mentah K baris ini, harga penutupan sepadan dengan harga penutupan terakhir data bahan mentah K baris ini, masa adalah masa yang diambil untuk harga pembukaan, jumlah transaksi dikira dan diperoleh dengan data bahan mentah. Di bawah ini adalah gambar:
Sebagai contoh, jika kita mengambil pasaran aset blockchain BTC_USDT, satu jam menjadi empat jam.
Masa | Tinggi | Terbuka | rendah | Penghantaran |
---|---|---|---|---|
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 ini, digabungkan dengan data dari satu kitaran 4 jam akar, harga buka adalah harga buka pertama pada 00:00:11382.57 Harga penutupan adalah harga penutupan terakhir iaitu pada pukul 03:00: 11384.71 Harga tertinggi cari harga tertinggi di sini:11447.07 Harga terendah cari harga terendah di sini: 11365.51 Siklus 4 jam. Waktu permulaan adalah 00:00 Waktu permulaan garis K 1 jam ini ialah 2019.8.12 00:00 Jumlah permintaan untuk setiap jam perdagangan (yang utama adalah melihat bagaimana harga disatukan, tidak ditunjukkan dalam data transaksi), tidak akan diceritakan di sini.
Satu garis K sepanjang 4 jam yang dihasilkan ialah: Tinggi: 114477 Buka: 11382.57 rendah: 11365.51 Pengumpulan: 11384.71 Waktu: 08.12.2019
Di sini anda boleh melihat bahawa data adalah konsisten.
Dengan mengkaji idea awal, anda boleh menulis kod secara manual untuk memenuhi keperluan ini.
Di sini, anda boleh melihat beberapa gambar yang menarik dan menarik.
function GetNewCycleRecords (sourceRecords, targetCycle) { // K线合成函数
var ret = []
// 首先获取源K线数据的周期
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++) {
// 获取 时区偏移数值
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
}
// 测试
function main () {
while (true) {
var r = exchange.GetRecords() // 原始数据,作为合成K线的基础K线数据,例如要合成4小时K线,可以用1小时K线作为原始数据。
var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4) // 通过 GetNewCycleRecords 函数 传入 原始K线数据 r , 和目标周期, 1000 * 60 * 60 * 4 即 目标合成的周期 是4小时K线数据。
$.PlotRecords(r2, "r2") // 策略类库栏 可以勾选画线类库,调用 $.PlotRecords 画线类库 导出函数 画图。
Sleep(1000) // 每次循环间隔 1000 毫秒,防止访问K线接口获取数据过于频繁,导致交易所限制。
}
}
Sebenarnya, untuk menghimpunkan K-string, kita memerlukan dua perkara, pertama, kita memerlukan data bahan mentah, iaitu data K-string bersiklus kecil, contohnya, kita memerlukan data K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string untuk menghimpunkan K-string.var r = exchange.GetRecords()
Data garis K bersiklus kecil yang diperoleh. Kedua, perlu untuk menentukan berapa banyak kitaran yang dikumpulkan, iaitu kitaran sasaran untuk penciptaan data garis K.
Kemudian, dengan menggunakan algoritma fungsi GetNewCycleRecords, anda akhirnya dapat mengembalikan data dari struktur aritmatika K baris yang disintesis.
Perhatikan bahawa:
1, kitaran sasaran tidak boleh lebih kecil daripada kitaran K baris yang anda masukkan ke fungsi GetNewCycleRecords sebagai bahan mentah data. Data yang lebih kecil tidak boleh disintesis dengan kitaran kecil.
2, kitaran sasaran yang ditetapkan mestilah ditutup;
Apa itu penutupan kitaran?
Secara ringkasnya, dalam satu jam atau sehari, jangka masa kitaran sasaran digabungkan untuk membentuk satu kitaran tertutup.
Contoh:
Sebagai contoh, garis K pada kitaran 12 minit, bermula dari 0 minit 0 saat setiap jam (contohnya pada waktu 0), dan kitaran pertama adalah00:00:00 ~ 00:12:00
Dan kitaran kedua ialah00:12:00 ~ 00:24:00
Dan kitaran ketiga ialah00:24:00 ~ 00:36:00
Dan kitaran keempat ialah00:36:00 ~ 00:48:00
Jadi, kitaran kelima ialah00:48:00 ~ 01:00:00
Dalam satu jam, anda akan dapat melihat gambar di bawah.
Jika ia adalah kitaran 13 minit, atau kitaran yang tidak ditutup, data yang dikira kitaran ini tidak unik, kerana data yang digabungkan berbeza mengikut titik permulaan data yang digabungkan.
Di sini, anda boleh melihat gambar di bawah:
Grafik Perbandingan Bursa
Saya sering mendapat soalan daripada rakan-rakan saya, bagaimana untuk mengira purata harga tertinggi untuk setiap K-line?
Biasanya kita mengira garis rata adalah rata-rata harga penutupan yang dikira, yang membentuk garis rata, tetapi kadang-kadang terdapat keperluan untuk mengira harga tertinggi, harga minimum, harga pembukaan, dan lain-lain.
Kita tidak boleh teruskan.exchange.GetRecords()
Data garis K yang dikembalikan oleh fungsi akan dihantar terus ke fungsi pengiraan penunjuk.
Contohnya:talib.MAFungsi pengiraan penunjuk bersambung mempunyai dua parameter, parameter pertama adalah data yang perlu dihantar, dan parameter kedua adalah parameter kitaran penunjuk. Jadi, contohnya, kita mahu kira perbandingan di bawah ini.
Dalam tempoh 4 jam, kitaran K-line akan meningkat. Pada carta bursa, garis rata telah ditetapkan, dengan parameter kitaran rata-rata adalah 9. Dan sumber data yang ditetapkan untuk dikira adalah harga tertinggi untuk setiap bar.Iaitu garis rata ini adalah rata-rata yang dikira sebagai purata harga tertinggi bagi 9 kitaran 4 jam Bar garis K, yang terdiri daripada garis rata penunjuk.
Kami mulakan dengan membina satu perhitungan data sendiri untuk melihat sama ada ia adalah sama dengan grafik bursa yang dikira.
var highs = []
for (var i = 0 ; i < r2.length ; i++) {
highs.push(r2[i].High)
}
Oleh kerana untuk mengira nilai purata harga tertinggi untuk setiap Bar, kita mendapat penunjuk rata-rata. Kemudian, kita perlu membina satu array yang mana setiap elemen data adalah nilai tertinggi bagi setiap bar. Anda boleh lihat bahawa variabel highs bermula sebagai satu susunan kosong, dan kemudian kita melintasi variabel data garis K r2 (tidak ingat r2? Lihat kod di atas dalam fungsi utama untuk menyusun garis K selama 4 jam). Membaca nilai tertinggi untuk setiap bar r2 (iaitu r2[i].High, i mengambil nilai dari 0 hingga r2.length-1), kemudian mendorong ke tinggi.
Pada masa ini, highs boleh dihantar ke talib. Fungsi MA mengira garis rata.
Contoh lengkap:
function main () {
while (true) {
var r = exchange.GetRecords()
var r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)
if (!r2) {
continue
}
$.PlotRecords(r2, "r2") // 画出K线
var highs = []
for (var i = 0 ; i < r2.length ; i++) {
highs.push(r2[i].High)
}
var ma = talib.MA(highs, 9) // 用均线指标函数 talib.MA 计算 均线指标
$.PlotLine("high_MA9", ma[ma.length - 2], r2[r2.length - 2].Time) // 使用画线类库把均线指标画在图表上
Sleep(1000)
}
}
Percubaan semula dijalankan:
Seperti yang anda lihat pada gambar ini, nilai penunjuk rata-rata di mana tetikus berhenti adalah11466.9289
Kod di atas boleh disalin untuk menjalankan ujian dalam dasar, ingat untuk menyimpan selepas mengklik "Layari baris gambar"!
Pencipta platform dagangan kuantitatif sudah mempunyai antara muka yang terbungkus, iaitu fungsi exchange.GetRecords, untuk mendapatkan data K-line. Di bawah ini memberi tumpuan kepada mendapatkan data melalui antara muka data K-line yang diakses secara langsung oleh pertukaran, kerana kadang-kadang parameter perlu ditentukan untuk mendapatkan lebih banyak K-line, yang dibungkus dengan antara muka GetRecords Biasanya, 100 baris dikembalikan. Jika anda menghadapi strategi yang memerlukan lebih daripada 100 baris K pada mulanya, anda perlu mengumpul menunggu. Untuk membuat dasar itu berfungsi secepat mungkin, anda boleh membungkus fungsi sendiri, pergi terus ke antara muka K-line pertukaran, dan tentukan parameter untuk mendapatkan lebih banyak data K-line.
Dengan menggunakan pasangan perdagangan BTC_USDT, kita dapat memenuhi keperluan ini:
Untuk mencari dokumen API pertukaran, lihat penerangan antara muka K-Line:
https://api.huobi.pro/market/history/kline?period=1day&size=200&symbol=btcusdt
Parameter:
Nama parameter | Jenis | Adakah perlu? | Penerangan | Mengambil nilai |
---|---|---|---|---|
simbol | senar | betul | Perdagangan | Btcusdt, ethbtc... |
tempoh | senar | betul | Mengembalikan butiran masa data, iaitu selang masa bagi setiap log. | 1 minit, 5 minit, 15 minit, 30 minit, 60 minit, 1 hari, 1 bulan, 1 minggu, 1 tahun |
saiz | bilangan bulat | palsu | Kembalikan rekod data K-line | [1, 2000] |
Kode 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")
}
Versi Python, contoh untuk mengakses antarmuka bursa token:
#!python3
import json
import urllib2
def GetRecords_Huobi(period, size, symbol):
headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
url = "https://api.huobi.pro/market/history/kline?" + "period=" + period + "&size=" + size + "&symbol=" + symbol
request = urllib2.Request(url)
request.add_header('User-Agent','Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6')
opener = urllib2.build_opener()
f= opener.open(request)
ret = f.read().decode('utf-8')
try :
jsonData = json.loads(ret)
records = []
for i in range(len(jsonData["data"]) - 1, -1, -1):
records.append({
"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
except Exception as e:
Log(e)
def main():
r = GetRecords_Huobi("1day", "300", "btcusdt")
Log(len(r))
ext.PlotRecords(r, "K") # 需要引用Python画线类库
Versi Python, contoh antara muka K-Line untuk mengakses Bursa Binance:
#!python3
import json
import urllib2
def GetRecords_Huobi(period, size, symbol):
headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
url = "https://api.binance.com/api/v3/klines?symbol=" + symbol + "&interval=" + period
request = urllib2.Request(url)
request.add_header('User-Agent','Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6')
opener = urllib2.build_opener()
f= opener.open(request)
ret = f.read().decode('utf-8')
try :
jsonData = json.loads(ret)
records = []
for i in range(len(jsonData)):
records.append({
"Time" : float(jsonData[i][0]),
"High" : float(jsonData[i][2]),
"Open" : float(jsonData[i][1]),
"Low" : float(jsonData[i][3]),
"Close" : float(jsonData[i][4]),
"Volume" : float(jsonData[i][5]),
})
return records
except Exception as e:
Log(e)
def main():
r = GetRecords_Huobi("1m", "300", "BTCUSDT")
Log(len(r))
ext.PlotRecords(r, "K") # 需要引用Python画线类库
Anda boleh lihat di log, cetak records.length adalah 300, iaitu rekod K baris bar data mempunyai 300 baris.
pengasuhTidak boleh mengumpul k hari dalam 3 jam atau 6 jam.
pengasuhif (((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) { isBegin = benar {C:$0000FF} Terdapat masalah dalam ayat ini, anda tidak boleh membuat k hari dengan 3 jam atau 6 jam, anda hanya boleh membuat k hari dengan 1 jam, 2 jam, 4 jam.
xis2004Jika anda ingin merakam semua data sejarah, adakah anda boleh merakam semua data sejarah?
willzhangTerima kasih kerana menjawab.
willzhangSila tanya, bagaimana untuk menangani lebih baik jika anda mahu lebih daripada 300 bit? Sebagai contoh, 1000 K-line data.
Pencipta Kuantiti - Impian KecilBaiklah, ambil masa untuk mengubahnya.
Pencipta Kuantiti - Impian KecilIni adalah data yang anda akses dari antara muka bursa, berapa banyak data yang diberikan oleh bursa kepada anda.
Pencipta Kuantiti - Impian KecilJika melebihi jumlah pulangan maksimum yang disokong oleh antara muka pertukaran, ini hanya akan mengumpul data, dan sebagainya, jumlah data baris K yang mencukupi.