
Saat menulis strategi perdagangan terprogram, menggunakan data K-line, sering kali ada kebutuhan untuk menggunakan beberapa data K-line periode non-standar, seperti data K-line periode 12 menit, data K-line periode 4 jam, biasanya jenis nonstandar ini Periode tidak dapat diperoleh secara langsung. Jadi bagaimana kita menanggapi tuntutan semacam itu? Jawabannya tentu saja ada caranya. Siklus non-standar dapat diperoleh dengan menggabungkan dan mensintesis data dari siklus yang lebih kecil. Anda dapat membayangkan bahwa harga tertinggi dalam beberapa siklus dihitung sebagai harga tertinggi setelah sintesis, dan harga terendah dihitung sebagai harga terendah setelah sintesis. Pembukaan harga tidak akan berubah. , harga pembukaan pertama dari data bahan baku K-line yang disintesis digunakan, harga penutupan sesuai dengan harga penutupan terakhir dari data bahan baku K-line yang disintesis, waktunya adalah waktu dari harga pembukaan, dan volume perdagangan Dihitung dengan menjumlahkan volume transaksi data bahan mentah. Seperti yang ditunjukkan pada gambar:
Kami ambil pasar aset blockchain BTC_USDT sebagai contoh dan mensintesis 1 jam menjadi 4 jam.




|Waktu|Tinggi|Buka|Rendah|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 keempat siklus 1 jam tersebut digabungkan menjadi data siklus 4 jam. Harga pembukaan adalah harga pembukaan pada jam 00:00 pertama: 11382.57 Harga penutupan adalah harga terakhir, yaitu harga penutupan pada pukul 03:00: 11384.71 Harga tertinggi adalah harga tertinggi di sini: 11447.07 Harga terendah ada di sini: 11365.51 Waktu mulai siklus 4 jam adalah 00:00, waktu mulai jalur K 1 jam, yaitu 2019.8.12 00:00 Volume perdagangan dapat dijumlahkan setiap 1 jam (terutama untuk mengamati bagaimana harga disintesis, yang tidak ditampilkan dalam data volume perdagangan). Saya tidak akan membahas detailnya di sini.
Garis K 4 jam yang disintesis adalah: Tinggi: 11447.07 Buka: 11382.57 Rendah: 11365.51 Diterima: 11384.71 Waktu: 12.8.2019 00:00

Anda dapat melihat bahwa datanya konsisten.
Setelah memverifikasi gagasan awal, Anda dapat mulai menulis beberapa kode untuk menerapkan persyaratan ini secara awal.
Rilis kodenya langsung, kode ini hanya untuk referensi:
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 mensintesis K-line, ada dua hal yang dibutuhkan. Yang pertama adalah data bahan baku, yaitu data K-line dalam periode yang kecil.var r = exchange.GetRecords()
Data garis K periode kecil yang diperoleh. Yang kedua adalah mendefinisikan periode sintesis dengan jelas, yaitu periode target untuk sintesis data K-line.
Kemudian, melalui algoritma fungsi GetNewCycleRecords, data dari struktur array K-line yang disintesis akhirnya dapat dikembalikan.
Perlu dicatat bahwa:
00:00:00 ~ 00:12:00siklus kedua adalah00:12:00 ~ 00:24:00siklus ketiga adalah00:24:00 ~ 00:36:00siklus keempat adalah00:36:00 ~ 00:48:00siklus kelima adalah00:48:00 ~ 01:00:00 , yang berarti satu jam penuh.Jika siklusnya 13 menit, maka itu adalah siklus terbuka, dan data yang dihitung dalam siklus tersebut tidaklah unik, karena data hasil sintesis akan berbeda bergantung pada titik awal data hasil sintesis.
Disk sebenarnya dijalankan:

Bandingkan grafik pertukaran

Anggota grup sering mengajukan pertanyaan: Saya ingin menghitung rata-rata pergerakan harga tertinggi setiap garis K, apa yang harus saya lakukan?
Biasanya, kita menghitung rata-rata bergerak dengan menghitung rata-rata harga penutupan untuk membentuk rata-rata bergerak, tetapi kadang-kadang ada kebutuhan untuk menghitung harga tertinggi, harga terendah, harga pembukaan, dan sebagainya.
Saat ini, Anda tidak bisa hanyaexchange.GetRecords() Data garis K yang dikembalikan oleh fungsi tersebut langsung diteruskan ke fungsi perhitungan indikator.
Misalnya:
Fungsi perhitungan indikator moving average talib.MA memiliki dua parameter. Parameter pertama adalah data yang perlu dimasukkan, dan parameter kedua adalah parameter periode indikator.
Misalnya, kita ingin menghitung indikator berikut ini

Siklus K-line adalah 4 jam.
Pada grafik pertukaran, rata-rata pergerakan telah ditetapkan dengan parameter periode rata-rata pergerakan sebesar 9.
Dan sumber data untuk perhitungan ditetapkan pada harga tertinggi setiap Bar.
Artinya, rata-rata pergerakan ini adalah rata-rata harga tertinggi dari 9 batang garis K 4 jam, yang merupakan rata-rata pergerakan indikator.
Mari kita buat sendiri beberapa data dan lihat apakah datanya sama dengan data yang dihitung oleh grafik bursa.
var highs = []
for (var i = 0 ; i < r2.length ; i++) {
highs.push(r2[i].High)
}
Karena kita perlu menghitung rata-rata harga tertinggi setiap batang untuk memperoleh indikator rata-rata bergerak. Kemudian Anda perlu membuat suatu array terlebih dahulu, yang mana setiap elemen datanya sesuai dengan harga tertinggi setiap Bar. Anda dapat melihat bahwa variabel tertinggi awalnya berupa array kosong, lalu kita menelusuri variabel data candlestick r2 (tidak ingat r2? Lihat kode dalam fungsi utama sintesis candlestick 4 jam di atas). Baca harga tertinggi setiap batang r2 (yaitu r2[i].High , i berkisar dari 0 hingga r2.length - 1 ), lalu mendorongnya ke tertinggi. Dengan cara ini, struktur data dibangun yang berkorespondensi satu-satu dengan data Bar K-line.
Pada titik ini, nilai tertinggi dapat dilewatkan ke fungsi talib.MA untuk menghitung rata-rata pergerakan.
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)
}
}
Uji coba kembali:

Anda dapat melihat bahwa nilai indikator moving average pada posisi mouse pada gambar adalah11466.9289
Kode di atas dapat disalin ke dalam strategi untuk menjalankan pengujian. Jangan lupa untuk mencentang “Line Drawing Library” dan menyimpannya!
Platform Perdagangan Kuantitatif Inventor sudah memiliki antarmuka paket, yaitu fungsi exchange.GetRecords, yang dapat memperoleh data K-line. Berikut ini berfokus pada akses langsung ke antarmuka data K-line pertukaran untuk mendapatkan data, karena terkadang Anda perlu menentukan parameter untuk mendapatkan lebih banyak K-line, antarmuka GetRecords yang dienkapsulasi Biasanya 100 dikembalikan. Jika strategi awalnya membutuhkan lebih dari 100 K-lines, Anda perlu mengumpulkan dan menunggu. Agar strategi berjalan secepat mungkin, Anda dapat merangkum sendiri fungsinya, langsung mengakses antarmuka pertukaran K-line, dan menentukan parameter untuk memperoleh lebih banyak data K-line.
Mengambil pasangan perdagangan BTC_USDT Huobi sebagai contoh, kami menerapkan persyaratan ini:
Temukan dokumen API bursa dan lihat deskripsi antarmuka K-line:

https://api.huobi.pro/market/history/kline?period=1day&size=200&symbol=btcusdt
parameter: |Nama parameter|Jenis|Diperlukan|Deskripsi|Nilai| |-|-|-|-|-| |simbol|string|benar|Pasangan perdagangan|btcusdt, ethbtc…| |periode|string|true|Mengembalikan granularitas waktu data, yaitu interval waktu setiap lilin|1mnt, 5mnt, 15mnt, 30mnt, 60mnt, 1hari, 1bln, 1minggu, 1tahun| |ukuran|bilangan bulat|salah|Mengembalikan jumlah data K-line|[1, 2000]|
Kode uji:
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 mengakses antarmuka pertukaran Huobi:
#!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 mengakses antarmuka K-line Binance Exchange:
#!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画线类库


Kita dapat melihat di log bahwa records.length adalah 300 yang berarti ada 300 bar data rekaman K-line.
