Trong việc viết các chiến lược giao dịch lập trình, sử dụng dữ liệu K-line thường có nhu cầu sử dụng một số dữ liệu K-line không chuẩn, ví dụ như sử dụng dữ liệu K-line 12 phút, dữ liệu K-line 4 giờ, thường không thể truy cập trực tiếp. Vậy làm thế nào để đối phó với nhu cầu như vậy? Câu trả lời chắc chắn là có cách nào đó. Các chu kỳ phi tiêu chuẩn có thể được thu thập tổng hợp thông qua dữ liệu từ các chu kỳ nhỏ hơn, bạn có thể tưởng tượng, giá cao nhất trong nhiều chu kỳ, được tính là giá cao nhất sau khi tổng hợp, giá thấp nhất được tính là giá thấp nhất sau khi tổng hợp, giá mở không thay đổi, giá mở đầu tiên được tính bằng dữ liệu nguyên liệu của đường K, giá đóng tương ứng với giá đóng cuối cùng của dữ liệu nguyên liệu của đường K, thời gian là thời gian của giá mở, khối lượng giao dịch được tính toán và tìm kiếm dữ liệu nguyên liệu. Những người bị ảnh hưởng là:
Ví dụ như trên thị trường tài sản blockchain BTC_USDT, một giờ trở thành 4 giờ.
Thời gian | cao | Mở | thấp | Lưu ý |
---|---|---|---|---|
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 |
Bốn chu kỳ 1 giờ này, tổng hợp dữ liệu của một chu kỳ 4 giờ gốc, giá mở là giá mở đầu tiên vào 00:00:11382.57 Giá đóng là giá đóng cuối cùng, tức là lúc 03:00: 11384.71 Giá cao nhất là giá cao nhất ở đây: 11447.07 Giá thấp nhất tìm giá thấp nhất ở đây: 11365.51 Thời gian bắt đầu của dòng K 1 giờ này là 2019.8.12 00:00 Số lượng giao dịch mỗi giờ (chỉ cần xem giá được tổng hợp như thế nào, không được hiển thị trong dữ liệu giao dịch) không được mô tả ở đây.
Một dòng K dài 4 giờ được tổng hợp: Cao: 114477 Mở: 11382.57 Giảm: 11365.51 Lưu ý: 11384.71 Thời gian: 19.8.12 00:00
Bạn có thể thấy dữ liệu phù hợp.
Một khi ý tưởng ban đầu đã được xác minh, bạn có thể tự viết mã để thực hiện nhu cầu ban đầu.
Có thể bạn sẽ thấy một số hình ảnh của những người đang sử dụng ứng dụng này.
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线接口获取数据过于频繁,导致交易所限制。
}
}
Thực tế là để tổng hợp các đường k, bạn cần hai thứ, thứ nhất là bạn cần dữ liệu nguyên liệu, dữ liệu đường k trong chu kỳ nhỏ, ví dụ như trong ví dụ này.var r = exchange.GetRecords()
Dữ liệu đường K chu kỳ nhỏ được thu thập. Thứ hai, cần phải xác định rõ ràng các chu kỳ lớn như thế nào, đó là các chu kỳ mục tiêu để tổng hợp dữ liệu đường K.
Sau đó, các thuật toán của hàm GetNewCycleRecords có thể trả về dữ liệu của một cấu trúc matrix K-line tổng hợp.
Những điều cần lưu ý:
1, chu kỳ mục tiêu không thể nhỏ hơn chu kỳ của K dòng của hàm GetNewCycleRecords như là dữ liệu nguyên liệu. Vì không thể tổng hợp dữ liệu từ các chu kỳ nhỏ hơn với các chu kỳ nhỏ hơn.
2, Các chu kỳ mục tiêu được đặt phải đóng chu kỳ.
Đó là một sự kết thúc của một chu kỳ.
Nói một cách đơn giản, trong một giờ hoặc trong một ngày, các phạm vi thời gian của chu kỳ mục tiêu được kết hợp với nhau để tạo thành một vòng tròn khép kín.
Ví dụ:
Ví dụ, đường K có chu kỳ 12 phút, bắt đầu từ 0 phút 0 giây trong mỗi giờ (ví dụ như 0 giờ), và chu kỳ đầu tiên là00:00:00 ~ 00:12:00
Và chu kỳ thứ hai là00:12:00 ~ 00:24:00
Và chu kỳ thứ ba là00:24:00 ~ 00:36:00
Chu kỳ thứ tư là00:36:00 ~ 00:48:00
Và chu kỳ thứ năm là00:48:00 ~ 01:00:00
Trong khi đó, một người đàn ông người Việt Nam có thể nói rằng:
Nếu là chu kỳ 13 phút, hay là chu kỳ không đóng, dữ liệu được tính toán theo chu kỳ như vậy không phải là duy nhất, bởi vì dữ liệu tổng hợp khác nhau tùy thuộc vào điểm bắt đầu của dữ liệu tổng hợp.
Một người đàn ông người Việt Nam nói với một người đàn ông khác:
Biểu đồ giao dịch so sánh
Một câu hỏi thường được đặt ra là tôi muốn tính giá trung bình cao nhất cho mỗi đường K.
Thông thường, chúng ta tính đường trung bình là giá trung bình của giá đóng, tạo thành đường trung bình, nhưng đôi khi cũng có nhu cầu tính giá cao nhất, giá thấp nhất, giá mở, v.v.
Không thể nói trực tiếp.exchange.GetRecords()
Dữ liệu đường K mà hàm trả về được truyền trực tiếp vào hàm tính chỉ số.
Ví dụ:talib.MAChức năng tính toán chỉ số đường thẳng có hai tham số, tham số đầu tiên là dữ liệu cần được truyền và tham số thứ hai là tham số chu kỳ chỉ số. Ví dụ, chúng ta sẽ tính các chỉ số như trên.
Một số người nói rằng, "K-line là một hệ thống máy tính có thể hoạt động trong vòng 4 giờ". Trên biểu đồ giao dịch, một đường trung bình đã được thiết lập với tham số chu kỳ đường trung bình là 9. Và các nguồn dữ liệu được tính toán là giá cao nhất cho mỗi Bar.Đường trung bình này là đường trung bình được tính trung bình giá cao nhất của 9 chu kỳ 4 giờ K-LineBar, bao gồm đường trung bình của chỉ số.
Chúng tôi tự xây dựng một số liệu để xem liệu nó có giống như các biểu đồ trên sàn giao dịch hay không.
var highs = []
for (var i = 0 ; i < r2.length ; i++) {
highs.push(r2[i].High)
}
Vì vậy, để tính toán giá cao nhất cho mỗi Bar, giá trung bình được đưa ra chỉ số đường thẳng. Sau đó, bạn cần phải tạo ra một mảng mà mỗi phần tử dữ liệu là giá trị cao nhất của mỗi Bar. Bạn có thể thấy rằng các biến highs bắt đầu như một mảng trống, sau đó chúng ta đi qua biến dữ liệu đường K này r2 (không nhớ r2? Xem mã trong hàm chính của đường K tổng hợp 4 giờ ở trên). Đọc giá trị cao nhất của r2 trên mỗi Bar (tức là r2[i].High, i lấy giá trị trong phạm vi từ 0 đến r2.length-1), và đẩy vào highs.
Khi đó, các highs có thể được truyền vào talib.
Một ví dụ hoàn chỉnh:
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)
}
}
Khả năng kiểm tra lại:
Bạn có thể thấy ở trên biểu đồ, các chỉ số đường trung tuyến của vị trí chuột dừng lại là11466.9289
Mã trên có thể được sao chép để chạy thử nghiệm trong chính sách, hãy nhớ chọn "Draw Line Library" để lưu!
Các nhà phát minh của nền tảng giao dịch định lượng đã có một giao diện được đóng gói sẵn, đó là chức năng exchange.GetRecords, có thể lấy dữ liệu từ K-line. Dưới đây là một giải thích về việc truy cập trực tiếp vào giao dịch K-line giao diện dữ liệu để lấy dữ liệu, vì đôi khi cần phải chỉ định các tham số để lấy nhiều hơn K-line, bao gồm giao diện GetRecords Thông thường trả về 100 thẻ. Nếu gặp phải một chiến lược yêu cầu ban đầu hơn 100 thẻ, bạn cần phải thu thập chờ. Để làm cho chính sách hoạt động càng nhanh càng tốt, bạn có thể tự đóng gói một hàm, truy cập trực tiếp vào giao diện K-Line của sàn giao dịch, chỉ định tham số để lấy nhiều dữ liệu K-Line hơn.
Với cặp giao dịch BTC_USDT, chúng tôi thực hiện nhu cầu này:
Tìm tài liệu API của sàn giao dịch và xem mô tả giao diện K-Line:
https://api.huobi.pro/market/history/kline?period=1day&size=200&symbol=btcusdt
Các thông số:
Tên tham số | Loại | Phải không? | Mô tả | Lấy giá trị |
---|---|---|---|---|
biểu tượng | chuỗi | đúng | Giao dịch | Btcusdt, ethbtc... |
thời gian | chuỗi | đúng | Trả về độ phân tử thời gian dữ liệu, tức là khoảng thời gian của mỗi đoạn. | 1 phút, 5 phút, 15 phút, 30 phút, 60 phút, 1 ngày, 1 tháng, 1 tuần, 1 năm |
kích thước | số nguyên | sai | Trả về các đoạn dữ liệu đường K | [1, 2000] |
Mã kiểm tra:
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")
}
Phiên bản Python, ví dụ về cách truy cập giao diện sàn giao dịch 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画线类库
Phiên bản Python, ví dụ về giao diện K-Line để truy cập 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画线类库
Bạn có thể thấy trên nhật ký, in records.length là 300, nghĩa là records K là số lượng các thanh dữ liệu trên dòng có 300.
BamsmenBạn có thể sửa được vấn đề này không? Bạn không thể tổng hợp k ngày trong 3 giờ hoặc 6 giờ.
Bamsmenif (((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) {
isBegin = true
xis2004Nếu bạn muốn leo lên tất cả các dữ liệu lịch sử của một giống, bạn có thể leo lên không?
willzhangCảm ơn bạn đã trả lời.
willzhangXin hỏi, làm thế nào để xử lý tốt hơn nếu bạn muốn hơn 300 bit? ví dụ: 1000 K-line dữ liệu.
Những nhà phát minh định lượng - những giấc mơ nhỏĐược rồi, hãy thay đổi thời gian nhé.
Những nhà phát minh định lượng - những giấc mơ nhỏĐây là số lượng dữ liệu mà giao dịch cung cấp cho bạn.
Những nhà phát minh định lượng - những giấc mơ nhỏNếu vượt quá số lượng trả về tối đa được hỗ trợ bởi giao diện giao dịch, chỉ có thể thu thập dữ liệu, và như vậy đủ dữ liệu K-line.