YinYang RSI ボリュームトレンド トレーディング戦略

作者: リン・ハーンチャオチャン開催日:2023年12月22日 14:29:05
タグ:

img

概要

この戦略は,トレンド指数 (RSI) とボリュームの組み合わせを使用して,トレンド方向を特定し,トレンドをフォローするトレンドフォロー戦略である.主要ポイントは以下の通りである.

  1. 中間線を計算するためにボリューム重量移動平均を使用し,トレンドの中間点を決定するためにボリューム情報を組み込む
  2. 中間線をベースに購入ゾーンと販売ゾーンの設定
  3. RSI情報を使用して,購入ゾーンと販売ゾーンの範囲を調整する
  4. ストップ・ロスの設定と,買い/売るゾーンに入る後に利益を取ること
  5. 再入力メカニズムを持つ

戦略の論理

この戦略は以下の指標とパラメータを使用します.

  • 中間線: 傾向の中間点を決定するための特定の期間の最大値と最低値のボリューム重量移動平均
  • RSI: 特定の期間で計算された相対強度指数 0-1範囲に変換
  • 購入ゾーン: 価格入力時に特定の比率でミッドラインプラスRSI調整金額,ロングエントリー
  • セールゾーン: 中間線マイナスRSI調整額,価格入力時にショートエントリー
  • 利益ライン: 中間線
  • ストップ・ロスのライン: 購入ゾーン以下/販売ゾーン上の一定の割合

価格が購入または販売ゾーンに入ると,対応する方向オーダーが開かれます. Stop loss と take profit ラインが設定されます. Take profit や stop loss がトリガーされると,ポジションが閉鎖されます. 設定されている場合,信号が再びトリガーされたときに新しいオーダーを開くことができるため,再エントリーメカニズムも設定されています.

利点

この戦略の利点は以下の通りです.

  1. 傾向を特定するためにRSIとボリュームの両方を使用し,正確性を向上させる
  2. RSIのパラメータ化調整により,購入/販売ゾーンは実際のトレンドにより順応する
  3. ボリューム情報により価格動向により高い重みを与え,ミッドラインをより正確にする
  4. リスク制御のためのストップ・ロスのメカニズムを持つ
  5. 偽の脱出のリスクを減らすため 再入国を許可します

リスク

リスクもあります:

  1. 誤ったRSIとボリュームパラメータは,購入/販売ゾーンの精度に影響を与える可能性があります.
  2. 中間線はトレンドを正確に判定できず,誤ったブレイクが発生する可能性があります.
  3. ストップ・ロスは幅が大きすぎると,損失が増える可能性があります.
  4. 再入国は過剰取引を引き起こす可能性があります.

解決策:

  1. RSIとボリュームサイクルを市場条件に合わせて調整する
  2. 購入/売却のシグナルを検証するために他の指標を使用する
  3. 損失を制限するためにストップロスを強化する
  4. 過剰な取引を防ぐために,1日間の取引を制限する

最適化

この戦略は,以下の方法で最適化できます.

  1. 信号を検証するために他の指標を試す,例えばキャンドルスタイク,変動指標など
  2. ポジションサイズメカニズムの追加,例えばピラミッドの勝者
  3. 買い/売るゾーンの精度を向上させるための機械学習アルゴリズムを使用
  4. ストップ・ロスの最適パラメータと得益の最適パラメータの評価
  5. パラメータは,異なる製品で別々のテストと最適化が必要です

結論

結論として,これはRSIとボリュームインジケーターを利用した戦略をフォローする定量的なトレンドである.信号を識別するための二重検証システム,リスクを制御するためのストップ損失/利益取り,収益性を向上させる再エントリーメカニズムがある.パラメータチューニングとアルゴリズム最適化により,非常に実践的なトレンドトレード戦略になることができます.


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

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    ,@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         @@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           @@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        .@@@@@@@@@@@@@@@            @@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@          *@@@@@@@@@@@@@@             @@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         @@@@@@@@@@@@@@@               @@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@                 @@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                  @@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.                    @@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                      @@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.                         @
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                             @
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,                                       @
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                @
// @@@@@@@@@@@@@@@@@@@@@@@@@@@                                                    @
// @@@@@@@@@@@@@@@@@@@@@@@@@                                                     @@
// @@@@@@@@@@@@@@@@@@@@@@@                                                       @@
// @@@@@@@@@@@@@@@@@@@@@@                                                       @@@
// @@@@@@@@@@@@@@@@@@@@@*                @@@@@                                 @@@@
// @@@@@@@@@@@@@@@@@@@@@               @@@@@@@@@                              @@@@@
// @@@@@@@@@@@@@@@@@@@@@              @@@@@@@@@@@                           @@@@@@@
// @@@@@@@@@@@@@@@@@@@@@               @@@@@@@@%                           @@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@                                                @@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@                                            @@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@                                        %@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@                                   @@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@                           @@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// © YinYangAlgorithms

//@version=5
strategy("YinYang RSI Volume Trend Strategy", shorttitle="YinYang RSVT Strategy", overlay=true )
// ~~~~~~~~~~~ INPUTS ~~~~~~~~~~~ //
len = input.int(80, "Trend Length:", tooltip="How far back should we span this indicator?\nThis length effects all lengths of the indicator")
purchaseSrc = input.source(close, "Purchase Source (Long and Short):", tooltip="What source needs to exit the purchase zone for a purchase to happen?")
exitSrc = input.source(close, "Exit Source (Long and Short):", tooltip="What source needs to hit a exit condition to stop the trade (Take profit, Stop Loss or hitting the other sides Purchase Zone)?")
useTakeProfit = input.bool(true, "Use Take Profit", tooltip="Should we take profit IF we cross the basis line and then cross it AGAIN?")
useStopLoss = input.bool(true, "Use Stop Loss", tooltip="Stop loss will ensure you don't lose too much if its a bad call")
stopLossMult = input.float(0.1, "Stoploss Multiplier %:", tooltip="How far from the purchase lines should the stop loss be")
resetCondition = input.string("Entry", "Reset Purchase Availability After:", options=["Entry", "Stop Loss", "None"],
 tooltip="If we reset after a condition is hit, this means we can purchase again when the purchase condition is met. \n" +
 "Otherwise, we will only purchase after an opposite signal has appeared.\n" +
 "Entry: means when the close enters the purchase zone (buy or sell).\n" +
 "Stop Loss: means when the close hits the stop loss location (even when were out of a trade)\n" +
 "This allows us to get more trades and also if our stop loss initally was hit but it WAS a good time to purchase, we don't lose that chance.")

// ~~~~~~~~~~~ VARIABLES ~~~~~~~~~~~ //
var bool longStart = na
var bool longAvailable = na
var bool longTakeProfitAvailable = na
var bool longStopLoss = na
var bool shortStart = na
var bool shortAvailable = na
var bool shortTakeProfitAvailable = na
var bool shortStopLoss = na

resetAfterStopLoss = resetCondition == "Stop Loss"
resetAfterEntry = resetCondition == "Entry"

// ~~~~~~~~~~~ CALCULATIONS ~~~~~~~~~~~ //
// Mid Line
midHigh = ta.vwma(ta.highest(high, len), len)
midLow = ta.vwma(ta.lowest(low, len), len)
mid = math.avg(midHigh, midLow)
midSmoothed = ta.ema(mid, len)

//Volume Filtered
avgVol = ta.vwma(volume, len)
volDiff = volume / avgVol
midVolSmoothed = ta.vwma(midSmoothed * volDiff, 3)

//RSI Filtered
midDifference = ta.sma(midHigh - midLow, len)
midRSI = ta.rsi(midVolSmoothed, len) * 0.01
midAdd = midRSI * midDifference

//Calculate Zones
purchaseZoneHigh = midSmoothed + midAdd
purchaseZoneLow = midSmoothed - midAdd
purchaseZoneBasis = math.avg(purchaseZoneHigh, purchaseZoneLow)

//Create Stop Loss Locations
stopLossHigh = purchaseZoneHigh * (1 + (stopLossMult * 0.01))
stopLossLow = purchaseZoneLow * (1 - (stopLossMult * 0.01))

// ~~~~~~~~~~~ PURCHASE CALCULATIONS ~~~~~~~~~~~ //
//Long
longEntry = ta.crossunder(purchaseSrc, purchaseZoneLow)
longStart := ta.crossover(purchaseSrc, purchaseZoneLow) and longAvailable
longAvailable := ta.crossunder(purchaseSrc, purchaseZoneHigh) or (resetAfterStopLoss and longStopLoss) or (resetAfterEntry and longEntry) ? true : longStart ? false : longAvailable[1]
longEnd = ta.crossover(exitSrc, purchaseZoneHigh)
longStopLoss := ta.crossunder(exitSrc, stopLossLow)
longTakeProfitAvailable := ta.crossover(exitSrc, purchaseZoneBasis) ? true : longEnd ? false : longTakeProfitAvailable[1]
longTakeProfit = ta.crossunder(exitSrc, purchaseZoneBasis) and longTakeProfitAvailable

//Short
shortEntry = ta.crossover(purchaseSrc, purchaseZoneHigh)
shortStart := ta.crossunder(purchaseSrc, purchaseZoneHigh) and shortAvailable
shortAvailable := ta.crossover(purchaseSrc, purchaseZoneLow) or (resetAfterStopLoss and shortStopLoss) or (resetAfterEntry and shortEntry)? true : shortStart ? false : shortAvailable[1]
shortEnd = ta.crossunder(exitSrc, purchaseZoneLow)
shortStopLoss := ta.crossover(exitSrc, stopLossHigh)
shortTakeProfitAvailable := ta.crossunder(exitSrc, purchaseZoneBasis) ? true : shortEnd ? false : shortTakeProfitAvailable[1]
shortTakeProfit = ta.crossover(exitSrc, purchaseZoneBasis) and shortTakeProfitAvailable

// ~~~~~~~~~~~ PLOTS ~~~~~~~~~~~ //
shortLine = plot(purchaseZoneHigh, color=color.green)
shortStopLossLine = plot(stopLossHigh, color=color.green) //color=color.rgb(0, 97, 3)
fill(shortLine, shortStopLossLine, color = color.new(color.green, 90))
plot(purchaseZoneBasis, color=color.white)
longLine = plot(purchaseZoneLow, color=color.red)
longStopLossLine = plot(stopLossLow, color=color.red) //color=color.rgb(105, 0, 0)
fill(longLine, longStopLossLine, color=color.new(color.red, 90))

// ~~~~~~~~~~~ STRATEGY ~~~~~~~~~~~ //
if (longStart)
    strategy.entry("buy", strategy.long)
else if (longEnd or (useStopLoss and longStopLoss) or (useTakeProfit and longTakeProfit))
    strategy.close("buy")

if (shortStart)
    strategy.entry("sell", strategy.short)
else if (shortEnd or (useStopLoss and shortStopLoss) or (useTakeProfit and shortTakeProfit))
    strategy.close("sell")

// ~~~~~~~~~~~ ALERTS ~~~~~~~~~~~ //
if longStart or (longEnd or (useStopLoss and longStopLoss) or (useTakeProfit and longTakeProfit)) or shortStart or (shortEnd or (useStopLoss and shortStopLoss) or (useTakeProfit and shortTakeProfit))
    alert("{{strategy.order.action}} | {{ticker}} | {{close}}", alert.freq_once_per_bar)

もっと