BTC와 ETH 장기 트렌드 전략

저자:차오장, 날짜: 2023-10-07 10:16:09
태그:

전반적인 설명

이것은 비트코인 및 이더리움과 같은 암호화폐에 대한 간단한 기술 지표 기반 자동화 된 장기 트렌드 전략으로 주요 상승 추세를 파악하고 빈번한 거래로 인한 거래 수수료 손실을 줄이는 것을 목표로합니다.

전략 논리

  1. 트렌드 방향을 결정하기 위해 MACD를 사용한다.

  2. 20주기 EMA, 100주기 SMA와 200주기 SMA를 계산합니다.

  3. EMA가 SMA보다 높고 SMA가 느린 SMA보다 높을 때 구매합니다.

  4. 스톱 로스 라인을 설정하고, 가격 경류가 되면 스톱 로스를 종료합니다.

  5. 가격이 하락하고 EMA가 SMA 아래로 넘어가면 포지션을 닫습니다.

이 전략은 트렌드와 진입 시기를 결정하기 위해 여러 지표를 결합하여 주요 상승 추세에서 이익을 얻습니다.

장점

  1. 여러 가지 지표 조합은 잘못된 신호와 잘못된 신호를 필터링하는 데 도움이 됩니다.

  2. 명백한 트렌드에 들어가는 것만이 불필요한 거래와 거래 빈도를 줄일 수 있습니다.

  3. 스톱 로즈는 거래당 최대 손실을 효과적으로 제한할 수 있습니다.

  4. 백테스트는 BTC와 ETH의 적당한 수익성을 보여줍니다.

  5. 단순하고 명확한 논리, 이해하기 쉽고 실행하기 쉬운, 초보자에게 좋습니다.

  6. 최적화를 위한 더 많은 지표를 포함하는 높은 확장성.

위험성

  1. 높은 시장의 무작위성, 잘못된 판단의 위험.

  2. 단일 포지션 접근법은 체계적인 위험을 감수할 수 없습니다.

  3. 잘못된 스톱 손실 설정은 오버 스톱 손실을 유발할 수 있습니다.

  4. 백테스트는 실제 결과를 나타내지 않습니다. 실제 성능은 아직 검증되지 않았습니다.

  5. 거래 비용 영향은 고려되지 않습니다. 라이브 공연과 다를 수 있습니다.

  6. 제품 특성을 고려하지 않았어, 매개 변수 조정 필요

최적화 방향

  1. 지표 매개 변수를 최적화하기 위해 다른 매개 변수 조합을 테스트합니다.

  2. KDJ 같은 필터를 추가해서 입력 신호를 필터링합니다.

  3. 동적 스톱 로스를 추가하는 것과 같은 스톱 로스 전략을 최적화합니다.

  4. 계좌 크기에 따라 포지션 크기를 고려하세요.

  5. 제품 특성을 구별하고 그에 따라 매개 변수를 조정합니다.

  6. 분석에 더 많은 시간 프레임을 포함합니다.

  7. 다양한 제품을 테스트하고 가장 적합한 것을 찾으십시오.

결론

전략 논리는 간단하고 명확하다. 여러 지표를 사용하면 잘못된 신호를 효과적으로 필터링하는 데 도움이 될 수 있다. 그러나 실제 적용 전에 실시간 거래 검증과 결합하여 매개 변수, 위험 통제 등을 더 이상 최적화해야합니다. 적절한 확장으로, 그것은 전략을 따르는 매우 실용적인 암호화 트렌드로 변할 수 있습니다.


/*backtest
start: 2023-09-06 00:00:00
end: 2023-10-06 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="BTC Long strategy", overlay=true, max_bars_back=3000, initial_capital=1000, commission_value=0.075)

//////////// !!!!!!!!!!!!!!!! WORK BEST IN 2 HOURS for BTC, ETH and ETHXBT !!!!!!!!!!!!!!!!!!! /////////////////////


[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 (1.5, "StopLoss in %", type=input.float) //StopLoss associated with the order 
//positionSize = input (1000, "in $")
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  = 2019


//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     = 31
ToMonth   = 12
ToYear    = 2099

// === 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"



//emaLength = input(20, "EMA Length")
//smaLength = input(100, "SMA Length")
//smaSlowLength = input(200, "SMA Length") 
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]) ? 50000 : positionSize[1]
stockPositionSize := na(stockPositionSize[1]) ? 0 : stockPositionSize[1]
//leverage := na(leverage[1]) ? 1 : leverage[1]
 
//ReEvaluate the direction of indicators
bEMAIsRising := rising(ema, 2) 
bSMAIsRising := rising(sma, 3)
bMACDIsRising := rising(macdLine, 3)
bMACDHistIsRising := rising(macdHist, 1)
bSMASlowIsRising := rising(smaSlow, 10)
bMACDSignalIsRising := rising(macdSignalLine, 3)

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


//There is too many signal in tranding market, to avoid this we need to make sure that the smaSlow has a mininal increase
//THIS DOES NOT WORK AT ALL!!!!!
//if bSMASlowIsRising == true
//    //calculate the percentegage difference over the last 10 bars
//    smaPercentageIncrease := ((smaSlow[0]/sma[10])-1)*100
//    if smaPercentageIncrease < SMA_PERCENT_INCREASE
//        //Not enough increase we reset the flag 
//        bSMASlowIsRising := false 
        
 
if (window()) 
    //Check if we can open a LONG
//sma > smaSlow and
    if ( volatilityPercentage < 2 and bPositionOpened == false and bSMASlowIsRising == true and bMACDIsRising == true and bEMAIsRising == true and bSMAIsRising == true and ema[0] > sma[0] and sma[0] < currentPrice)
    // add comparaison between macd and macd signal line
    //if (bPositionOpened == false and macdSignalLine < macdLine and bMACDIsRising == true and bMACDHistIsRising == true and bEMAIsRising == true and bSMAIsRising == true and ema[1] > sma[1] and sma[1] < 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]) or currentPrice < sma[1]))  
    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
        


더 많은