您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Go語言怎么處理程序化交易中的K線數據”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Go語言怎么處理程序化交易中的K線數據”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
前言
在編寫程序化交易策略時,使用K線數據,經常會有需求使用一些非標準周期K線數據的情況,例如需要使用12分鐘周期K線數據、4小時K線周期數據,通常這類非標準周期是無法直接獲取的。那么我們如何應對此類需求呢?
答案肯定是有辦法的。
非標準周期可以通過更小周期的數據,合并合成獲取,可以想象一下,多個周期中的最高價,算作合成后的最高價,最低價算作合成后的最低價,開盤價不會變,就用合成這根K線原料數據的第一個開盤價,收盤價對應的是用合成這根K線的原料數據的最后一個的收盤價,時間就是取的開盤價的時間,成交量用原料數據的交易量求和計算得出。
思路
我們以區塊鏈資產市場BTC_USDT為例,用1小時合成為4小時。
可以看到數據是一致的。
編寫代碼實現
驗證了初步的思路,就可以動手寫一寫代碼初步實現一下這個需求了。直接放出代碼,代碼僅供參考學習:
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線接口獲取數據過于頻繁,導致交易所限制。 } }
其實要合成K線,就需要兩個東西,第一是需要原料數據,即小周期的K線數據,例子中 var r = exchange.GetRecords()。
獲取的小周期K線數據。第二是需要明確合成為多大的周期,即K線數據合成的目標周期。然后通過GetNewCycleRecords函數的算法,就可以最后返回一個合成出來的K線數組結構的數據了。實盤運行了一下:
對比交易所圖表
需要注意的是:目標周期不能小于你傳入GetNewCycleRecords 函數作為數據原料的K線的周期,因為無法用小周期去合成更小的周期的數據。設置的目標周期必須是周期閉合的。例如 12分鐘周期的K線,從每個小時的0分0秒開始(以0時舉例),第一個周期是00:00:00 ~ 00:12:00
,第二個周期是00:12:00 ~ 00:24:00
,第三個周期是00:24:00 ~ 00:36:00
,第四個周期是00:36:00 ~ 00:48:00
,第五個周期是00:48:00 ~ 01:00:00
,正好組成一個完整的1小時。如果是 13分鐘周期,就是不閉合的周期,這樣的周期算出的數據不唯一,因為根據合成的數據起始點不同,合成出來的數據有差異。
使用K線數據構造需要的數據結構
經常有群友提問,我想計算每根K線的最高價的均線,怎么辦?通常,我們計算均線都是計算的收盤價的均值,組成均線,但是也有時候有需求計算最高價、最低價、開盤價等等。這個時候就不能直接把exchange.GetRecords()
函數返回的K線數據直接傳入 指標計算函數了。例如:talib.MA 均線指標計算函數有兩個參數,第一個參數是需要傳入的數據,第二個參數是指標周期參數。例如我們要算如下圖的指標:
K線周期是4小時,在交易所圖表上,已經設置好了一條均線,均線周期參數為9。并且設置計算的數據源是每根Bar的最高價。
即這條均線是9個4小時周期K線Bar的最高價平均計算出的均值,組成的指標均線。我們自己動手構造一個數據算下,看是不是和交易所的圖表計算得出的一樣。
var highs = [] for (var i = 0 ; i < r2.length ; i++) { highs.push(r2[i].High) }
既然要計算每根Bar的最高價的均值得出均線指標。那么就需要先構造一個數組,其中每個數據元素都是對應每根Bar的最高價。可以看到 highs 變量初始為一個空數組,然后我們遍歷 r2 這個K線數據變量(不記得r2了?看下上面合成4小時K線的main函數中的代碼)。讀取r2每根Bar的最高價(即 r2[i].High , i取值范圍 從 0 到 r2.length - 1 ),然后 push 進highs 。這樣就構造了一個和K線數據Bar一一對應的數據結構。此時 highs 就可以傳入 talib.MA函數計算出均線了。
完整的例子:
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) } }
回測運行:
可以看到 圖中鼠標停留位置的均線指標值均為 11466.9289
。以上代碼可以復制到策略中運行測試,記得勾選「畫線類庫」后保存!
數字貨幣市場的K線數據獲取方式
發明者量化交易平臺已經有封裝好的接口,即 exchange.GetRecords 函數,即可獲取K線數據。下面著重講解的是直接訪問交易所K線數據接口獲取數據,因為有時候需要指定參數獲取更多的K線,封裝的GetRecords 接口一般是返回 100根。如果遇到策略初始需要超過100根的K線時,就需要收集等待。
為了讓策略盡快進行運作,可以自己封裝一個函數,直接訪問交易所K線接口,指定參數獲取更多的K線數據。以火幣幣幣交易 BTC_USDT 交易對為例,我們實現這個需求:找到交易所的API文檔,查看K線接口描述:
https://api.huobi.pro/market/history/kline?period=1day&size=200&symbol=btcusdt
參數:
測試代碼:
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") }
可以看到日志上,打印 records.length 為 300, 即 records K線數據 bar 數量有300根。
讀到這里,這篇“Go語言怎么處理程序化交易中的K線數據”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。