Type/to search
8
Follow
1363
Followers
プログラム取引におけるKラインデータ処理に関する簡単な説明
Discussions
Created 2019-08-13 11:11:38  Updated 2023-10-20 20:06:13
 8
 4973

img

プログラム取引におけるKラインデータ処理に関する簡単な説明

Kラインデータを使用してプログラムによる取引戦略を作成する場合、通常、12分周期のKラインデータ、4時間周期のKラインデータなど、非標準の周期のKラインデータを使用する必要があることがよくあります。このような非標準的な期間は直接取得できません。では、このような要求に私たちはどう応えればよいのでしょうか?
答えは、間違いなく方法はあるということです。
非標準サイクルは、より小さなサイクルのデータを統合して合成することで得られます。複数のサイクルの最高価格は合成後の最高価格としてカウントされ、最低価格は合成後の最低価格としてカウントされることを想像してください。価格は変更されません。、合成Kラインの原材料データの最初の始値が使用され、終値は合成Kラインの原材料データの最後の終値に対応し、時間は時間です。始値、出来高は原材料データの取引量を合計して算出します。
写真の通り:

  • アイデア

    ブロックチェーン資産市場 BTC_USDT を例に、1 時間を 4 時間に合成します。

    img

    img

    img

    img

    時間高値始値安値終値
    2019.8.12 00:0011447.0711382.5711367.211406.92
    2019.8.12 01:001142011405.6511366.611373.83
    2019.8.12 02:0011419.2411374.6811365.5111398.19
    2019.8.12 03:0011407.8811398.5911369.711384.71

    これら4つの1時間サイクルのデータは4時間サイクルデータに統合されます。始値は最初の00:00の始値: 11382.57です。
    終値は最後のもの、つまり03:00の終値:11384.71です。
    最高価格はここの最高価格です: 11447.07
    最低価格はここです: 11365.51
    4時間サイクルの開始時間は00:00、1時間Kラインの開始時間は2019.8.12 00:00です。
    取引量は1時間ごとに集計できます(主に、取引量データには表示されない価格の合成方法を観察するため)。ここでは詳細には触れません。

    合成された 4 時間の K ラインは次のとおりです。
    高値: 11447.07
    オープン: 11382.57
    安値: 11365.51
    受信数: 11384.71
    時間: 2019.8.12 00:00

    img

    データが一貫していることがわかります。

  • 実装するためのコードを書く

    予備的なアイデアを検証した後、この要件を予備的に実装するためのコードの作成を開始できます。

    コードを直接リリースします。コードは参照用です。

    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 ラインを合成するには、2 つのものが必要です。1 つ目は、生の材料データ、つまり、小周期の K ライン データです。var r = exchange.GetRecords()
    得られた小周期K線データ。 2つ目は、Kラインデータ合成の対象期間である合成期間を明確に定義することです。
    その後、GetNewCycleRecords 関数のアルゴリズムを通じて、合成された K ライン配列構造のデータが最終的に返されます。
    以下の点に注意してください。

      1. ターゲット サイクルは、GetNewCycleRecords 関数にデータ原材料として渡す K ラインのサイクルよりも小さくすることはできません。
        これは、小さなサイクルを使用して、より小さなサイクルからのデータを合成することが不可能であるためです。
      1. 設定する対象期間は、終了した期間である必要があります。
        サイクルクローズとは何ですか?
        簡単に言えば、1 時間または 1 日以内に、ターゲット サイクル時間の範囲が組み合わされて、閉じたループが形成されます。
        例:
        例えば、12分周期のKラインは毎時0:00(0:00を例にとる)に始まり、最初の周期は00:00:00 ~ 00:12:002番目のサイクルは00:12:00 ~ 00:24:003番目のサイクルは00:24:00 ~ 00:36:004番目のサイクルは00:36:00 ~ 00:48:00、第5サイクルは00:48:00 ~ 01:00:00 、合計1時間になります。

      13 分周期の場合はオープン サイクルであり、このようなサイクルで計算されるデータは、合成データの開始点によって合成データが異なるため、一意ではありません。

    実際のディスクは次のように実行されました:
    img

    為替チャートを比較する
    img

  • Kラインデータを使用して必要なデータ構造を構築する

    グループのメンバーからよく質問があります: 各 K ラインの最高価格の移動平均を計算したいのですが、どうすればいいですか?

    通常、移動平均線は終値の平均を計算して移動平均線を形成しますが、最高値、最安値、始値などを計算する必要がある場合もあります。
    現時点では、exchange.GetRecords() 関数によって返される K ライン データは、インジケーター計算関数に直接渡されます。

    例えば:
    talib.MA 移動平均インジケーター計算関数には 2 つのパラメーターがあります。最初のパラメーターは渡す必要のあるデータであり、2 番目のパラメーターはインジケーター期間パラメーターです。
    例えば、次の指標を計算したいとします。
    img

    Kラインサイクルは4時間です。
    為替チャートでは、移動平均期間パラメータが 9 で移動平均が設定されています。
    そして計算のデータソースは各バーの最高価格に設定されています。
    img
    つまり、この移動平均は、インジケーターの移動平均を構成する 9 本の 4 時間 K ライン バーの最高価格の平均です。

    自分でデータを構築し、それが取引所のチャートで計算されたものと同じかどうかを確認してみましょう。

    var highs = [] for (var i = 0 ; i < r2.length ; i++) { highs.push(r2[i].High) }

    移動平均インジケーターを導出するには、各バーの最高価格の平均を計算する必要があるためです。
    次に、各データ要素が各バーの最高価格に対応する配列を最初に構築する必要があります。
    highs 変数は最初は空の配列であり、次に r2 ローソク足データ変数を走査していることがわかります (r2 を覚えていませんか? 上記の 4 時間ローソク足を合成するメイン関数のコードを参照してください)。
    r2の各バーの最高価格を読み取ります(つまりr2[i].High 、 i の範囲は 0 から r2.length - 1 ) で、それを highs にプッシュします。このようにして、K ライン データ バーと 1 対 1 に対応するデータ構造が構築されます。

    この時点で、高値を 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) } }

    バックテストの実行:

    img

    図のマウス位置の移動平均指標の値は11466.9289

    上記のコードを戦略にコピーしてテストを実行できます。「線画ライブラリ」をチェックして保存することを忘れないでください。

  • デジタル通貨市場でKラインデータを取得する方法

    Inventor Quantitative Trading Platform には、K ライン データを取得できる exchange.GetRecords 関数というパッケージ化されたインターフェイスがすでにあります。
    以下では、データを取得するために交換Kラインデータインターフェースに直接アクセスすることに焦点を当てています。これは、より多くのKラインを取得するためにパラメータを指定する必要があることがあるためです。カプセル化されたGetRecordsインターフェース
    通常は100個が返されます。戦略が最初に 100 を超える K ラインを必要とする場合は、収集して待機する必要があります。
    戦略をできるだけ速く実行するために、関数を自分でカプセル化し、取引所の K ライン インターフェイスに直接アクセスし、パラメータを指定してより多くの K ライン データを取得することができます。

    Huobi の BTC_USDT 取引ペアを例にとると、この要件を実装します。

    取引所の API ドキュメントを見つけて、K ライン インターフェースの説明を表示します。
    img

    https://api.huobi.pro/market/history/kline?period=1day&size=200&symbol=btcusdt

    パラメータ:

    パラメータ名タイプ必須説明
    シンボル文字列true取引ペアbtcusdt、ethbtc...
    period文字列trueデータの時間粒度、つまり各キャンドルの時間間隔を返します1分、5分、15分、30分、60分、1日、1か月、1週間、1年
    sizeintegerfalseK ラインデータの数を返します[1, 2000]

    テストコード:

    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") }

    Python バージョン、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画线类库

Python バージョン、Binance Exchange の K ライン インターフェースにアクセスする例:

#!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画线类库

img

img

ログを見ると、records.length が 300 であることがわかります。これは、K ライン データのレコードが 300 バーあることを意味します。
img

Related Recommendations
Comment
All comments (8)

    贴主能修复一下问题么?无法用3小时或6小时k合成日k

    6 years ago

    好的,抽时间改改。

    6 years ago

    if (((1000 * 60 * 60 * 24) - sourceRecords[i].Time % (1000 * 60 * 60 * 24) + (n * 1000 * 60)) % targetCycle == 0) {
    isBegin = true
    }

    这一句有问题,无法用3小时或6小时k合成日k,只能用1小时,2小时,4小时的k线合成日k

    6 years ago

    如果要爬某品种全部的历史数据也能爬么?

    6 years ago

    这是访问交易所接口数据的,交易所给你多少数据就是多少。也就是最近的几百根吧一般来说。

    6 years ago

    感谢回复

    7 years ago

    请问,如果想要超过300根,怎么处理比较好呢?比如1000根K线数据。交易所单次好像支持每次300根。多谢

    7 years ago

    如果 超过交易所接口支持的最大返回数量,这样只能收集数据,等足够K线数据量。

    7 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)