これは,ビットコインやイーサリアムなどの暗号通貨のための単純な技術指標ベースの自動化された長期トレンド戦略で,主要な上昇傾向を把握し,頻繁な取引による取引手数料損失を減らすことを目的としています.
傾向の方向を決定するためにMACDを使用し,MACDが上昇するときに長;
20期間のEMA,100期間のSMAと200期間のSMAを計算します.
EMAがSMAより高く,SMAがSMAより遅いときに購入する.
ストップ・ロストラインを設定し,価格が破るとストップ・ロストをします.
価格が下がり,EMAがSMAを下回るとポジションを閉じる.
この戦略は,複数の指標を組み合わせて,主要な上昇傾向から利益を得るために,トレンドとエントリータイミングを決定します.
複数のインジケーターの組み合わせは 偽のブレイクや間違った信号を フィルタリングするのに役立ちます
必要な取引や取引頻度を減らすことができます
ストップ・ロスは,取引ごとに最大損失を効果的に制限することができます.
バックテストでは BTCとETHの収益性が良好です
シンプルで明快な論理で 分かりやすく実行し 初心者にも適しています
最適化のためのより多くの指標を含むための高い拡張性.
市場のランダム性が高く 判断が間違えるリスクもあります
単一ポジションアプローチは,体系的なリスクをカバーすることはできません.
誤ったストップ損失設定は,オーバーストップ損失を引き起こす可能性があります.
バックテストは実際の結果を示さない 実際の性能はまだ検証されていません
取引コストの影響は考慮されていないが ライブパフォーマンスとは異なる可能性があります
製品特性を考慮しなかった パラメータ調整が必要だった
指標パラメータを最適化するために異なるパラメータ組み合わせをテストする.
KDJのようなフィルターを入力信号に追加します
ストップロスの戦略を最適化します 例えば ダイナミックストップロスを追加します
ポジションのサイズを口座サイズに基づいて考える.
製品の特徴を区別し,そのパラメータを調整する.
分析のためにより多くの時間枠を組み込む.
異なる製品を試し,最も適したものを探す.
戦略の論理は単純で明確である.複数の指標を使用することで,誤った信号を効果的にフィルターにすることができます.しかし,実際の適用前に,ライブ取引検証と組み合わせて,パラメータ,リスク管理などに対するさらなる最適化が必要です.適切な拡張により,戦略をフォローする非常に実践的な暗号トレンドになり得ます.
/*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