アダプティブ・仮想通貨・グリッド・トレーディング・ストラテジー

作者: リン・ハーンチャオチャン開催日:2024年1月19日 14:17:50
タグ:

img

概要

これは,格子取引方法論に基づく適応型仮想通貨グリッド取引戦略である.市場変動に基づいて格子取引の価格範囲を自動的に調整し,その価格範囲内で効率的な格子取引を行うことができる.

戦略原則

この戦略の基本理念は

  1. 過去の高値と低値に基づいて,ダイナミックに取引格子価格範囲を計算する.

  2. この値範囲内で N つのグリッド線を等しい間隔で設定します.

  3. 価格が各グリッドラインを突破すると 定額でロングまたはショートポジションを開きます

  4. 隣接するグリッド線と 利益のための閉じるポジションの間での仲裁です

  5. 価格がグリッドレンジに戻ると,グリッドラインの限界コストでポジションを開くことを続けます.

  6. このサイクルは,グリッド価格範囲内の高周波アビタージ取引で繰り返す.

具体的には,この戦略は,設定されたlookbackウィンドウ (i_boundLookback) と波動性範囲 (i_boundDev) のパラメータに従って,グリッドの上限と下限をリアルタイムで計算します.

次に,Nのグリッドライン (i_gridQty) は上限と下限の間に均等に分けられます.これらのグリッドラインの価格は,グリッドLineArr配列に格納されます.

価格がグリッドラインを突破すると,固定量 (グリッド数で割った戦略資本) がロングまたはショートポジションを開くのに使用されます.オーダーレコードは,orderArr配列に保管されます.

価格が隣接したグリッドラインを再び突破すると 利回し先行オーダーと 利回し先行オーダーと 合わせることができます

価格変動範囲内での高周波アビタージではこのサイクルを繰り返す.

利点分析

この戦略の最大の利点は,従来の電力網戦略と比較して,電力網の範囲が市場変動に自動的に調整され,以下の特徴を持つことにある.

  1. 全自動で 手作業は必要ありません

  2. 価格の動向を把握し,トレンド方向で取引できる.

  3. 制御可能なリスク 片方的なリスクを追求を避けます

  4. 高い取引頻度と利益率

  5. 分かりやすい シンプルな構成です

  6. 高い資本利用率で 簡単に捕まらない

  7. リアルタイムで市場変化を反映し アルゴリズム取引に適しています

リスク分析

この戦略には多くの利点がありますが,いくつかのリスクもあります.

  1. 極端な物価変動で 損失が増える可能性があります

  2. 利益を得るために適切な保有期間と取引ペアが必要です

  3. 資本規模は 波動範囲に一致する必要があります

  4. パラメータの頻繁な監視と最適化が必要かもしれません.

対応措置には,次のものがあります.

  1. グリッドの範囲を拡大するために グリッドの距離を拡大します

  2. より安定した取引ペアを選択します.

  3. 十分な流動性を確保するために資本規模を調整する.

  4. 自動監視・警報メカニズムを確立する.

オプティマイゼーションの方向性

戦略は以下の側面で最適化できます.

  1. ダイナミックグリッド: 格子変動に基づいてグリッドパラメータを自動的に調整します.

  2. ストップ損失メカニズム: 極端なリスクを制限するために,合理的なストップ・ロスの位置を設定します.

  3. 複合格子: 時間を最大限に活用するために,異なるパラメータを使用してグリッドを組み合わせます.

  4. 機械学習ルールではなくパラメータを自動的に最適化するために ニューラルネットワークを使用します

  5. 市場間仲介: 取引所や通貨ペア間の仲介.

概要

概要すると,これはアービタージのための非常に実践的な適応型暗号グリッド取引戦略である.伝統的なグリッド戦略と比較して,最大の特徴は,市場の変化に基づいてグリッド範囲の自動調整であり,トレーダーは独自の取引範囲を構成することができます. 戦略ロジックは明確で理解し,設定するのが簡単で,いくつかの基礎を持つ個人投資家にも適しています. また,取引アルゴリズムのためのテンプレートとして. 適切なパラメータチューニングにより,非常に高い資本利用効率を達成することができます.


/*backtest
start: 2024-01-11 00:00:00
end: 2024-01-18 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("(IK) Grid Script", overlay=true, pyramiding=14, close_entries_rule="ANY", default_qty_type=strategy.cash, initial_capital=100.0, currency="USD", commission_type=strategy.commission.percent, commission_value=0.1)
i_autoBounds    = input(group="Grid Bounds", title="Use Auto Bounds?", defval=true, type=input.bool)                             // calculate upper and lower bound of the grid automatically? This will theorhetically be less profitable, but will certainly require less attention
i_boundSrc      = input(group="Grid Bounds", title="(Auto) Bound Source", defval="Hi & Low", options=["Hi & Low", "Average"])     // should bounds of the auto grid be calculated from recent High & Low, or from a Simple Moving Average
i_boundLookback = input(group="Grid Bounds", title="(Auto) Bound Lookback", defval=250, type=input.integer, maxval=500, minval=0) // when calculating auto grid bounds, how far back should we look for a High & Low, or what should the length be of our sma
i_boundDev      = input(group="Grid Bounds", title="(Auto) Bound Deviation", defval=0.10, type=input.float, maxval=1, minval=-1)  // if sourcing auto bounds from High & Low, this percentage will (positive) widen or (negative) narrow the bound limits. If sourcing from Average, this is the deviation (up and down) from the sma, and CANNOT be negative.
i_upperBound    = input(group="Grid Bounds", title="(Manual) Upper Boundry", defval=0.285, type=input.float)                      // for manual grid bounds only. The upperbound price of your grid
i_lowerBound    = input(group="Grid Bounds", title="(Manual) Lower Boundry", defval=0.225, type=input.float)                      // for manual grid bounds only. The lowerbound price of your grid.
i_gridQty       = input(group="Grid Lines",  title="Grid Line Quantity", defval=8, maxval=15, minval=3, type=input.integer)       // how many grid lines are in your grid

f_getGridBounds(_bs, _bl, _bd, _up) =>
    if _bs == "Hi & Low"
        _up ? highest(close, _bl) * (1 + _bd) : lowest(close, _bl)  * (1 - _bd)
    else
        avg = sma(close, _bl)
        _up ? avg * (1 + _bd) : avg * (1 - _bd)

f_buildGrid(_lb, _gw, _gq) =>
    gridArr = array.new_float(0)
    for i=0 to _gq-1
        array.push(gridArr, _lb+(_gw*i))
    gridArr

f_getNearGridLines(_gridArr, _price) =>
    arr = array.new_int(3)
    for i = 0 to array.size(_gridArr)-1
        if array.get(_gridArr, i) > _price
            array.set(arr, 0, i == array.size(_gridArr)-1 ? i : i+1)
            array.set(arr, 1, i == 0 ? i : i-1)
            break
    arr

var upperBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true) : i_upperBound  // upperbound of our grid
var lowerBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false) : i_lowerBound // lowerbound of our grid
var gridWidth       = (upperBound - lowerBound)/(i_gridQty-1)                                                       // space between lines in our grid
var gridLineArr     = f_buildGrid(lowerBound, gridWidth, i_gridQty)                                                 // an array of prices that correspond to our grid lines
var orderArr        = array.new_bool(i_gridQty, false)                                                              // a boolean array that indicates if there is an open order corresponding to each grid line

var closeLineArr    = f_getNearGridLines(gridLineArr, close)                                                        // for plotting purposes - an array of 2 indices that correspond to grid lines near price
var nearTopGridLine = array.get(closeLineArr, 0)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line above current price
var nearBotGridLine = array.get(closeLineArr, 1)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line below current price
strategy.initial_capital = 50000
for i = 0 to (array.size(gridLineArr) - 1)
    if close < array.get(gridLineArr, i) and not array.get(orderArr, i) and i < (array.size(gridLineArr) - 1)
        buyId = i
        array.set(orderArr, buyId, true)
        strategy.entry(id=tostring(buyId), long=true, qty=(strategy.initial_capital/(i_gridQty-1))/close, comment="#"+tostring(buyId))
    if close > array.get(gridLineArr, i) and i != 0
        if array.get(orderArr, i-1)
            sellId = i-1
            array.set(orderArr, sellId, false)
            strategy.close(id=tostring(sellId), comment="#"+tostring(sellId))

if i_autoBounds
    upperBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true)
    lowerBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false)
    gridWidth   := (upperBound - lowerBound)/(i_gridQty-1)
    gridLineArr := f_buildGrid(lowerBound, gridWidth, i_gridQty)

closeLineArr    := f_getNearGridLines(gridLineArr, close)
nearTopGridLine := array.get(closeLineArr, 0)
nearBotGridLine := array.get(closeLineArr, 1)





もっと