Cet article explique en détail une tendance quantitative suivant une stratégie basée sur l'analyse du ratio de volume.
I. Logique stratégique
L'indicateur de base de cette stratégie est le volume haussier et baissier.
Calculer le volume total quotidien.
Étiquettez le volume comme étant le volume des taureaux lorsque la barre quotidienne se ferme, et le volume des ours lorsqu'elle se ferme.
Calculer les moyennes mobiles séparément pour les volumes taureau et ours.
Un signal d'achat est généré lorsque le volume MA haussier dépasse le volume MA baissier, et inversement.
L'indicateur du taux de variation des prix est également utilisé comme filtre, ne prenant des transactions que lorsqu'une tendance claire existe.
Mettez un stop-loss et des bénéfices basés sur les signaux pour verrouiller les bénéfices.
En jugeant la direction de la tendance par rapport au volume et en filtrant avec le taux de variation des prix, la qualité du signal peut être améliorée.
II. Avantages de la stratégie
Le plus grand avantage de cette stratégie est l'utilisation du volume pour déterminer la direction de la tendance, qui est l'une des méthodes de suivi de tendance les plus élémentaires.
En outre, les indicateurs de volume peuvent refléter tôt les signaux de rupture, étant relativement sensibles.
Enfin, le filtrage par taux de variation des prix améliore également la qualité du signal.
III. Risques potentiels
Bien que la stratégie présente des avantages, les risques suivants doivent être pris en considération pour le trading en direct:
Premièrement, les paramètres des indicateurs de volume doivent être fixés avec prudence afin d'éviter de faux signaux.
Deuxièmement, le fait de s'appuyer uniquement sur un indicateur le rend susceptible d'invalidation des prix.
Enfin, le risque d'arrêt prématuré d'un stop loss trop proche.
IV. Résumé
En résumé, cet article a expliqué une stratégie quantitative utilisant le ratio de volume pour déterminer les tendances. Elle génère des signaux de trading en calculant des moyennes mobiles de volume haussier et baissier. La stratégie a un certain degré de lead et de sensibilité, mais doit être combinée à d'autres indicateurs pour vérification.
/*backtest start: 2023-08-14 00:00:00 end: 2023-09-13 00:00:00 period: 3h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 // Based on Volume Flow v3 indicator by oh92 strategy("Volume Flow BF", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0) /////////////// Time Frame /////////////// testStartYear = input(2017, "Backtest Start Year") testStartMonth = input(1, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0) testStopYear = input(2019, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(31, "Backtest Stop Day") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0) testPeriod() => true maType = input(title="Moving Average Type", options=["Simple", "Exponential", "Double Exponential"], defval="Simple") length = input(6, title="MA Length") x = input(3.1, title="Factor For Breakout Candle") // Basic Volume Calcs // vol = volume bull = close>open?vol:0 bear = open>close?vol:0 // Double EMA Function // dema(src, len) => (2 * ema(src, len) - ema(ema(src, len), len)) // BULL Moving Average Calculation bullma = maType == "Exponential" ? ema(bull, length) : maType == "Double Exponential" ? dema(bull, length) : sma(bull, length) // BEAR Moving Average Calculation // bearma = maType == "Exponential" ? ema(bear, length) : maType == "Double Exponential" ? dema(bear, length) : sma(bear, length) ///////////// Rate Of Change ///////////// source = close roclength = input(12, minval=1) pcntChange = input(2, minval=1) roc = 100 * (source - source[roclength]) / source[roclength] emaroc = ema(roc, roclength / 2) isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2)) /////////////// Strategy /////////////// long = bullma > bearma and isMoving() short = bullma < bearma and isMoving() last_long = 0.0 last_short = 0.0 last_long := long ? time : nz(last_long[1]) last_short := short ? time : nz(last_short[1]) long_signal = crossover(last_long, last_short) short_signal = crossover(last_short, last_long) last_open_long_signal = 0.0 last_open_short_signal = 0.0 last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1]) last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1]) last_long_signal = 0.0 last_short_signal = 0.0 last_long_signal := long_signal ? time : nz(last_long_signal[1]) last_short_signal := short_signal ? time : nz(last_short_signal[1]) in_long_signal = last_long_signal > last_short_signal in_short_signal = last_short_signal > last_long_signal last_high = 0.0 last_low = 0.0 last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1]) last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1]) sl_inp = input(2.0, title='Stop Loss %') / 100 tp_inp = input(900.0, title='Take Profit %') / 100 take_level_l = strategy.position_avg_price * (1 + tp_inp) take_level_s = strategy.position_avg_price * (1 - tp_inp) since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na slShort = strategy.position_avg_price * (1 + sl_inp) long_sl = in_long_signal ? slLong : na short_sl = in_short_signal ? slShort : na /////////////// Execution /////////////// if testPeriod() strategy.entry("Long", strategy.long, when=long) strategy.entry("Short", strategy.short, when=short) strategy.exit("Long Ex", "Long", stop=long_sl, limit=take_level_l, when=since_longEntry > 0) strategy.exit("Short Ex", "Short", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0) ///////////// Plotting ///////////// bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80) bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30) plot(bullma, color=color.lime, linewidth=1, transp=0, title="Bull MA", transp=10) plot(bearma, color=color.red, linewidth=1, transp=0, title="Bear MA", transp=10)