
適応格子取引戦略は,格子取引システムに基づく量化戦略で,格子線の位置を自動的に調整することで市場の変化に対応する.この戦略は,複数の技術指標を使用して最適な取引ポイントを計算し,価格の変動に応じて格子を動的に更新する.その核心思想は,設定された価格区間内で,価格が格子設定の格子線に触れたときに買いまたは売り操作を実行し,市場波動によってもたらされる利益の機会を捕捉することである.この戦略は,その弾力的な仕組み ((Elasticity) と遅延パラメータ ((Laziness) の特徴で,格子が異なる市場環境に適応するために自動的に調整でき,より柔軟な取引実行を実現する.
この戦略は,以下のコアコンポーネントと働き方に基づいています.
スムーズな処理メカニズム戦略は,まず価格を平滑に処理し,複数の移動平均型 (線形回帰,SMA,EMA,VWMA,TEMA) をサポートし,ユーザーは好みのまま適切な平滑方法を選択することができます.
遅延パラメータはこれは戦略の重要な革新点であり,遅延関数lz (()) を導入することで,価格の変化が一定パーセントを超えるとのみ,システムが信号を更新し,市場騒音を効果的にフィルターする.
格子構造機構:
信号生成論理:
取引制御機構:
動態格子更新: 怠惰な移動平均 (LMA) が変化すると,全格子構造が再調整され,戦略が新しい価格区間に適応します.
戦略は,各格子線の価格を配列で保存し,格子線と価格の交差を計算して,不必要な取引を避けるために,複数の拘束条件を考慮しながら,特定の買取りポイントを決定します.
適応力があるこの戦略の最大の利点は,人為的な介入なしに,市場の変化に応じてグリッドの位置を自動的に調整できることです. 弹性パラメータと点調整機構により,グリッドは価格の傾向の変化に合わせて移動し,常に関連性があります.
騒音フィルター遅延パラメータ ((Laziness) の導入は,価格の変化が十分に顕著である場合にのみ格子調整を誘発することを保証する革新であり,市場騒音への反応を効果的に軽減し,戦略の安定性を向上させる.
柔軟なカスタマイズ: 戦略は,格子数,格子間隔,方向の好み,平滑型など,多くのパラメータの設定を提供します. ユーザーは,異なる市場特性と個人取引スタイルに応じて調整することができます.
取引エリアを視覚化: 策略は,現在のアクティブな取引区間を,色で満たして表示し,取引者が,現在の価格がグリッド内の位置を直感的に理解できるようにし,意思決定を容易にする.
リスク管理: 取引を特定のグリッドの範囲内でのみ行うように制限することで,戦略は極端な市場条件下での不利な取引を防ぐための自然なリスク制御機構を確立します.
統一された出場論理: 取引論理の一致性と予測性を維持するために,同じグリッドラインを買取と販売の信号として使用する.
区間突破の危険性この戦略は本質的に区間取引戦略であり,強いトレンド市場では継続的な損失に直面する可能性があります.価格が格子上の下限を突破し,一方的な動きを継続すると,戦略は誤った方向で継続的にポジションを上げる可能性があります. 解決策は,トレンド認識コンポーネントを追加するか,トレンドが確立されたときに格子取引を一時停止することです.
パラメータ感度: 戦略の性能は,パラメータの設定,特に遅延パラメータ ((Laziness) と弾性パラメータ ((Elasticity) に大きく依存する. 不適切なパラメータは,グリッドの調整が遅かれ早かれまたは過度に敏感になる可能性がある. 異なる市場環境でリターンでこれらのパラメータを最適化することを推奨する.
ピラミッド型のリスク戦略は,同じ方向に複数の入場を許容する ((pyramiding=4),極端な市場条件では,過度なレバレッジとリスク集中につながる可能性がある.最大保有限とダイナミックなポジション管理の設定を考慮する必要があります.
スライドポイントと手数料の影響:格子取引戦略は通常,頻繁な取引を伴う.実際の実行では,滑り点と手数料が戦略の収益性に著しく影響する可能性があります.これらの要因は,反測に含まれ,取引頻度とコストをバランスさせるために格子間隔を調整する必要がある可能性があります.
信号衝突処理: 買出信号が同時に発生すると,現在の戦略は2つの信号を無視することを選択し,これは重要な取引の機会を逃す可能性があります. 追加の市場指標または価格パターンに基づいて信号の衝突を解決することを考えることができます.
適応パラメータの調整: 戦略は,市場変動に応じて格子間隔と遅延パラメータを自動的に調整するためにさらに最適化できます.例えば,高変動の市場で格子間隔を増加させ,低変動の市場で格子間隔を減少させ,戦略を異なる市場条件により良く適応させることができます.
トレンド認識コンポーネントを統合する: 現行の戦略は,トレンド市場ではうまく行かない可能性があり,トレンド識別指標 (ADX,移動平均の交差など) を導入し,強いトレンドが認識されたときに取引方向を自動的に調整したり,格子取引を一時停止したりすることができます.
ダイナミックなポジション管理:現在の戦略は,固定ポジションサイズを使用し,リスクベースのダイナミックポジション管理に改めることができます.例えば,ATR (平均リアル波幅) に基づいてポジションサイズを調整するか,または口座の純資産のパーセントに基づいて資金を配分します.
多時間枠分析: 複数の時間枠分析を導入し,より長い時間周期のトレンド方向を用いて取引信号をフィルタリングし,より大きな時間枠のトレンド方向にのみグリッド取引を実行する.
完璧なストップロスメカニズム:現在の戦略には明確なストップ・メカニズムがないため,市場全体の状況に基づいて全局的なストップを追加したり,単一の取引の最大損失を制限するために各格子レベルに個別のストップ・ポイントを設定したりできます.
試合開始時の最適化: 戦略は,取引量または価格動力の指標を統合して,格子信号がトリガーされたときに,追加のフィルタリング条件によって特定の出場時刻を最適化し,成功率を向上させることができます.
機械学習の統合: 格子位置とパラメータ選択を最適化するために機械学習アルゴリズムを使用し,歴史データ訓練モデルを使用して最適な格子設定を予測し,戦略の適応性をさらに向上させることができます.
適応格子取引戦略は,革新的な遅延関数とダイナミック格子調整メカニズムによって,従来の格子取引戦略の柔軟性の欠如の問題に解決する.それは,市場の変化に自動的に適応し,異なる価格区間の間の取引機会を捉え,複数のパラメータを通じて取引行動を制御することができる.この戦略は,揺れ動いている市場での適用に適しており,合理的な格子間隔と方向の好みを設定することで,自動取引実行を実現することができる.
区間突破リスクやパラメータの感受性などの潜在的な問題があるにもかかわらず,トレンド識別と動的パラメータ調整などの最適化方向を統合することによって,この戦略は,さまざまな市場環境で安定したパフォーマンスを発揮する可能性がある.実用的なアプリケーションでは,戦略の性能,特に異なる市場条件下でのパフォーマンスを全面的に反省して検証し,特定の取引品種の特性に合わせてパラメータを調整して最適な効果を達成することをお勧めします.
//@version=5
// This source code is subject to the terms of the Mozilla Public License 2.0 https://mozilla.org/MPL/2.0/
// ©mvs1231 || xxattaxx
strategy(title='Grid Bot Auto Strategy', shorttitle='GridBot', initial_capital = 100000, overlay=true, pyramiding=4, default_qty_type = strategy.fixed, default_qty_value = 0, commission_value = 0.04, commission_type = strategy.commission.percent, margin_long = 0, margin_short = 0, process_orders_on_close = true)
//----<User Inputs>------------------------------------------------------------------------------//
iLen = input.int(7, 'Smoothing Length(7)', minval=1)
iMA = input.string('lreg', 'Smoothing Type', options=['lreg', 'sma', 'ema', 'vwma', 'tema'])
iLZ = input.float(4.0, 'Laziness(4%)', step=.25) / 100
iELSTX = input(50.0, 'Elasticity(50)')
iGI = input.float(2.0, 'Grid Interval(2%)', step=.25) / 100
iGrids = input.int(6, 'Number of Grids', options=[2, 4, 6, 8])
iCool = input.int(2, 'Cooldown(2)', minval=0)
iDir = input.string('neutral', 'Direction', options=['neutral', 'up', 'down'])
iGT = input.int(70, 'Grid Line Transparency(100 to hide)', minval=0, maxval=100)
iFT = input.int(90, 'Fill Transparency(100 to hide)', minval=0, maxval=100)
iSS = input.string('small', 'Signal Size', options=['small', 'large'])
iReset = input(true, 'Reset Buy/Sell Index When Grids Change')
iEXTR = input(true, 'Use Highs/Lows for Signals')
iMT = input(true, 'Show Min Tick')
iRFC = input(false, 'Reverse Fill Colors')
qty_ent = iGrids/2
qty_pos = strategy.initial_capital / qty_ent / 2 / open
//----<Colors>-----------------------------------------------------------------------------------//
RedGrid = color.new(color.red, iGT)
GreenGrid = color.new(color.green, iGT)
Crimson = #DC143C
LimeGreen = #32CD32
//----<Variables>--------------------------------------------------------------------------------//
NextUP = 0.0
NextDN = 0.0
LastSignal = 0
LastSignal_Index = 0
AP = 0.0
G = iGrids
Buy = false
Sell = false
UpperLimit = 0.0
LowerLimit = 0.0
SignalLine = 0.0
CurrentGrid = 0.0
BuyLine = 0.0
SellLine = 0.0
DIR = 0
MeaningOfLife = 42
//----<Calculations>-----------------------------------------------------------------------------//
//Lazy Formula
lz(x, lzf) =>
LZ = 0.0
s = math.sign(x)
LZ := x == nz(x[1], x) ? x : x > nz(LZ[1] + lzf * LZ[1] * s, x) ? x : x < nz(LZ[1] - lzf * LZ[1] * s, x) ? x : LZ[1]
LZ
//Smoothing
LR = ta.linreg(close, iLen, 0)
SMA = ta.sma(close, iLen)
EMA = ta.ema(close, iLen)
VWMA = ta.vwma(close, iLen)
TEMA = ta.ema(ta.ema(ta.ema(close, iLen), iLen), iLen)
MA = iMA == 'lreg' ? LR : iMA == 'sma' ? SMA : iMA == 'ema' ? EMA : iMA == 'vwma' ? VWMA : TEMA
//Make Lazy
LMA = lz(MA, iLZ)
//Calculate Elasticity
ELSTX = syminfo.mintick * iELSTX
//Show Mintick
if iMT and barstate.islast
table.cell(table.new(position.top_right, 1, 1), 0, 0, str.tostring(syminfo.mintick))
//Anchor Point
AP := MA > LMA ? AP[1] + ELSTX : MA < LMA ? AP[1] - ELSTX : AP[1]
AP := AP >= NextUP[1] ? NextUP[1] : AP
AP := AP <= NextDN[1] ? NextDN[1] : AP
//Reset if Next Level Reached or AP is crossed
AP := LMA != LMA[1] ? LMA : AP
//Next Gridlines
NextUP := LMA != LMA[1] ? LMA + LMA * iGI : NextUP[1]
NextDN := LMA != LMA[1] ? LMA - LMA * iGI : NextDN[1]
//Grid Interval
GI = AP * iGI
//----<Grid Array>-------------------------------------------------------------------------------//
a_grid = array.new_float(9)
for x = -4 to 4 by 1
array.set(a_grid, x + 4, AP + GI * x)
Get_Array_Values(ArrayName, index) =>
value = array.get(ArrayName, index)
value
//----<Set Static Grids>-------------------------------------------------------------------------//
G0 = Get_Array_Values(a_grid, 0) //Upper4
G1 = Get_Array_Values(a_grid, 1) //Upper3
G2 = Get_Array_Values(a_grid, 2) //Upper2
G3 = Get_Array_Values(a_grid, 3) //Upper1
G4 = Get_Array_Values(a_grid, 4) //Center
G5 = Get_Array_Values(a_grid, 5) //Lower1
G6 = Get_Array_Values(a_grid, 6) //Lower2
G7 = Get_Array_Values(a_grid, 7) //Lower3
G8 = Get_Array_Values(a_grid, 8) //Lower4
//----<Set Upper and Lower Limits>---------------------------------------------------------------//
UpperLimit := G >= 8 ? G8 : G >= 6 ? G7 : G >= 4 ? G6 : G5
LowerLimit := G >= 8 ? G0 : G >= 6 ? G1 : G >= 4 ? G2 : G3
//----<Calculate Signals>------------------------------------------------------------------------//
Get_Signal_Index() =>
Value = 0.0
Buy_Index = 0
Sell_Index = 0
start = 4 - G / 2
end = 4 + G / 2
for x = start to end by 1
Value := Get_Array_Values(a_grid, x)
if iEXTR
Sell_Index := low[1] < Value and high >= Value ? x : Sell_Index
Buy_Index := high[1] > Value and low <= Value ? x : Buy_Index
Buy_Index
else
Sell_Index := close[1] < Value and close >= Value ? x : Sell_Index
Buy_Index := close[1] > Value and close <= Value ? x : Buy_Index
Buy_Index
[Buy_Index, Sell_Index]
[BuyLine_Index, SellLine_Index] = Get_Signal_Index()
//----<Signals>----------------------------------------------------------------------------------//
Buy := BuyLine_Index > 0 ? true : Buy
Sell := SellLine_Index > 0 ? true : Sell
//No repeat trades at current level
Buy := low >= SignalLine[1] - GI ? false : Buy
Sell := high <= SignalLine[1] + GI ? false : Sell
//No trades outside of grid limits
Buy := close > UpperLimit ? false : Buy
Buy := close < LowerLimit ? false : Buy
Sell := close < LowerLimit ? false : Sell
Sell := close > UpperLimit ? false : Sell
//Direction Filter (skip one signal if against market direction)
DIR := iDir == 'up' ? 1 : iDir == 'down' ? -1 : 0
Buy := DIR == -1 and low >= SignalLine[1] - GI * 2 ? false : Buy
Sell := DIR == 1 and high <= SignalLine[1] + GI * 2 ? false : Sell
//Conflicting Signals
if Buy and Sell
Buy := false
Sell := false
LastSignal_Index := LastSignal_Index[1]
LastSignal_Index
//----<Cooldown>---------------------------------------------------------------------------------//
y = 0
for i = 1 to iCool by 1
if Buy[i] or Sell[i]
y := 0
break
y += 1
y
CoolDown = y
Buy := CoolDown < iCool ? false : Buy
Sell := CoolDown < iCool ? false : Sell
//----<Trackers>---------------------------------------------------------------------------------//
LastSignal := Buy ? 1 : Sell ? -1 : LastSignal[1]
LastSignal_Index := Buy ? BuyLine_Index : Sell ? SellLine_Index : LastSignal_Index[1]
SignalLine := Get_Array_Values(a_grid, LastSignal_Index)
//Reset to Center Grid when LMA changes
if iReset
SignalLine := LMA < LMA[1] ? UpperLimit : SignalLine
SignalLine := LMA > LMA[1] ? LowerLimit : SignalLine
SignalLine
BuyLine := Get_Array_Values(a_grid, BuyLine_Index)
SellLine := Get_Array_Values(a_grid, SellLine_Index)
//----<Plot Grids>--------------------------//
color apColor = na
apColor := MA < AP ? color.new(color.red, iGT) : MA > AP ? color.new(color.green, iGT) : apColor[1]
apColor := LMA != LMA[1] ? na : apColor
plot(G >= 8 ? G0 : na, color=GreenGrid)
plot(G >= 6 ? G1 : na, color=GreenGrid)
plot(G >= 4 ? G2 : na, color=GreenGrid)
plot(G >= 2 ? G3 : na, color=GreenGrid)
plot(G4, color=apColor, linewidth=4) // Center
plot(G >= 2 ? G5 : na, color=RedGrid)
plot(G >= 4 ? G6 : na, color=RedGrid)
plot(G >= 6 ? G7 : na, color=RedGrid)
plot(G >= 8 ? G8 : na, color=RedGrid)
//fill
LineAbove = SignalLine == UpperLimit ? SignalLine : SignalLine + GI
LineBelow = SignalLine == LowerLimit ? SignalLine : SignalLine - GI
a = plot(LineAbove, color=color.new(color.red, 100), style=plot.style_circles)
b = plot(LineBelow, color=color.new(color.green, 100), style=plot.style_circles)
boxColor = LastSignal == 1 ? color.new(color.green, iFT) : color.new(color.red, iFT)
if iRFC
boxColor := LastSignal == -1 ? color.new(color.green, iFT) : color.new(color.red, iFT)
boxColor
fill(a, b, color=boxColor)
//----<Plot Signals>-----------------------------------------------------------------------------//
plotchar(Buy and iSS == 'small', 'Buy', color=color.new(LimeGreen, 0), size=size.tiny, location=location.belowbar, char='▲')
plotchar(Sell and iSS == 'small', 'Sell', color=color.new(Crimson, 0), size=size.tiny, location=location.abovebar, char='▼')
plotchar(Buy and iSS == 'large', 'Buy', color=color.new(LimeGreen, 0), size=size.small, location=location.belowbar, char='▲')
plotchar(Sell and iSS == 'large', 'Sell', color=color.new(Crimson, 0), size=size.small, location=location.abovebar, char='▼')
//----<Alerts>-----------------------------------------------------------------------------------//
alertcondition(condition=Buy, title='buy', message='buy')
alertcondition(condition=Sell, title='sell', message='sell')
//-----------------------------------------------------------------------------------------------//
if strategy.position_size >= 0 and Buy
strategy.entry("Long", strategy.long, qty = qty_pos)
if strategy.position_size <= 0 and Sell
strategy.entry("Short", strategy.short, qty = qty_pos)
if strategy.position_size > 0 and Sell
strategy.close("Long", qty = qty_pos)
if strategy.position_size < 0 and Buy
strategy.close("Short", qty = qty_pos)