BTCとETHの長期トレンド戦略

作者: リン・ハーンチャオチャン,日付: 2023年10月7日 10:16:09
タグ:

概要

これは,ビットコインやイーサリアムなどの暗号通貨のための単純な技術指標ベースの自動化された長期トレンド戦略で,主要な上昇傾向を把握し,頻繁な取引による取引手数料損失を減らすことを目的としています.

戦略の論理

  1. 傾向の方向を決定するためにMACDを使用し,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
        


もっと