Cette stratégie est basée sur les signaux haussiers et baissiers générés par l'indicateur de canal de prix Donchain et l'indicateur quantitatif de l'oscillateur OBV pour le trading bidirectionnel.
Utilisez l'indicateur de canal de prix Donchain pour déterminer les canaux de prix supérieur et inférieur.
Construisez un oscillateur OBV en utilisant l'indicateur quantitatif OBV et l'indicateur EMA pour déterminer la force haussière et la force baissière.
Un signal long est généré lorsque le prix traverse le canal supérieur et que l'oscillateur est supérieur à 0, un signal court est généré lorsque le prix traverse le canal inférieur et que l'oscillateur est inférieur à 0.
Fermer les positions longues lorsque les prix reculent vers le canal inférieur; Fermer les positions courtes lorsque les prix reculent vers le canal supérieur.
L'utilisation de canaux de prix pour déterminer les tendances permet d'éviter d'être induit en erreur par les fluctuations des marchés.
L'incorporation d'indicateurs quantitatifs pour juger de la force haussière et baissière garantit que la direction des échanges est cohérente avec la force du marché.
L'adoption du trading bidirectionnel permet de réaliser des profits que le marché monte ou tombe.
La mise en place de stratégies de stop loss permet de gérer efficacement les risques.
Un mauvais réglage des paramètres des canaux de prix peut conduire à des canaux trop larges ou étroits, à des opportunités de négociation manquantes ou à la génération de signaux erronés.
Des paramètres d'indicateur mal réglés peuvent également entraîner une génération de signal retardée ou prématurée.
Les mouvements soudains et anormalement volatils d'événements peuvent déclencher des arrêts de pertes menant à des pertes.
La négociation bidirectionnelle nécessite la gestion simultanée de positions longues et courtes, ce qui complique l'opération.
Optimiser les paramètres des canaux de prix pour trouver des combinaisons optimales.
Testez et optimisez les paramètres de l'oscillateur OBV afin d'assurer des jugements rapides et précis de la force haussière/baissière.
Considérez l'incorporation d'autres indicateurs tels que MACD, KD, etc. pour améliorer la précision du signal.
Tester différentes méthodes de stop loss, par exemple les stop de suivi, les stop en pourcentage, etc.
Testez différents produits pour trouver celui qui convient le mieux à la stratégie.
Dans l'ensemble, il s'agit d'une stratégie de négociation bidirectionnelle claire et facile à comprendre, intégrant l'action des prix et des indicateurs quantitatifs pour déterminer les tendances et la force du marché.
/*backtest start: 2022-12-06 00:00:00 end: 2023-12-12 00:00:00 period: 1d basePeriod: 1h 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/ // © ahancock //@version=4 strategy( title = "Hancock - Filtered Volume OBV OSC [Strategy]", initial_capital = 1000, overlay = false, commission_type = strategy.commission.percent, commission_value= 0.075) // Inputs source = input(close, title = "Source", type = input.source) use_volume_filter = input(true, title = "Use Volume Filter", type = input.bool) vol_filter_length = input(20, title = "Volume Filter - Length", type = input.integer, minval = 1) vol_filter_multiplier = input(1.2, title = "Volume Filter - Multiplier", type = input.float, minval = 0.1, step = 0.1) use_osc = input(true, title = "Use Oscillator", type = input.bool) osc_length = input(40, title = "Oscillator - Signal Length", type = input.integer, minval = 1) channel_length = input(65, title = "Channel - Slow Length", minval = 5, maxval = 200, step = 5) channel_percent = input(70, title = "Channel - Fast Length Percent", minval = 5, maxval = 100, step = 5) trade_both = "Both", trade_long = "Long", trade_short = "Short" trade_direction = input("Both", title = "Trade - Direction", options = [trade_both, trade_long, trade_short]) trade_leverage = input(2, title = "Trade - Leverage", type = input.integer, minval = 1, maxval = 100) trade_stop = input(7.5, title = "Trade - Stop Loss %", type = input.float, minval = 0.5, step = 0.5, maxval = 100) trade_trail_threshold = input(5, title = "Trade - Trail Stop Threshold %", type = input.float, minval = 0.5, step = 0.5, maxval = 100) trade_trail = input(5, title = "Trade - Trail Stop Minimum %", type = input.float, minval = 0.5, step = 0.5, maxval = 100) trade_risk = input(100, title = "Trade - Risk %", type = input.integer, step = 1, minval = 1, maxval = 100) test_year = input(2019, "Test - Year", type = input.integer, minval = 1970, maxval = 2222) test_month = input(01, "Test - Month", type = input.integer, minval = 1, maxval = 12) test_day = input(01, "Test - Day", type = input.integer, minval = 1, maxval = 31) // Functions get_round(value, precision) => round(value * (pow(10, precision))) / pow(10, precision) get_obv(values, filter_length, filter_multiplier, use_filter, osc_length, use_osc) => threshold = abs(avg(volume, filter_length) - (stdev(volume, filter_length) * filter_multiplier)) obv = 0.0 if (use_filter and volume < threshold) obv := nz(obv[1]) else obv := nz(obv[1]) + sign(change(values)) * volume use_osc ? (obv - ema(obv, osc_length)) : obv get_dc(high_values, low_values, length) => top = highest(high_values, length) bot = lowest(low_values, length) mid = bot + ((top - bot) / 2) [top, mid, bot] get_dcs(high_values, low_values, length, length_percent) => slow_length = length fast_length = slow_length * length_percent / 100 [slow_top, slow_mid, slow_bot] = get_dc(high_values, low_values, slow_length) [fast_top, fast_mid, fast_bot] = get_dc(high_values, low_values, fast_length) [slow_top, slow_mid, slow_bot, fast_top, fast_mid, fast_bot] // Strategy obv = get_obv( source, vol_filter_length, vol_filter_multiplier, use_volume_filter, osc_length, use_osc) [slow_top_price, _, slow_bot_price, fast_top_price, _, fast_bot_price] = get_dcs(high, low, channel_length, channel_percent) [slow_top_obv, _, slow_bot_obv, fast_top_obv, _, fast_bot_obv] = get_dcs(obv, obv, channel_length, channel_percent) enter_long_price = high > slow_top_price[1] exit_long_price = low < fast_bot_price[1] enter_short_price = low < slow_bot_price[1] exit_short_price = high > fast_top_price[1] enter_long_obv = obv > slow_top_obv[1] and (use_osc ? obv > 0 : true) enter_short_obv = obv < fast_bot_obv[1] and (use_osc ? obv < 0 : true) exit_long_obv = obv < slow_bot_obv[1] exit_short_obv = obv > fast_top_obv[1] // Trade Conditions can_trade = true enter_long_condition = enter_long_obv and enter_long_price exit_long_condition = exit_long_obv and exit_long_price enter_short_condition = enter_short_obv and enter_short_price exit_short_condition = exit_short_obv and exit_short_price position_signal = 0 position_signal := enter_long_condition ? 1 : enter_short_condition ? -1 : exit_long_condition or exit_short_condition ? 0 : position_signal[1] // Positions test_time = timestamp(test_year, test_month, test_day, 0, 0) if (time >= test_time and strategy.opentrades == 0) contracts = get_round((strategy.equity * trade_leverage / close) * (trade_risk / 100), 4) if (trade_direction == trade_both or trade_direction == trade_long) strategy.entry( "LONG", strategy.long, qty = contracts, when = enter_long_condition) if (trade_direction == trade_both or trade_direction == trade_short) strategy.entry( "SHORT", strategy.short, qty = contracts, when = enter_short_condition) in_long = strategy.position_size > 0 in_short = strategy.position_size < 0 float long_high = na float short_low = na long_high := in_long ? high >= nz(long_high[1], low) ? high : long_high[1] : na short_low := in_short ? low <= nz(short_low[1], high) ? low : short_low[1] : na long_change = abs(((long_high - strategy.position_avg_price) / strategy.position_avg_price) * 100) short_change = abs(((short_low - strategy.position_avg_price) / strategy.position_avg_price) * 100) threshold_difference = (strategy.position_avg_price / trade_leverage) * (trade_trail_threshold / 100) long_trail_threshold = in_long ? strategy.position_avg_price + threshold_difference : na short_trail_threshold = in_short ? strategy.position_avg_price - threshold_difference : na long_trail = in_long and long_high > long_trail_threshold ? long_high - (long_high / trade_leverage) * (trade_trail / 100) : na short_trail = in_short and short_low < short_trail_threshold ? short_low + (short_low / trade_leverage) * (trade_trail / 100) : na stop_difference = (strategy.position_avg_price / trade_leverage) * (trade_stop / 100) long_stop = in_long ? long_high > long_trail_threshold ? long_trail : strategy.position_avg_price - stop_difference : na short_stop = in_short ? short_low < short_trail_threshold ? short_trail : strategy.position_avg_price + stop_difference : na strategy.exit("S/L", "LONG", stop = long_stop, qty = abs(get_round(strategy.position_size, 4))) strategy.exit("S/L", "SHORT", stop = short_stop, qty = abs(get_round(strategy.position_size, 4))) strategy.close_all(when = abs(change(position_signal)) > 0) // Plots plotshape(enter_long_condition, "Enter Long", shape.diamond, location.top, color.green) plotshape(exit_long_condition, "Exit Long", shape.diamond, location.top, color.red) plotshape(enter_short_condition, "Enter Short", shape.diamond, location.bottom, color.green) plotshape(exit_short_condition, "Exit Short", shape.diamond, location.bottom, color.red) color_green = #63b987 color_red = #eb3d5c hline(use_osc ? 0 : na) plot(use_osc ? obv : na, color = color.silver, style = plot.style_area, transp = 90) plot(obv, color = color.white, style = plot.style_line, linewidth = 2, transp = 0) plot_slow_top = plot(slow_top_obv, color = color_green, linewidth = 2, transp = 60) plot_slow_bot = plot(slow_bot_obv, color = color_green, linewidth = 2, transp = 60) fill(plot_slow_top, plot_slow_bot, color = color_green, transp = 90) plot_fast_top = plot(fast_top_obv, color = color_red, linewidth = 2, transp = 60) plot_fast_bot = plot(fast_bot_obv, color = color_red, linewidth = 2, transp = 60) fill(plot_fast_top, plot_fast_bot, color = color_red, transp = 90)