ベイビーシャークのVWAP取引戦略 VWAPおよびOBVRSI指標に基づいて

作者: リン・ハーンチャオチャン,日付: 2024-03-08 16時39分28秒
タグ:

img

戦略の概要

ベビーシャークVWAP取引戦略は,ボリューム・ウェイト・平均価格 (VWAP) とバランス・ボリューム相対強度指数 (OBV RSI) をベースとした定量的な取引戦略である.この戦略は,特定の値を超えたVWAPとOBV RSIからの偏差に基づいて潜在的な買い売り信号を特定することを目的としている.

戦略原則

この戦略の主な原則は,市場動向と勢力の変化を把握するためにVWAPおよびOBV RSI指標を使用することです.VWAPは価格とボリュームに基づいて動的な移動平均値で,市場の主要な取引領域を反映しています.価格がVWAPから大幅に逸脱すると,通常市場での過買いまたは過売状態を示します.一方,OBV RSIは,ボリューム変化の強度を測定することによって市場動向の強さを決定するために,伝統的なRSI指標に基づいてボリューム因子を導入します.

具体的には,この戦略は,VWAPの計算期間として60個のキャンドルを使用し,閉値が入力データである.その後,VWAPからの正値および負値3標準偏差の価格偏差に基づいて過買いおよび過売りゾーンを構築する.OBV RSIでは,計算期間として5個のキャンドルを使用し,過買いおよび過売り条件を決定するための基準として70と30の値を設定する.

トレーディングロジックの観点から,価格がVWAPの下帯以下のoversoldゾーンにあり,OBV RSIが30未満の場合,ストラテジーはロング信号を生成する.逆に,価格がVWAPの上帯以上のoversoldゾーンにあり,OBV RSIが70を超えると,ショート信号を生成する.さらに,戦略は0.6%の利潤とストップ損失比を設定し,リスクを制御するために連続した損失後10キャンドルの冷却期間を導入する.

戦略 の 利点

  1. 価格や量などの複数の市場要因を組み合わせて,市場の動向と勢いを包括的に把握します.
  2. 動的VWAPおよびOBV RSI指標を採用し,異なる市場サイクルの変化に適応する.
  3. 合理的な利益とストップ・ロスの比率と冷却期間を設定し,機会を把握しながらリスクを効果的に制御します.
  4. 明確な論理,理解し実行しやすい,ある程度の解釈可能性がある.
  5. 調節可能なパラメータ,さまざまなスタイルを持つトレーダーに最適化と改善に適しています.

戦略リスク

  1. 振動または繰り返しの市場では,頻繁な取引シグナルが過剰な取引と滑りコストの増加につながることがあります.
  2. トレンド市場では,VWAPのみで利益を得ることは,戦略が早すぎる段階で終了し,後続のトレンド利益が失われる可能性があります.
  3. 固定パラメータの設定は,市場の状況の変化に適応できない可能性があり,異なるツールと時間枠に最適化する必要があります.
  4. OBV指標は量データに大きく依存しており,量データが不正確または操作された場合,指標の歪みは判断を誤導する可能性があります.
  5. この戦略は,マクロ経済やニュースなどの外部要因を考慮していないため,極端な市場状況では失敗する可能性があります.

オプティマイゼーションの方向性

  1. 振動する市場に対するフィルタリング条件を,傾向確認指標や変動指標などより多く導入し,頻繁に取引を減らす.
  2. トレーリングストップや他のトレンド指数と組み合わせることで,トレンド市場をより良く把握するための脱出条件を最適化します.
  3. VWAPとOBVのRSIパラメータの適応最適化を行い,計算期間と値設定を動的に調整する.
  4. OBV RSI インジケーターの信頼性を向上させるため,ボリューム認証メカニズムを導入する.
  5. マクロ経済データ分析,感情指標なども考慮し,戦略の適応性と強さを高める.

概要

ベビーシャークVWAP取引戦略は,売り過ぎや売り過ぎの状況,トレンドモメンタムの変化を把握することによって取引信号を生成するために,ボリューム重量平均価格とバランスボリューム相対強度指数を組み合わせる定量的な取引戦略である.この戦略は,価格やボリュームなどの複数の市場要因を統合し,市場のパルスを包括的に把握する明確な論理を有する.同時に,合理的な利益とストップ損失設定,リスク管理メカニズムにより,戦略はリスク管理を考慮しながらリターンを追求することができる.しかし,戦略には,振動する市場やトレンド市場や固定最適化器への適応性の不十分などの潜在的な問題もあります.将来の改善はエントリーアダプター,ダイナミック・プロフィートテイキング,動的パラメータ,外部データ分析の強化,戦略の強固性と収益性の改善に焦点を当てることができます.全体的に,ベビーシャークVWAPは,さらなる調査と改善に値する取引戦略のための定量的な基準フレームワークを提供します.


/*backtest
start: 2024-02-01 00:00:00
end: 2024-02-29 23:59:59
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © GreatestUsername

//@version=5
strategy("BabyShark VWAP Strategy", overlay=true, margin_long=100, margin_short=100, calc_on_every_tick = true)


// VWAP
ls = input(false, title='Log-space', group = "Optional")
type = 'Average Deviation'
length = input(60, group="Strategy Modification")
source = input(close, group="Strategy Modification")
_low = ls == true ? math.log(low) : low
_high = ls == true ? math.log(high) : high
src = ls == true ? math.log(source) : source

//weighted mean
pine_vwmean(x, y) =>
    cw = 0.0
    cd = 0.0
    w_sum = 0.0
    d_sum = 0.0
    for i = 0 to y - 1 by 1
        cd := x[i]
        cw := volume[i]
        d_sum += cw * cd
        w_sum += cw
        w_sum
    d_sum / w_sum

//weighted standard deviation
pine_vwstdev(x, y, b) =>
    d_sum = 0.0
    w_sum = 0.0
    cd = 0.0
    for i = 0 to y - 1 by 1
        cd := x[i]
        cw = volume[i]
        d_sum += cw * math.pow(cd - b, 2)
        w_sum += cw
        w_sum
    math.sqrt(d_sum / w_sum)

//weighted average deviation
pine_vwavdev(x, y, b) =>
    d_sum = 0.0
    w_sum = 0.0
    cd = 0.0
    for i = 0 to y - 1 by 1
        cd := x[i]
        cw = volume[i]
        d_sum += cw * math.abs(cd - b)
        w_sum += cw
        w_sum
    d_sum / w_sum

vwmean = pine_vwmean(src, length)

//consider using Average Deviation instead of Standard Deviatio if there are values outside of 3rd upper & lower bands within a rolling window
dev = if type == 'Standard Deviation'
    dev = pine_vwstdev(src, length, vwmean)
    dev
else if type == 'Average Deviation'
    dev = pine_vwavdev(src, length, vwmean)
    dev

basis = ls == true ? math.exp(vwmean) : vwmean
plot(basis, color=color.new(#b7b7b7, 60), title='Basis')

upper_dev_2 = vwmean + dev * 2
upper_dev_3 = vwmean + dev * 3

lower_dev_2 = vwmean - dev * 2
lower_dev_3 = vwmean - dev * 3

fill(
     plot1=plot(ls == true ? math.exp(upper_dev_2) : upper_dev_2, color=color.new(#B20000, 0), title='Upper dev 2'), 
     plot2=plot(ls == true ? math.exp(upper_dev_3) : upper_dev_3, color=color.new(#FF6666, 0), title='Upper dev 3', display=display.none), 
     color=color.new(#FF4D4D, 80), title='Upper band'
     )
fill(
     plot1=plot(ls == true ? math.exp(lower_dev_3) : lower_dev_3, color=color.new(#00CC00, 0), title='Lower dev 3', display=display.none), 
     plot2=plot(ls == true ? math.exp(lower_dev_2) : lower_dev_2, color=color.new(#008000, 0), title='Lower dev 2'), 
     color=color.new(#006600, 80), title='Lower band'
     )


// Input to enable or disable the table visibility
table_visible = input(false, title="Show Table", group="Deviation Cross Monitor")
// Input for the number of candles to look back
table_length = input(300, title="Table Lookback Length", group="Deviation Cross Monitor")

// Custom count function
count_occurrences(cond, length) =>
    count = 0
    for i = 0 to length - 1
        if cond[i]
            count := count + 1
    count

// Count occurrences of prices above Upper dev 2 and below Lower dev 2

above_upper_dev_2 = count_occurrences(close > upper_dev_2, table_length)
below_lower_dev_2 = count_occurrences(close < lower_dev_2, table_length)

// Create table in the bottom right corner
var table tbl = table.new(position=position.bottom_right, rows=2, columns=2)

if table_visible
    if barstate.islast
        // Update the table headers
        table.cell(tbl, 0, 0, "Above Upper Dev 2", bgcolor=color.gray, text_color=color.white)
        table.cell(tbl, 0, 1, "Below Lower Dev 2", bgcolor=color.gray, text_color=color.white)
        
        // Update the table values
        table.cell(tbl, 1, 0, str.tostring(above_upper_dev_2), bgcolor=color.new(color.green, 90), text_color=color.green)
        table.cell(tbl, 1, 1, str.tostring(below_lower_dev_2), bgcolor=color.new(color.red, 90), text_color=color.red)
else
    table.delete(tbl)

// RSI
obvsrc = close
change_1 = ta.change(obvsrc)
obv = ta.cum(ta.change(obvsrc) > 0 ? volume : change_1 < 0 ? -volume : 0 * volume)

src2 = obv
len = input.int(5, minval=1, title="RSI Length", group="Strategy Modification")
up = ta.rma(math.max(ta.change(src2), 0), len)
down = ta.rma(-math.min(ta.change(src2), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - 100 / (1 + up / down)
higherlvl = input(70, title="Higher Level", group="Strategy Modification")
lowerlvl = input(30, title="Lower Level", group="Strategy Modification")


plot_color = rsi >= higherlvl ? color.red : rsi <= lowerlvl ? color.green : color.new(#b7b7b7, 60)
// plot(rsi, color=plot_color)

//plot(rsi, color=color.white)



// Count occurrences of RSI crossing higher level and lower level
cross_above_higher = ta.crossover(rsi, higherlvl)
cross_below_lower = ta.crossunder(rsi, lowerlvl)
above_higher_count = count_occurrences(cross_above_higher, table_length)
below_lower_count = count_occurrences(cross_below_lower, table_length)

// Create table in the bottom right corner
if (table_visible)
    var table tbl2 = table.new(position=position.bottom_right, rows=2, columns=2)
    if (barstate.islast)
        // Update the table headers
        table.cell(tbl2, 0, 0, "Higher Level Cross", bgcolor=color.gray, text_color=color.white)
        table.cell(tbl2, 0, 1, "Lower Level Cross", bgcolor=color.gray, text_color=color.white)
        
        // Update the table values
        table.cell(tbl2, 1, 0, str.tostring(above_higher_count), bgcolor=color.new(color.red, 90), text_color=color.red)
        table.cell(tbl2, 1, 1, str.tostring(below_lower_count), bgcolor=color.new(color.green, 90), text_color=color.green)


// Entries

// Long Entry:
// Price is in the shaded GREEN area of [Hoss] VWAP Deviation
// and the [Hoss] OBV RSI is GREEN.
longCondition1 = close <= lower_dev_3
longConditions = plot_color == color.green and longCondition1 and strategy.position_size == 0

// Short Entry:
// Price is in the shaded RED area of [Hoss] VWAP Deviation
// and the [Hoss] OBV RSI is RED.
shortCondition1 = close >= upper_dev_3
shortConditions = plot_color == color.red and shortCondition1 and strategy.position_size == 0

var int lastEntryBar = 0


shortEMA = ta.ema(close, 12)
longEMA = ta.ema(close, 21)
uptrend = shortEMA > longEMA

if longConditions and lastEntryBar < bar_index - 10 //and uptrend
    strategy.entry("Long", strategy.long, stop=close * 0.994)
    lastEntryBar := bar_index

if shortConditions and lastEntryBar < bar_index - 10 //and not uptrend
    strategy.entry("Short", strategy.short, stop=close * 1.006)
    lastEntryBar := bar_index


if strategy.position_size > 0 and (ta.crossover(close, basis) or strategy.opentrades.entry_price(strategy.opentrades - 1) * 0.994 > close)
    strategy.close("Long", immediately = true)
if strategy.position_size < 0 and (ta.crossunder(close, basis) or strategy.opentrades.entry_price(strategy.opentrades - 1) * 1.006 < close)
    strategy.close("Short", immediately = true)

// Stop Loss:
// 0.6%
// After 1 Loss => NO more Trades for 10 Candles (10 minutes) (usually a breakout will happen, and it takes average 10min till it ranges again. So basically wait for range to form again)

// Take Profit:
// Grey line on [Hoss] VWAP Deviation or 0.6%



もっと