
EMA平均値回帰取引戦略は,価格が平均線から離れる程度に基づいて,ポジション開設とポジション操作を行う取引戦略である. EMA平均線距離の現在の価格のパーセント差を開設シグナルとして使用し,ストップロスを追跡してポジションを管理する.
この戦略はEMAを平均線指標として使用し,現在の価格からEMAのパーセント差を計算する.価格がEMAから十分に離れるとき (デフォルトは9%) ポジションを多く開く.価格がEMAに十分に近づくと (デフォルトは1%),平仓する.ポジションを開いた後,利益をロックするために運用ストップロスを使用し,利益が増加するにつれて徐々にストップロスを上昇させる.
具体的には,戦略は以下の構成要素で構成されています.
EMA平均線を計算する.周期を設定する (デフォルト200),データソース (閉盘価格),計算方法 (EMA,SMA,RMA,WMA) を設定する.
現在の価格とEMAのパーセント差を計算する.正負の処理に注意する.
差の比率による開設. 余開設の値は9% (配置可能),空設の値は9% (配置可能) である.
梯形開倉をサポートします.梯形に配置できる階段の数と各階段度.
ポジション開設後のストップ・トラッキング.設定可能なストップ・トラッキングの値 ((デフォルトの利益1%) とトラッキング幅 ((デフォルトの1%)).
差の比率による平仓。多仓平仓の値が1% ((配置可能),空仓同理。
未完成の注文を撤回する.価格がEMAに近づくと,未完成の注文を撤回する.
設定可能な止損率
リアルタイム取引と反省のサポート
この戦略の利点は以下の通りです.
平均線回帰の概念を利用して,価格が平均線から離れる時にポジションを開き,戻る時に平仓,トレンド取引理論に合致する.
ポジション開設,停止,平置のパラメータは細かく構成され,異なる市場環境に適応できます.
梯形式開倉は,積み重なった積み重なった積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる積み重なる.
運用ストップは収益を固定し,リスクを管理する.
最適化スペースは広大で,平均線パラメータまたは開設平仓差を調整して異なる状況に適応することができる.
主流プログラミング言語のPine Scriptをサポートし,TradingViewに直接使用できます.
視覚的なグラフで,観察や分析が容易になります.
この戦略には以下のリスクもあります.
回測データ適合リスク。パラメータ最適化は回測データに過度に適合し,実機効果は疑わしい。
平均線が失効するリスク. 価格が長期にわたって平均線から大きく離れ,戻れない可能性がある.
ストップダメージはリスクに追い込まれます. 状況が激しく,ストップダメージは突破される可能性があります.
取引は頻繁で,取引費用は重い.
長い観察周期が必要で,突発的な事件の影響は大きい.
リスク管理:
複数のパラメータを調整し,安定したパラメータを確保する.複数の市場検証の有効性.
合理的に配置された均線周期は,短すぎたり長すぎたりしてはならない.
ストップダスの幅を適正に緩め, を防止する.
取引の頻度を下げるため,適切な取引条件の緩和.
緊急事態への適応力を向上させるための指標を追加する.
この戦略は以下の点で最適化できます.
取引量,ブリン帯,RSIなどのフィルタリング条件を追加し,偽信号を減らす.
複合平均線を足し,双EMAシステムのように,順位取引の確率を高めること.
自動停止,Chandelier Exitなどの最適化ストップ戦略により,リスクをさらに制限する.
自動パラメータ最適化機能が追加され,より優良なパラメータの組み合わせを自動的に探す.
価格が平均線から離れる確率を判断する機械学習の予測を増加させる.
時間帯間の取引を考慮し,夜盤または前盤の情報を利用して事前に配置する.
株式プールの統合,自動選択,取引,戦略容量の拡大
EMAレバレッジ策略は,価格平均線回帰特性を基礎にしたトレンド追跡策略である. 均線の統計特性を合理的に利用してトレンド転換を判断し,ストップ・ローズでリスクを制御する. 従来の均線取引策略と比較して,ストップ・ローズを動的に追跡するよりも,ストップ・ローズを固定的に開設するよりも焦点を当てている. この策略は,トレンド追跡策略のポートフォリオを豊かにすることができるが,最適化問題を測定し,取引頻度を制御する必要があります.
/*backtest
start: 2022-10-19 00:00:00
end: 2023-10-25 00:00:00
period: 1d
basePeriod: 1h
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/
// © jordanfray
//@version=5
strategy(title="EMA Mean Reversion Strategy", overlay=true, max_bars_back=5000, default_qty_type=strategy.percent_of_equity, default_qty_value=100,initial_capital=100000, commission_type=strategy.commission.percent, commission_value=0.05, backtest_fill_limits_assumption=2)
// Indenting Classs
indent_1 = " "
indent_2 = " "
indent_3 = " "
indent_4 = " "
// Tooltips
longEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, a long postion will open."
shortEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, a short postion will open."
closeEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, open postion will close."
ladderInToolTip = "Enable this to use the laddering settings below."
cancelEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, any unfilled entries will be canceled."
// Group Titles
group_one_title = "EMA Settings"
group_two_title = "Entry Settings"
// Colors
blue = color.new(#00A5FF,0)
lightBlue = color.new(#00A5FF,90)
green = color.new(#2DBD85,0)
gray_80 = color.new(#7F7F7F,80)
gray_60 = color.new(#7F7F7F,60)
gray_40 = color.new(#7F7F7F,40)
white = color.new(#ffffff,0)
red = color.new(#E02A4A,0)
transparent = color.new(#000000,100)
// Strategy Settings
EMAtimeframe = input.timeframe(defval="", title="Timeframe", group=group_one_title)
EMAlength = input.int(defval=200, minval=1, title="Length", group=group_one_title)
EMAtype = input.string(defval="EMA", options = ["EMA", "SMA", "RMA", "WMA"], title="Type", group=group_one_title)
EMAsource = input.source(defval=close, title="Source", group=group_one_title)
openLongEntryAbove = input.float(defval=9, title="Long Position Entry Trigger", tooltip=longEntryToolTip, group=group_two_title)
openEntryEntryAbove = input.float(defval=9, title="Short Position Entry Trigger", tooltip=shortEntryToolTip, group=group_two_title)
closeEntryBelow = input.float(defval=1.0, title="Close Position Trigger", tooltip=closeEntryToolTip, group=group_two_title)
cancelEntryBelow = input.float(defval=4, title="Cancel Unfilled Entries Trigger", tooltip=cancelEntryToolTip, group=group_two_title)
enableLaddering = input.bool(defval=true, title="Ladder Into Positions", tooltip=ladderInToolTip, group=group_two_title)
ladderRungs = input.int(defval=4, minval=2, maxval=4, step=1, title=indent_4+"Ladder Rungs", group=group_two_title)
ladderStep = input.float(defval=.5, title=indent_4+"Ladder Step (%)", step=.1, group=group_two_title)/100
stop_loss_val = input.float(defval=4.0, title="Stop Loss (%)", step=0.1, group=group_two_title)/100
start_trailing_after = input.float(defval=1, title="Start Trailing After (%)", step=0.1, group=group_two_title)/100
trail_behind = input.float(defval=1, title="Trail Behind (%)", step=0.1, group=group_two_title)/100
// Calculate trailing stop values
long_start_trailing_val = strategy.position_avg_price + (strategy.position_avg_price * start_trailing_after)
long_trail_behind_val = close - (strategy.position_avg_price * trail_behind)
long_stop_loss = strategy.position_avg_price * (1.0 - stop_loss_val)
short_start_trailing_val = strategy.position_avg_price - (strategy.position_avg_price * start_trailing_after)
short_trail_behind_val = close + (strategy.position_avg_price * trail_behind)
short_stop_loss = strategy.position_avg_price * (1 + stop_loss_val)
// Calulate EMA
EMA = switch EMAtype
"EMA" => ta.ema(EMAsource, EMAlength)
"SMA" => ta.sma(EMAsource, EMAlength)
"RMA" => ta.rma(EMAsource, EMAlength)
"WMA" => ta.wma(EMAsource, EMAlength)
=> na
EMA_ = EMAtimeframe == timeframe.period ? EMA : request.security(syminfo.ticker, EMAtimeframe, EMA[1], lookahead = barmerge.lookahead_on)
plot(EMA_, title="EMA", linewidth=2, color=blue, editable=true)
EMA_cloud_upper_band_val = EMA_ + (EMA_ * openLongEntryAbove/100)
EMA_cloud_lower_band_val = EMA_ - (EMA_ * openLongEntryAbove/100)
EMA_cloud_upper_band = plot(EMA_cloud_upper_band_val, title="EMA Cloud Upper Band", color=blue)
EMA_cloud_lower_band = plot(EMA_cloud_lower_band_val, title="EMA Cloud Upper Band", color=blue)
fill(EMA_cloud_upper_band, EMA_cloud_lower_band, editable=false, color=lightBlue)
distance_from_EMA = ((close - EMA_)/close)*100
if distance_from_EMA < 0
distance_from_EMA := distance_from_EMA * -1
// Calulate Ladder Entries
long_ladder_1_limit_price = close - (close * 1 * ladderStep)
long_ladder_2_limit_price = close - (close * 2 * ladderStep)
long_ladder_3_limit_price = close - (close * 3 * ladderStep)
long_ladder_4_limit_price = close - (close * 4 * ladderStep)
short_ladder_1_limit_price = close + (close * 1 * ladderStep)
short_ladder_2_limit_price = close + (close * 2 * ladderStep)
short_ladder_3_limit_price = close + (close * 3 * ladderStep)
short_ladder_4_limit_price = close + (close * 4 * ladderStep)
var position_qty = strategy.equity/close
if enableLaddering
position_qty := (strategy.equity/close) / ladderRungs
else
position_qty := strategy.equity/close
plot(position_qty, color=white)
//plot(strategy.equity, color=green)
// Entry Conditions
currently_in_a_postion = strategy.position_size != 0
currently_in_a_long_postion = strategy.position_size > 0
currently_in_a_short_postion = strategy.position_size < 0
average_price = strategy.position_avg_price
bars_since_entry = currently_in_a_postion ? bar_index - strategy.opentrades.entry_bar_index(strategy.opentrades - 1) + 1 : 5
long_run_up = ta.highest(high, bar_index == 0 ? 5000: bars_since_entry)
long_run_up_line = plot(long_run_up, style=plot.style_stepline, editable=false, color=currently_in_a_long_postion ? green : transparent)
start_trailing_long_entry = currently_in_a_long_postion and long_run_up > long_start_trailing_val
long_trailing_stop = start_trailing_long_entry ? long_run_up - (long_run_up * trail_behind) : long_stop_loss
long_trailing_stop_line = plot(long_trailing_stop, style=plot.style_stepline, editable=false, color=currently_in_a_long_postion ? long_trailing_stop > strategy.position_avg_price ? green : red : transparent)
short_run_up = ta.lowest(low, bar_index == 0 ? 5000: bars_since_entry)
short_run_up_line = plot(short_run_up, style=plot.style_stepline, editable=false, color=currently_in_a_short_postion ? green : transparent)
start_trailing_short_entry = currently_in_a_short_postion and short_run_up < short_start_trailing_val
short_trailing_stop = start_trailing_short_entry ? short_run_up + (short_run_up * trail_behind) : short_stop_loss
short_trailing_stop_line = plot(short_trailing_stop, style=plot.style_stepline, editable=false, color=currently_in_a_short_postion ? short_trailing_stop < strategy.position_avg_price ? green : red : transparent)
long_conditions_met = distance_from_EMA > openLongEntryAbove and close < EMA_ and not currently_in_a_postion
short_conditions_met = distance_from_EMA > openEntryEntryAbove and close > EMA_ and not currently_in_a_postion
close_long_entries = distance_from_EMA <= closeEntryBelow or close <= long_trailing_stop
close_short_entries = distance_from_EMA <= closeEntryBelow or close >= short_trailing_stop
cancel_entries = distance_from_EMA <= cancelEntryBelow
plotshape(long_conditions_met ? close : na, style=shape.diamond, title="Long Conditions Met" )
plotshape(short_conditions_met ? close : na, style=shape.diamond, title="Short Conditions Met" )
plot(average_price,style=plot.style_stepline, editable=false, color=currently_in_a_postion ? blue : transparent)
// Long Entry
if enableLaddering
if ladderRungs == 2
strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
else if ladderRungs == 3
strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 3", direction=strategy.long, qty=position_qty, limit=long_ladder_3_limit_price, when=long_conditions_met)
else if ladderRungs == 4
strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 3", direction=strategy.long, qty=position_qty, limit=long_ladder_3_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 4", direction=strategy.long, qty=position_qty, limit=long_ladder_4_limit_price, when=long_conditions_met)
strategy.exit(id="Close Long Ladder 1", from_entry="Long Ladder 1", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
strategy.exit(id="Close Long Ladder 2", from_entry="Long Ladder 2", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
strategy.exit(id="Close Long Ladder 3", from_entry="Long Ladder 3", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
strategy.exit(id="Close Long Ladder 4", from_entry="Long Ladder 4", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
strategy.cancel(id="Long Ladder 1", when=cancel_entries)
strategy.cancel(id="Long Ladder 2", when=cancel_entries)
strategy.cancel(id="Long Ladder 3", when=cancel_entries)
strategy.cancel(id="Long Ladder 4", when=cancel_entries)
else
strategy.entry(id="Long", direction=strategy.long, qty=100, when=long_conditions_met)
strategy.exit(id="Close Long", from_entry="Long", stop=long_stop_loss, limit=EMA_, when=close_long_entries)
strategy.cancel(id="Long", when=cancel_entries)
// Short Entry
if enableLaddering
if ladderRungs == 2
strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
else if ladderRungs == 3
strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 3", direction=strategy.short, qty=position_qty, limit=short_ladder_3_limit_price, when=short_conditions_met)
else if ladderRungs == 4
strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 3", direction=strategy.short, qty=position_qty, limit=short_ladder_3_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 4", direction=strategy.short, qty=position_qty, limit=short_ladder_4_limit_price, when=short_conditions_met)
strategy.exit(id="Close Short Ladder 1", from_entry="Short Ladder 1", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
strategy.exit(id="Close Short Ladder 2", from_entry="Short Ladder 2", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
strategy.exit(id="Close Short Ladder 3", from_entry="Short Ladder 3", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
strategy.exit(id="Close Short Ladder 4", from_entry="Short Ladder 4", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
strategy.cancel(id="Short Ladder 1", when=cancel_entries)
strategy.cancel(id="Short Ladder 2", when=cancel_entries)
strategy.cancel(id="Short Ladder 3", when=cancel_entries)
strategy.cancel(id="Short Ladder 4", when=cancel_entries)
else
strategy.entry(id="Short", direction=strategy.short, when=short_conditions_met)
strategy.exit(id="Close Short", from_entry="Short", limit=EMA_, when=close_short_entries)
strategy.cancel(id="Short", when=cancel_entries)