この戦略は,ビットコインの購入・販売のタイミングを決定し,取引を自動化するために複数の定量指標を使用している.主にハル指標,相対強度指数 (RSI),ボリンジャーバンド (BB),ボリュームオシレーター (VO) を含む.
変更されたハル移動平均値を利用して市場の主要トレンド方向を決定し,ボリンジャー帯を組み合わせて,ブレイクアウトの買いと売却点を決定します.
RSIインジケーターは,適応性波動性範囲と組み合わせて,取引信号を生成するために,過剰購入および過剰販売ゾーンを決定します.また,重複信号検証のために2つのパラメータセットが設定されています.
ボリュームオシレーターは 偽のブレイクを避けるために 買い物と販売の勢いを決定します
ストップ・ロスト/メリット・テイク比を事前に設定して,リスク管理のためにストップ・ロストとメリット・テイクレベルを事前に設定します.
ハル曲線はトレンドの変化をより早く捉えることができ ボリンジャー帯は誤った信号を減らすのに役立ちます
RSI パラメーターの最適化と重複信号の検証により,より信頼性が高まります.
ボリュームオシレーターとトレンドとインジケーターの信号が組み合わせられれば,不正な取引が避けられます.
既定のストップ・ロストとメリット・テイク・メソッドは,単一の利益と損失を自動的に制御し,全体的なリスクを効果的に管理することができます.
パラメータの設定が正しくない場合,取引頻度が高すぎたり,信号性能が低下したりする可能性があります.
突然の市場動向は,価格が激動し,ストップ・ロスは発生し,さらに大きな損失が生じる可能性があります.
取引品種が他のコインに変更されると,パラメータを再テストし最適化する必要があります.
音量データがない場合,音量振動器が故障します.
RSI パラメータの組み合わせをテストして 最適なパラメータを見つけます
RSIをMACDやKDなどの他の指標と組み合わせて信号の精度を向上させてください
モデル予測モジュールを追加し 機械学習を使用して 市場の方向性を判断します
他の取引品種に適用するとパラメータをテストする.
ストップ・ロストを最適化して 利潤を最大化します
この戦略は,エントリーと出口のタイミングを決定するために複数の定量的な技術指標を組み合わせます.パラメータ最適化,リスク管理,その他の方法を通じて,良い結果を持つ自動化されたビットコイン取引を達成しました.しかし,市場の変化に適応するために継続的なテストと最適化が必要です.投資家が取引決定を支援するための参照として機能することができます.
/*backtest start: 2023-11-25 00:00:00 end: 2023-12-25 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // © maxencetajet //@version=5 strategy("Strategy Crypto", overlay=true, initial_capital=1000, default_qty_type=strategy.fixed, default_qty_value=0.5, slippage=25) src1 = input.source(close, title="Source") target_stop_ratio = input.float(title='Risk/Reward', defval=1.5, minval=0.5, maxval=100) startDate = input.int(title='Start Date', defval=1, minval=1, maxval=31, group="beginning Backtest") startMonth = input.int(title='Start Month', defval=5, minval=1, maxval=12, group="beginning Backtest") startYear = input.int(title='Start Year', defval=2022, minval=2000, maxval=2100, group="beginning Backtest") inDateRange = time >= timestamp(syminfo.timezone, startYear, startMonth, startDate, 0, 0) swingHighV = input.int(7, title="Swing High", group="number of past candles") swingLowV = input.int(7, title="Swing Low", group="number of past candles") //Hull Suite modeSwitch = input.string("Hma", title="Hull Variation", options=["Hma", "Thma", "Ehma"], group="Hull Suite") length = input(60, title="Length", group="Hull Suite") lengthMult = input(3, title="Length multiplier", group="Hull Suite") HMA(_src1, _length) => ta.wma(2 * ta.wma(_src1, _length / 2) - ta.wma(_src1, _length), math.round(math.sqrt(_length))) EHMA(_src1, _length) => ta.ema(2 * ta.ema(_src1, _length / 2) - ta.ema(_src1, _length), math.round(math.sqrt(_length))) THMA(_src1, _length) => ta.wma(ta.wma(_src1, _length / 3) * 3 - ta.wma(_src1, _length / 2) - ta.wma(_src1, _length), _length) Mode(modeSwitch, src1, len) => modeSwitch == 'Hma' ? HMA(src1, len) : modeSwitch == 'Ehma' ? EHMA(src1, len) : modeSwitch == 'Thma' ? THMA(src1, len / 2) : na _hull = Mode(modeSwitch, src1, int(length * lengthMult)) HULL = _hull MHULL = HULL[0] SHULL = HULL[2] hullColor = HULL > HULL[2] ? #00ff00 : #ff0000 Fi1 = plot(MHULL, title='MHULL', color=hullColor, linewidth=1, transp=50) Fi2 = plot(SHULL, title='SHULL', color=hullColor, linewidth=1, transp=50) fill(Fi1, Fi2, title='Band Filler', color=hullColor, transp=40) //QQE MOD RSI_Period = input(6, title='RSI Length', group="QQE MOD") SF = input(5, title='RSI Smoothing', group="QQE MOD") QQE = input(3, title='Fast QQE Factor', group="QQE MOD") ThreshHold = input(3, title='Thresh-hold', group="QQE MOD") src = input(close, title='RSI Source', group="QQE MOD") Wilders_Period = RSI_Period * 2 - 1 Rsi = ta.rsi(src, RSI_Period) RsiMa = ta.ema(Rsi, SF) AtrRsi = math.abs(RsiMa[1] - RsiMa) MaAtrRsi = ta.ema(AtrRsi, Wilders_Period) dar = ta.ema(MaAtrRsi, Wilders_Period) * QQE longband = 0.0 shortband = 0.0 trend = 0 DeltaFastAtrRsi = dar RSIndex = RsiMa newshortband = RSIndex + DeltaFastAtrRsi newlongband = RSIndex - DeltaFastAtrRsi longband := RSIndex[1] > longband[1] and RSIndex > longband[1] ? math.max(longband[1], newlongband) : newlongband shortband := RSIndex[1] < shortband[1] and RSIndex < shortband[1] ? math.min(shortband[1], newshortband) : newshortband cross_1 = ta.cross(longband[1], RSIndex) trend := ta.cross(RSIndex, shortband[1]) ? 1 : cross_1 ? -1 : nz(trend[1], 1) FastAtrRsiTL = trend == 1 ? longband : shortband length1 = input.int(50, minval=1, title='Bollinger Length', group="QQE MOD") mult = input.float(0.35, minval=0.001, maxval=5, step=0.1, title='BB Multiplier', group="QQE MOD") basis = ta.sma(FastAtrRsiTL - 50, length1) dev = mult * ta.stdev(FastAtrRsiTL - 50, length1) upper = basis + dev lower = basis - dev color_bar = RsiMa - 50 > upper ? #00c3ff : RsiMa - 50 < lower ? #ff0062 : color.gray QQEzlong = 0 QQEzlong := nz(QQEzlong[1]) QQEzshort = 0 QQEzshort := nz(QQEzshort[1]) QQEzlong := RSIndex >= 50 ? QQEzlong + 1 : 0 QQEzshort := RSIndex < 50 ? QQEzshort + 1 : 0 RSI_Period2 = input(6, title='RSI Length', group="QQE MOD") SF2 = input(5, title='RSI Smoothing', group="QQE MOD") QQE2 = input(1.61, title='Fast QQE2 Factor', group="QQE MOD") ThreshHold2 = input(3, title='Thresh-hold', group="QQE MOD") src2 = input(close, title='RSI Source', group="QQE MOD") Wilders_Period2 = RSI_Period2 * 2 - 1 Rsi2 = ta.rsi(src2, RSI_Period2) RsiMa2 = ta.ema(Rsi2, SF2) AtrRsi2 = math.abs(RsiMa2[1] - RsiMa2) MaAtrRsi2 = ta.ema(AtrRsi2, Wilders_Period2) dar2 = ta.ema(MaAtrRsi2, Wilders_Period2) * QQE2 longband2 = 0.0 shortband2 = 0.0 trend2 = 0 DeltaFastAtrRsi2 = dar2 RSIndex2 = RsiMa2 newshortband2 = RSIndex2 + DeltaFastAtrRsi2 newlongband2 = RSIndex2 - DeltaFastAtrRsi2 longband2 := RSIndex2[1] > longband2[1] and RSIndex2 > longband2[1] ? math.max(longband2[1], newlongband2) : newlongband2 shortband2 := RSIndex2[1] < shortband2[1] and RSIndex2 < shortband2[1] ? math.min(shortband2[1], newshortband2) : newshortband2 cross_2 = ta.cross(longband2[1], RSIndex2) trend2 := ta.cross(RSIndex2, shortband2[1]) ? 1 : cross_2 ? -1 : nz(trend2[1], 1) FastAtrRsi2TL = trend2 == 1 ? longband2 : shortband2 QQE2zlong = 0 QQE2zlong := nz(QQE2zlong[1]) QQE2zshort = 0 QQE2zshort := nz(QQE2zshort[1]) QQE2zlong := RSIndex2 >= 50 ? QQE2zlong + 1 : 0 QQE2zshort := RSIndex2 < 50 ? QQE2zshort + 1 : 0 hcolor2 = RsiMa2 - 50 > ThreshHold2 ? color.silver : RsiMa2 - 50 < 0 - ThreshHold2 ? color.silver : na Greenbar1 = RsiMa2 - 50 > ThreshHold2 Greenbar2 = RsiMa - 50 > upper Redbar1 = RsiMa2 - 50 < 0 - ThreshHold2 Redbar2 = RsiMa - 50 < lower //Volume Oscillator var cumVol = 0. cumVol += nz(volume) if barstate.islast and cumVol == 0 runtime.error("No volume is provided by the data vendor.") shortlen = input.int(5, minval=1, title = "Short Length", group="Volume Oscillator") longlen = input.int(10, minval=1, title = "Long Length", group="Volume Oscillator") short = ta.ema(volume, shortlen) long = ta.ema(volume, longlen) osc = 100 * (short - long) / long //strategy enterLong = ' { "message_type": "bot", "bot_id": 4635591, "email_token": "25byourtefcodeuufyd2-43314-ab98-bjorg224", "delay_seconds": 1} ' //start long deal ExitLong = ' { "message_type": "bot", "bot_id": 4635591, "email_token": "25byourtefcodeuufyd2-43314-ab98-bjorg224", "delay_seconds": 0, "action": "close_at_market_price"} ' // close long deal market enterShort = ' { "message_type": "bot", "bot_id": 4635690, "email_token": "25byourtefcodeuufyd2-43314-ab98-bjorg224", "delay_seconds": 1} ' // start short deal ExitShort = ' { "message_type": "bot", "bot_id": 4635690, "email_token": "25byourtefcodeuufyd2-43314-ab98-bjorg224", "delay_seconds": 0, "action": "close_at_market_price"} ' // close short deal market longcondition = close > MHULL and HULL > HULL[2] and osc > 0 and Greenbar1 and Greenbar2 and not Greenbar1[1] and not Greenbar2[1] shortcondition = close < SHULL and HULL < HULL[2] and osc > 0 and Redbar1 and Redbar2 and not Redbar1[1] and not Redbar2[1] float risk_long = na float risk_short = na float stopLoss = na float takeProfit = na float entry_price = na risk_long := risk_long[1] risk_short := risk_short[1] swingHigh = ta.highest(high, swingHighV) swingLow = ta.lowest(low, swingLowV) if strategy.position_size == 0 and longcondition and inDateRange risk_long := (close - swingLow) / close strategy.entry("long", strategy.long, comment="Buy", alert_message=enterLong) if strategy.position_size == 0 and shortcondition and inDateRange risk_short := (swingHigh - close) / close strategy.entry("short", strategy.short, comment="Sell", alert_message=enterShort) if strategy.position_size > 0 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", stop = stopLoss, limit = takeProfit, alert_message=ExitLong) if strategy.position_size < 0 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", stop = stopLoss, limit = takeProfit, alert_message=ExitShort) p_ep = plot(entry_price, color=color.new(color.white, 0), linewidth=2, style=plot.style_linebr, title='entry price') p_sl = plot(stopLoss, color=color.new(color.red, 0), linewidth=2, style=plot.style_linebr, title='stopLoss') p_tp = plot(takeProfit, color=color.new(color.green, 0), linewidth=2, style=plot.style_linebr, title='takeProfit') fill(p_sl, p_ep, color.new(color.red, transp=85)) fill(p_tp, p_ep, color.new(color.green, transp=85))