Khi viết và sử dụng các chiến lược, chúng ta thường sử dụng một số dữ liệu giai đoạn đường K hiếm khi được sử dụng. Tuy nhiên, trao đổi và nguồn dữ liệu không cung cấp dữ liệu về các giai đoạn này. Nó chỉ có thể được tổng hợp bằng cách sử dụng dữ liệu với một giai đoạn hiện có. thuật toán tổng hợp đã có phiên bản JavaScript (liên kếtTrong thực tế, nó rất dễ dàng để cấy ghép một phần mã JavaScript vào Python. tiếp theo, hãy viết một phiên bản Python của thuật toán tổng hợp K-line.
function GetNewCycleRecords (sourceRecords, targetCycle) { // K-line synthesis function
var ret = []
// Obtain the period of the source K-line data first
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
}
Có các thuật toán JavaScript. Python có thể được dịch và cấy ghép từng dòng một. Nếu bạn gặp các hàm JavaScript tích hợp hoặc các phương thức vốn có, bạn có thể đi đến Python để tìm các phương thức tương ứng. Do đó, việc di chuyển dễ dàng.
Logic thuật toán là chính xác như nhau, ngoại trừ rằng hàm JavaScript gọivar n=d.getTimezoneOffset()
Khi di chuyển đến Python,n=time.altzone
Các khác biệt khác chỉ là về ngữ pháp ngôn ngữ (chẳng hạn như việc sử dụng for for vòng lặp, giá trị Boolean, logic AND, logic NOT, logic OR, v.v.).
Mã Python di chuyển:
import time
def GetNewCycleRecords(sourceRecords, targetCycle):
ret = []
# Obtain the period of the source K-line data first
if not sourceRecords or len(sourceRecords) < 2 :
return None
sourceLen = len(sourceRecords)
sourceCycle = sourceRecords[-1]["Time"] - sourceRecords[-2]["Time"]
if targetCycle % sourceCycle != 0 :
Log("targetCycle:", targetCycle)
Log("sourceCycle:", sourceCycle)
raise "targetCycle is not an integral multiple of sourceCycle."
if (1000 * 60 * 60) % targetCycle != 0 and (1000 * 60 * 60 * 24) % targetCycle != 0 :
Log("targetCycle:", targetCycle)
Log("sourceCycle:", sourceCycle)
Log((1000 * 60 * 60) % targetCycle, (1000 * 60 * 60 * 24) % targetCycle)
raise "targetCycle cannot complete the cycle."
multiple = targetCycle / sourceCycle
isBegin = False
count = 0
barHigh = 0
barLow = 0
barOpen = 0
barClose = 0
barTime = 0
barVol = 0
for i in range(sourceLen) :
# Get the time zone offset value
n = time.altzone
if ((1000 * 60 * 60 * 24) - (sourceRecords[i]["Time"] * 1000) % (1000 * 60 * 60 * 24) + (n * 1000)) % targetCycle == 0 :
isBegin = True
if isBegin :
if count == 0 :
barHigh = sourceRecords[i]["High"]
barLow = sourceRecords[i]["Low"]
barOpen = sourceRecords[i]["Open"]
barClose = sourceRecords[i]["Close"]
barTime = sourceRecords[i]["Time"]
barVol = sourceRecords[i]["Volume"]
count += 1
elif count < multiple :
barHigh = max(barHigh, sourceRecords[i]["High"])
barLow = min(barLow, sourceRecords[i]["Low"])
barClose = sourceRecords[i]["Close"]
barVol += sourceRecords[i]["Volume"]
count += 1
if count == multiple or i == sourceLen - 1 :
ret.append({
"High" : barHigh,
"Low" : barLow,
"Open" : barOpen,
"Close" : barClose,
"Time" : barTime,
"Volume" : barVol,
})
count = 0
return ret
# Test
def main():
while True:
r = exchange.GetRecords()
r2 = GetNewCycleRecords(r, 1000 * 60 * 60 * 4)
ext.PlotRecords(r2, "r2")
Sleep(1000)
Biểu đồ thị trường Huobi
Biểu đồ 4 giờ tổng hợp backtest
Mã ở trên chỉ để tham khảo. Nếu nó được sử dụng trong các chiến lược cụ thể, vui lòng sửa đổi và thử nghiệm theo các yêu cầu cụ thể. Nếu có lỗi hoặc đề xuất cải tiến, vui lòng để lại một tin nhắn. cảm ơn rất nhiều. o ^ ^ o