
この戦略は,MACD指標の金叉死叉信号,K線閉盘価格と中位線の関係,価格の揺動特性を活用して,入場と退出のタイミングを判断し,再入場と修正入場機構を設定し,より多くの取引機会を得るために,同時にリスクを制御し,安定した利益を達成する.
この戦略は以下の原則に基づいています.
MACDの分析による快線と慢線の金叉死叉は,多頭と空頭市場,および特定のエントリーポイントを判断する.
K線の閉盤価格と中位線の関係で,多空トレンドが終了したかどうかを判断し,出口を判断する.
再入場メカニズムを設定し,MACDの本回転の終了後に,トレンドに沿って再入場し,収益の機会を増加させる.
修正入場メカニズムを設定し,価格が部分的に調整されてもまだ逆転していない場合は,ポジションを追加します.これはトレンド内の調整です.
上記のポイントをまとめ,動的にポジションを調整し,トレンドの中でできるだけ多くの利益を得,トレンドが終わるとすぐに退場する.
具体的には,戦略はまず,MACDの快線と慢線が金叉または死叉の発生かどうかを判断し,金叉は多し,死叉は空し;それから,K線が閉盘で中位線に触れたかどうかを判断し,触れた場合はトレンドの終わりとして平仓を判断する.
さらに,戦略はまた,再入場機構を設定します.すなわち,元の方向のトレンドが終了した後,MACDが同じ方向の信号を示し続けると,戦略は再びトレンドを追跡するポジションを開きます.また,修正入場機構を設定します.価格がわずかな調整が起こると,全面的に逆転していない場合は,戦略は適切なポジションを上げます.これはトレンドの正常な逆調行為です.
これらの設定により,戦略はトレンドの中で動的にポジションを調整し,より多くの出入りをし,リスクを制御した前提でより高い収益を得ることができます.
この戦略は複数の指標を組み合わせて行われ,主な利点は以下の通りです.
MACDはトレンドと逆転点を識別し,特定の入場点を決定します.
閉盤価格と中位線の関係判断は,トレンドの終わりを正確に判断する.
また,再エントリーメカニズムにより,ポジションの開設回数が増え,資金の利用効率が向上しました.
修正された入場メカニズムは,トレンドを十分に捉えるため,準備を間に合わせた.
戦略操作の頻度は高いが,リスクは制御可能で,より高い収益因子を得ることが容易である.
各パラメータは調整可能で,異なる品種と状況に最適化できます.
戦略は明快で理解しやすい,コードは簡潔で,CD操作は簡単.
観測データは充実し,信頼性が高く,実態は容易に検証できる.
この戦略には以下の主要なリスクがあります.
MACDが偽信号を発する確率は,他の指標と組み合わせて検証する必要があります.
大規模なストップダメージ設定が小さすぎると,大規模な動きが外される可能性があります.
再入場と修正入場は,運用頻度を増やし,資金活用率を制御する必要があります.
市場が反発する中で,修正された入場は大きな損失をもたらす可能性がある.
取引品種とパラメータの設定は最適化が必要で,すべての品種には適用されません.
継続的な反省と最適化が必要で,市場によるパラメータの調整が必要である.
滑点コストの影響は,実盤で考慮する必要があります.
対応するリスク管理策には,単一損失を制限するストップ・ローズを設定し,資金活用率を評価し,合理的な現金準備を維持し,品種に適したパラメータの組み合わせを選択して反測を行うこと,パラメータを最適化するために状況特性の変化に継続的に注目し,反測とシミュレーションで滑り込みコストの影響を考慮するなどが含まれます.
この戦略は,以下の点でさらに最適化できます.
他の指標と組み合わせて信号検証を行い,信号の正確性を向上させる。例えばKDJ指標など。
自動自律式止損基準を設定する.
再入学と修正入学条件の論理を最適化する.
分種パラメータ最適化,最適なパラメータ組み合わせを設定する.
資金活用率の最適化,再入学と修正入学の資金制限の設定
結合量能指数で,反発的な状況で追放損失を回避する.
モバイル・ストップなどのオフメカニズムを追加する.
戦略包装を取引ロボットに変換し,取引を自動化することを検討する.
スライドポイントのコストなど,リールディスクの考慮要素を追加する.
これらの最適化により,戦略の安定性,適応性,自動化程度,および実用性をさらに向上させることができます.
この戦略は,MACD指標の取引信号,K線閉盘価格分析と複数の入場メカニズムを使用し,トレンドを把握しながらリスクを制御する,高効率の量化取引戦略のアイデアです. この戦略は,動作頻度が高い,資金活用率が高い,達成難度が低いなどの利点があります. しかし,リスク管理と戦略最適化にも注意する必要があります. 強力な実用価値と拡張スペースがあります. ロボット技術と組み合わせて自動化を実現すれば,非常に実用的量化取引方案になることができます.
/*backtest
start: 2023-09-29 00:00:00
end: 2023-10-29 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Puckapao
//@version=4
// strategy(title="MACD", shorttitle="MACD", overlay=true, initial_capital=10000.00, currency="USD", default_qty_type=strategy.cash, default_qty_value=10000.00)
// Getting inputs
reenter_delay = input(title="Re-enter Delay", type=input.integer, defval=2)
sculp_delay = input(title="Sculp Delay", type=input.integer, defval=4)
fast_length = input(title="Fast Length", type=input.integer, defval=12)
slow_length = input(title="Slow Length", type=input.integer, defval=26)
src = input(title="Source", type=input.source, defval=close)
signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9)
sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false)
sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=true)
ema_period = input(title="EMA Period", type=input.integer, defval=21)
// Get date
startDate = input(title="Start Date", type=input.integer,
defval=19, minval=1, maxval=31)
startMonth = input(title="Start Month", type=input.integer,
defval=09, minval=1, maxval=12)
startYear = input(title="Start Year", type=input.integer,
defval=2017, minval=1800, maxval=2100)
endDate = input(title="End Date", type=input.integer,
defval=31, minval=1, maxval=31)
endMonth = input(title="End Month", type=input.integer,
defval=3, minval=1, maxval=12)
endYear = input(title="End Year", type=input.integer,
defval=2021, minval=1800, maxval=2100)
// STEP 2:
// Look if the close time of the current bar
// falls inside the date range
inDateRange = true
reenter_cnt = 0
reenter_cnt := nz(reenter_cnt[1])
sculp_cnt = 0
sculp_cnt := nz(sculp_cnt[1])
close_cnt = 0
close_cnt := nz(close_cnt[1])
on_long = false
on_long := nz(on_long[1])
on_short = false
on_short := nz(on_short[1])
sculp = false
reenter = false
slowdown = false
ema = ema(close, ema_period)
// Plot colors
col_grow_above = #26A69A
col_grow_below = #FFCDD2
col_fall_above = #B2DFDB
col_fall_below = #EF5350
col_macd = #0094ff
col_signal = #ff6a00
// Calculating
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length)
hist = macd - signal
// plot(hist, title="Histogram", style=plot.style_columns, color=(hist>=0 ? (hist[1] < hist ? col_grow_above : col_fall_above) : (hist[1] < hist ? col_grow_below : col_fall_below) ), transp=0 )
// plot(macd, title="MACD", color=col_macd, transp=0)
// plot(signal, title="Signal", color=col_signal, transp=0)
cross_up = crossover(macd, signal)
cross_down = crossunder(macd, signal)
if (inDateRange)
over_macd = macd > 0 and signal > 0 ? true : false
under_macd = macd < 0 and signal < 0 ? true : false
over_water = close > ema ? true : false
under_water = close < ema ? true : false
slowdown := hist >= 0 ? (hist[1] > hist ? true : false) : (hist[1] > hist ? false : true)
reenter := hist >= 0 ? (hist[1] < hist ? true : false) : (hist[1] > hist ? true : false)
sculp := (hist >= 0 ? (hist[1] > hist ? true : false) : (hist[1] < hist ? true : false))
if(reenter == true)
if(reenter_cnt < reenter_delay)
reenter_cnt := reenter_cnt + 1
else
if(reenter_cnt > 0)
reenter_cnt := reenter_cnt - 1
if(sculp == true)
if(sculp_cnt < sculp_delay)
sculp_cnt := sculp_cnt + 1
else
if(sculp_cnt > 0)
sculp_cnt := sculp_cnt - 1
if(slowdown == false)
if(close_cnt < 2)
close_cnt := close_cnt + 1
else
close_cnt := 0
// plotchar(fork_cnt, "fork count", "")
// plotchar(spoon_cnt, "spoon count", "")
// Entry
if (cross_up == true)
strategy.entry("long", strategy.long, comment = "long", alert_message = "long")
on_long := true
on_short := false
if (cross_down == true)
strategy.entry("short", strategy.short, comment = "short", alert_message = "short")
on_short := true
on_long := false
// Sculp bottom / top
if (sculp == true and sculp_cnt >= sculp_delay)
if (hist >= 0)
strategy.entry("sculp-short", strategy.short, comment = "sculp-short", alert_message = "sculp-short")
else
strategy.entry("sculp-long", strategy.long, comment = "sculp-long", alert_message = "sculp-long")
sculp_cnt := 0
sculp := false
// Re-Entry
if (reenter == true and reenter_cnt >= reenter_delay)
if (hist >= 0)
strategy.entry("re-long", strategy.long, comment = "re-long", alert_message = "re-long")
else
strategy.entry("re-short", strategy.short, comment = "re-short", alert_message = "re-short")
reenter_cnt := 0
reenter := false
// Close
strategy.close("long", when = slowdown, comment = "close long", alert_message = "close long")
strategy.close("short", when = slowdown, comment = "close short", alert_message = "close short")
strategy.close("re-long", when = slowdown, comment = "close re-long", alert_message = "close re-long")
strategy.close("re-short", when = slowdown, comment = "close re-short", alert_message = "close re-short")
strategy.close("sculp-long", when = slowdown, comment = "close sculp-long", alert_message = "close sculp-long")
strategy.close("sculp-short", when = slowdown, comment = "close sculp-short", alert_message = "close sculp-short")
if (slowdown)
if (hist >= 0)
on_long := false
else
on_short := false
plotchar(slowdown, "close", "")
plotchar(reenter, "reenter", "")
plotchar(reenter_cnt, "reenter count", "")
plotchar(sculp, "sculp", "")
plotchar(sculp_cnt, "sculp count", "")