전략에 따른 다인자 이동 평균 트렌드

저자:차오장, 날짜: 2024-01-18 12:07:52
태그:

img

전반적인 설명

이것은 비트코인과 이더리움에 적합한 간단한 이동 평균 트렌드를 따르는 전략이다. 트렌드 방향을 파악하기 위해 이동 평균, MACD 및 RSI와 같은 여러 지표를 결합하고 장기 트렌드 추적을 위해 고정 위치 사이징을 채택한다.

전략 논리

이 전략의 핵심 논리는 20일 EMA가 100일 SMA를 넘고 100일 SMA가 200일 SMA를 넘을 때 긴 지점을 취하는 것이며, 20일 EMA가 100일 SMA를 넘을 때 포지션을 닫는 것이다. 즉, 트렌드 방향을 결정하기 위해 다른 기간의 3개의 이동 평균을 사용한다.

특히, 전략은 20일 EMA, 100일 SMA 및 200일 SMA의 값을 계산하고 트렌드를 판단하기 위해 그 크기의 관계를 비교합니다. 20일 EMA가 100일 SMA 이상으로 넘으면 가격이 상승하기 시작했다는 것을 의미합니다. 이 시점에서 100일 SMA도 200일 SMA보다 크다면 중장기 트렌드도 상승하고 있음을 나타냅니다. 이것은 강력한 긴 신호입니다.

장기 포지션에 진입 한 후 전략은 트렌드를 따라 포지션을 계속 유지합니다. 20 일 EMA가 100 일 SMA 아래로 다시 넘을 때 단기 트렌드 역전 신호가 발생했다는 것을 나타냅니다. 이 시점에서 전략은 손실을 막기 위해 포지션을 닫는 것을 선택합니다.

또한, 전략은 추세를 확인하기 위해 MACD 및 RSI와 같은 지표를 포함합니다. MACD의 DIF 라인, DEMA 라인 및 HIST 바 라인이 모두 상승하고 RSI 지표가 50 이상일 때만 긴 포지션을 열기를 선택합니다.

장점

이 전략의 가장 큰 장점은 중장기 트렌드를 효과적으로 추적 할 수있는 명확한 트렌드 거래 규칙을 수립한다는 것입니다. 구체적인 장점은 다음과 같습니다.

  1. 트렌드를 판단하기 위해 여러 이동 평균을 조합하여 비교적 신뢰할 수 있습니다.

  2. 단기 시장 변동에 방해받지 않고 트렌드 움직임을 추적하기 위해 장기 보유 지위를 채택하십시오.

  3. 전략 신호 확인을 위해 MACD와 RSI와 같은 지표를 결합하면 잘못된 브레이크를 필터 할 수 있습니다.

  4. EMA와 SMA 라인의 황금 십자가와 죽음의 십자가를 사용하여 입구와 출구 지점을 결정하면 규칙이 간단하고 명확합니다.

  5. 스톱 로스를 통해 손실을 제한함으로써 위험을 효과적으로 제어 할 수 있습니다.

위험 과 해결책

이 전략에는 또한 몇 가지 위험이 있습니다. 주요 문제는 트렌드가 역전될 때 손실을 시간 내에 막을 수 없다는 것입니다. 구체적인 위험과 해결책은 다음과 같습니다.

  1. 트렌드 반전 지점을 시간적으로 추적 할 수 없습니다. 이동 평균 주기를 단축하거나 포괄적 인 판단을 위해 더 많은 지표를 추가하십시오.

  2. 장기간 보유 시간이 더 큰 손실로 이어질 수 있습니다.

  3. 이동 평균 지표가 지연하는 경향이 있습니다: 활성 스톱 손실에 대해 일정 비율의 스톱 손실 라인을 추가합니다.

최적화 방향

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

  1. 최적의 매개 변수를 찾기 위해 이동 평균 주기의 더 많은 조합을 테스트합니다.

  2. 다른 지표 또는 모델을 사용하여 트렌드와 입시 시기를 판단하십시오. 볼링거 밴드, KD 지표 등.

  3. 기계 학습 및 다른 방법을 사용하여 매개 변수를 동적으로 최적화하십시오. 예를 들어, 강제 학습을 사용하여 중지 손실 진폭을 조정하십시오.

  4. 가짜 브레이크아웃을 피하기 위해 거래량 지표를 포함합니다. 예를 들어, 잔액 부피, 거래 부피 등.

  5. 자동 스톱 로스 및 스톱 로스 추적 시스템을 개발하여 시장 조건에 따라 스톱 로스 포지션을 조정할 수 있습니다.

결론

요약하자면, 이 전략은 단순하고 직설적인 트렌드 추후 전략이다. 트렌드 방향을 결정하기 위해 이동 평균, 신호를 필터하기 위해 MACD 및 RSI를 사용합니다. 트렌드 움직임을 추적하기 위해 비교적 긴 보유 기간을 채택하십시오. 중장기 트렌드 기회를 효과적으로 포착 할 수 있습니다. 동시에, 트렌드 역전을 식별하는 데 차질되는 위험이 있습니다. 파라미터 최적화, 지표 추가 등을 통해 미래 개선 및 업그레이드가 가능합니다.


/*backtest
start: 2024-01-16 00:00:00
end: 2024-01-17 00:00:00
period: 10m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="BTC_Long_Only_TV01_200507", overlay=true)

//////////// !!!!!!!!!!!!!!!! WORK BEST IN 2 HOURS for BTC, ETH and ETHXBT !!!!!!!!!!!!!!!!!!! /////////////////////
//280820 - After long esting this is the best script for ETHUSD in 4 hours. From 01/01/2020 til 28/08/2020


[macdLine, macdSignalLine, macdHist] = macd(close, 12, 26, 7)  

//_rsi_len = input(14, title="RSI length")
_rsi_len = 14 
  
NewValue = 0
PreviousValue = 0
leverage = 1

smaPercentageIncrease = 0.0
SMA_PERCENT_INCREASE = 0.0
float atrValue = 0
bool bPositionOpened = false
float stockPositionSize = 0 
float volatilityPercentage = 0.0
bool bDisplayArrow = false 
bool bEMAIsRising = false
bool bSMAIsRising = false
bool bSMASlowIsRising = false
bool bMACDIsRising = false
bool bMACDHistIsRising = false
bool bMACDSignalIsRising = false

float stopLoss = input (5, "StopLoss in %", type=input.float) //StopLoss associated with the order
//Best for alt versus BTC float stopLoss = input (3, "StopLoss in %", type=input.float) //StopLoss associated with the order 
float positionSize = 1000
float currentPrice = close 
float stopLossPrice = 0
float entryPrice = 0


//-----------------------------------------------------------


// === INPUT BACKTEST RANGE ONE YEAR 
//FromDay   = input(defval = 01, title = "From Day", minval = 1, maxval = 31)
//FromMonth = input(defval = 01, title = "From Month", minval = 1, maxval = 12)
//FromYear  = input(defval = 2020, title = "From Year", minval = 2017)
FromDay   = 01
FromMonth = 01
FromYear  = 2020

//ToDay     = input(defval = 01, title = "To Day", minval = 1, maxval = 31)
//ToMonth   = input(defval = 01, title = "To Month", minval = 1, maxval = 12)
//ToYear    = input(defval = 2023, title = "To Year", minval = 2017)
ToDay     = 14
ToMonth   = 05
ToYear    = 2029

// === FUNCTION EXAMPLE ===
start     = timestamp(FromYear, FromMonth, FromDay, 00, 00)  // backtest start window
finish    = timestamp(ToYear, ToMonth, ToDay, 23, 59)        // backtest finish window
window()  => true // create function "within window of time"


//FUNCTION DEFINITIONS
//----------------------
IsRising(data, loopBack) =>
    bIsRising = true
    for n = 1 to loopBack
        if data[n] > data[n-1]
            bIsRising := false
        continue
    bIsRising
    
IsFalling(data, loopBack) =>
    bIsFalling = true
    for n = 1 to loopBack
        if data[n] < data[n-1]
            bIsFalling := false
        continue
    bIsFalling
    
// END OF FUNCTION DEFINITIONS //


emaLength = 20
smaLength = 100
smaSlowLength = 200
 
ema = ema(close, emaLength) 
sma = sma(close, smaLength)
smaSlow = sma(close, smaSlowLength)

plot(sma, color=color.green)
plot(smaSlow, color=color.orange)
plot(ema, color=color.yellow)

//reload previous values
stopLossPrice := na(stopLossPrice[1]) ? 0.0 : stopLossPrice[1]
entryPrice := na(entryPrice[1]) ? 0.0 : entryPrice[1]
bPositionOpened := na(bPositionOpened[1]) ? false : bPositionOpened[1]
positionSize := na(positionSize[1]) ? 1000 : positionSize[1]
stockPositionSize := na(stockPositionSize[1]) ? 0 : stockPositionSize[1]
//leverage := na(leverage[1]) ? 1 : leverage[1]

bEMAIsRising := IsRising(ema, 2) 
bSMAIsRising := IsRising(sma, 3)
bMACDIsRising := IsRising(macdLine, 3)
bMACDHistIsRising := IsRising(macdHist, 1)
bSMASlowIsRising := IsRising(smaSlow, 10)
bMACDSignalIsRising := IsRising(macdSignalLine, 3)


atrValue := atr(14)
volatilityPercentage := (atrValue/currentPrice)*100 //calcute the volatility. Percentage of the actual price

 
if (window()) 
    //Check if we can open a LONG
    if (bPositionOpened == false and bSMASlowIsRising == true and bMACDIsRising == true and bEMAIsRising == true and bSMAIsRising == true and ema[0] > sma[0] and sma[0] < currentPrice)
        //Enter in short position 
        stockPositionSize := (positionSize*leverage)/currentPrice //Calculate the position size based on the actual price and the position Size (in $) configured.
        
        //calculate exit values
        stopLossPrice := currentPrice*(1-stopLoss/100) 
        strategy.entry("myPosition", strategy.long, qty=stockPositionSize, comment="BUY at " + tostring(currentPrice))
        entryPrice := currentPrice //store the entry price
        bPositionOpened := true  
        bDisplayArrow := true 
        
    if (bPositionOpened == true and (currentPrice <= stopLossPrice or crossunder(ema[1], sma[1])))
        strategy.close("myPosition", comment="" + tostring(currentPrice) ) //Stop
        //uncomment the below line to make the bot investing the full portfolio amount to test compounding effect.
        //positionSize := positionSize + ((stockPositionSize * currentPrice) - (positionSize*leverage)) 
        //reset some flags 
        bPositionOpened := false 
        bDisplayArrow := true 
        entryPrice := 0.0
        


더 많은