グリッド取引に基づく適応型暗号通貨裁定取引戦略


作成日: 2024-01-19 14:17:50 最終変更日: 2024-01-19 14:17:50
コピー: 1 クリック数: 1123
1
フォロー
1617
フォロワー

グリッド取引に基づく適応型暗号通貨裁定取引戦略

概要

この戦略は,グリッド取引理念に基づく自適性暗号通貨の利策である.市場変動に応じてグリッド取引の価格範囲を自動的に調整し,その価格範囲内で効率的な利取引を行うことができる.

戦略原則

この戦略の核心となる考えは,

  1. ダイナミクスは,歴史上の高点と低点に基づいて取引格子の価格範囲を計算します.

  2. この価格範囲内で,等間隔でN条の取引格子線を設定します.

  3. 価格が各格子線を突破すると,固定数量でポジションをオーバーまたは空にする.

  4. 隣接するグリッドラインの間で競り合い,利益を得た後に平仓する.

  5. 価格が格子領域に戻ったとき,格子線の限界コスト価格でポジションを開くことを続けます.

  6. 格子価格の範囲内で高頻度リベラル取引を行う.

具体的には,戦略は,配置された回顧窓 ((i_boundLookback) と波動区間の ((i_boundDev) パラメータに基づいて,格子価格の上下限をリアルタイムで計算する.

そして,上下限の間には,それぞれNの格子線 ((i_gridQty) を分割する.これらの格子線の価格は,gridLineArrの配列に保存される.

価格が格子線を突破すると,固定数量 ((策略本金分格子数量) でポジションをオーバーまたは空にする. 注文は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)