EMA 회수 전략

저자:차오장, 날짜: 2023-12-21 11:48:54
태그:

img

전반적인 설명

EMA 회수 전략은 EMA 지표에 기반한 양적 거래 전략이다. 그것은 서로 다른 기간을 가진 세 개의 EMA 곡선을 사용하여 거래 신호를 구성하고 거래를 자동화하기 위해 가격 회수를 기반으로 Stop Loss 및 Take Profit를 설정합니다.

전략 원칙

이 전략은 세 개의 EMA 곡선을 사용합니다.

  • EMA1: 비교적 짧은 기간으로 가격 인하 지원/저항 수준을 판단하기 위해 33 기간까지 기본.
  • EMA2: 일부 반전 신호를 필터링하기 위해, EMA1의 5배의 기간으로, 165 기간으로 기본 설정됩니다.
  • EMA3: 전체 트렌드 방향을 결정하기 위해, EMA1의 11배의 기간으로, 365 기간까지 기본 설정됩니다.

거래 신호는 다음과 같은 논리에 따라 생성됩니다.

긴 신호: 가격이 EMA1을 넘어서고, EMA1을 넘어서고, EMA1을 넘어서고, EMA1을 넘어서면 긴 신호를 입력합니다.

쇼트 신호: 가격이 EMA1 아래로 넘어가고, EMA1 아래로 다시 올라가고, EMA2에 도달하지 않고 다시 올라간다. 가격이 EMA1 아래로 넘어갈 때 쇼트 신호를 입력한다.

스톱 로스는 가장 낮은/최고의 풀백 가격으로 설정됩니다. 영업은 스톱 로스의 2배로 설정됩니다.

전략적 장점

이 전략은 다음과 같은 장점을 가지고 있습니다.

  1. 신뢰할 수 있는 EMA 지표를 사용하여 만들어진 거래 신호.
  2. 가격 인하가 함락되는 것을 효과적으로 방지합니다.
  3. 기존의 높은/저한 제어에서 손실을 중지하여 효율적으로 위험.
  4. 이윤을 취하는 것은 위험과 보상 비율을 만족시키는 것입니다.
  5. EMA 매개 변수는 다른 사이클에 따라 조절할 수 있습니다.

전략 위험

이 전략은 또한 몇 가지 위험을 안고 있습니다.

  1. EMA는 지연 효과를 가지고 있으며, 트렌드 반전 지점을 놓칠 수 있습니다.
  2. EMA2를 초과하는 너무 큰 Pullback 범위는 잘못된 신호를 생성할 수 있습니다.
  3. 트렌딩 시장에서는 스톱 로스가 깨질 수 있습니다.
  4. 부적절한 매개 변수 설정은 과도한 거래 또는 놓친 기회로 이어집니다.

위험은 EMA 기간, 인회 제한 등을 조정함으로써 완화 될 수 있습니다. 다른 지표도 필터 신호에 추가 될 수 있습니다.

최적화 방향

이 전략은 다음 측면에서도 최적화 될 수 있습니다.

  1. 트렌드 상거래를 피하기 위해 트렌드 지표를 추가합니다. 예를 들어 MACD.
  2. 가짜 브레이크오웃을 피하기 위해 거래량 지표를 추가합니다. 예를 들어 OBV
  3. EMA 기간을 최적화하거나 적응 EMA를 사용하십시오.
  4. 단어의 가방과 같은 기계 학습 모델을 사용하여 매개 변수를 동적으로 최적화합니다.
  5. 적응식 스톱 로스 및 수익을 취하기 위한 모델 예측을 추가합니다.

결론

EMA 풀백 전략은 세 개의 EMA를 사용하여 거래 시스템을 구축하고 거래를 자동화하기 위해 가격 풀백을 기반으로 스톱 로스를 설정하고 이익을 취합니다. 거래 위험을 효과적으로 제어하고 시장 조건에 따라 매개 변수를 조정하여 최적화 할 수 있습니다. 전반적으로 전략은 건전한 논리를 가지고 있으며 실제 거래에서 적용 할 수 있습니다. 추세 결정, 매개 변수 최적화 및 위험 관리와 같은 측면에서 향후 개선이 가능합니다.


/*backtest
start: 2023-11-20 00:00:00
end: 2023-12-20 00:00:00
period: 1h
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/
// created by Space Jellyfish
//@version=4

strategy("EMA pullback strategy", overlay = true, initial_capital=10000, commission_value = 0.075)

target_stop_ratio = input(title="Take Profit Stop Loss ratio", type=input.float, defval=2.06, minval=0.5, maxval=100)
riskLimit_low =  input(title="lowest risk per trade", type=input.float, defval=0.008, minval=0, maxval=100)
riskLimit_high =  input(title="highest risk per trade", type=input.float, defval=0.02, minval=0, maxval=100)
//give up the trade, if the risk is smaller than limit, adjust position size if risk is bigger than limit

ema_pullbackLevel_period = input(title="EMA1 for pullback level Period", type=input.integer, defval=33, minval=1, maxval=10000)
ema_pullbackLimiit_period = input(title="EMA2 for pullback limit Period", type=input.integer, defval=165, minval=1, maxval=10000)
ema_trend_period = input(title="EMA3 for trend Period", type=input.integer, defval=365, minval=1, maxval=10000)

startDate = input(title="Start Date", type=input.integer, defval=1, minval=1, maxval=31)
startMonth = input(title="Start Month", type=input.integer, defval=1, minval=1, maxval=12)
startYear = input(title="Start Year", type=input.integer, defval=2018, minval=2008, maxval=2200)

inDateRange = (time >= timestamp(syminfo.timezone, startYear, startMonth, startDate, 0, 0))

ema_pullbackLevel = ema(close, ema_pullbackLevel_period)
ema_pullbackLimit = ema(close, ema_pullbackLimiit_period)
ema_trendDirection = ema(close, ema_trend_period)

//ema pullback 
float pricePullAboveEMA_maxClose = na
float pricePullAboveEMA_maxHigh = na

float pricePullBelowEMA_minClose = na
float pricePullBelowMA_minLow = na

if(crossover(close, ema_pullbackLevel))
    pricePullAboveEMA_maxClose := close
    pricePullAboveEMA_maxHigh := high
else
    pricePullAboveEMA_maxClose := pricePullAboveEMA_maxClose[1]
    pricePullAboveEMA_maxHigh := pricePullAboveEMA_maxHigh[1]

if(close > pricePullAboveEMA_maxClose)
    pricePullAboveEMA_maxClose := close
if(high > pricePullAboveEMA_maxHigh)
    pricePullAboveEMA_maxHigh := high

if(crossunder(close, ema_pullbackLevel))
    pricePullBelowEMA_minClose := close
    pricePullBelowMA_minLow := low
else
    pricePullBelowEMA_minClose :=pricePullBelowEMA_minClose[1]
    pricePullBelowMA_minLow:=pricePullBelowMA_minLow[1]
    
if(close < pricePullBelowEMA_minClose)
    pricePullBelowEMA_minClose := close
if(low < pricePullBelowMA_minLow)
    pricePullBelowMA_minLow := low


long_strategy = crossover(close, ema_pullbackLevel) and pricePullBelowEMA_minClose < ema_pullbackLimit and ema_pullbackLevel>ema_trendDirection 
short_strategy = crossunder(close, ema_pullbackLevel) and pricePullAboveEMA_maxClose > ema_pullbackLimit and ema_pullbackLevel<ema_trendDirection


var open_long_or_short = 0// long = 10000, short = -10000, no open = 0

//check if position is closed
if(strategy.position_size == 0)
    open_long_or_short := 0
else
    open_long_or_short := open_long_or_short[1]

float risk_long = na
float risk_short = na
float stopLoss = na
float takeProfit = na
float entry_price = na

float entryContracts = 0



risk_long := risk_long[1]
risk_short := risk_short[1]
    
//open a position determine the position size
if (strategy.position_size == 0 and long_strategy and inDateRange)
    risk_long := (close - pricePullBelowMA_minLow) / close

    if(risk_long < riskLimit_high)
        entryContracts := strategy.equity / close
    else
        entryContracts := (strategy.equity * riskLimit_high / risk_long)/close
    
    if(risk_long > riskLimit_low)
        strategy.entry("long", strategy.long, qty = entryContracts, when = long_strategy)


    open_long_or_short := 10000
    
if (strategy.position_size == 0 and short_strategy and inDateRange)
    risk_short := (pricePullAboveEMA_maxHigh - close) / close
    if(risk_short < riskLimit_high)
        entryContracts := strategy.equity / close
    else
        entryContracts := (strategy.equity * riskLimit_high / risk_short)/close

    if(risk_short > riskLimit_low)
        strategy.entry("short", strategy.short, qty = entryContracts, when = short_strategy)

    
    open_long_or_short := -10000

//take profit / stop loss
if(open_long_or_short == 10000)

    stopLoss :=   strategy.position_avg_price*(1 - risk_long)
    takeProfit :=  strategy.position_avg_price*(1 + target_stop_ratio * risk_long)
    entry_price := strategy.position_avg_price
    strategy.exit("Long exit","long", limit = takeProfit , stop = stopLoss)
    
if(open_long_or_short == -10000)
    stopLoss :=  strategy.position_avg_price*(1 + risk_short)
    takeProfit :=  strategy.position_avg_price*(1 - target_stop_ratio * risk_short)
    entry_price := strategy.position_avg_price
    strategy.exit("Short exit","short", limit = takeProfit, stop = stopLoss)



plot(ema_pullbackLevel, color=color.aqua,  title="ema pullback level")
plot(ema_pullbackLimit, color=color.purple,  title="ema pullback limit")
plot(ema_trendDirection, color=color.white,  title="ema trend")

plot(entry_price, color = color.yellow, linewidth = 1, style = plot.style_linebr)
plot(stopLoss, color = color.red, linewidth = 1, style = plot.style_linebr)
plot(takeProfit, color = color.green, linewidth = 1, style = plot.style_linebr)





//

더 많은