
EMA 평균값 회귀 거래 전략 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)