Strategi ini berdasarkan isyarat menaik dan menurun yang dihasilkan oleh penunjuk saluran harga Donchain dan penunjuk kuantitatif osilator OBV untuk perdagangan dua arah. Ia menggunakan penunjuk saluran harga untuk menilai pecah harga dan penurunan, digabungkan dengan penunjuk kuantitatif untuk menentukan kekuatan menaik dan menurun, untuk menghasilkan isyarat perdagangan.
Gunakan penunjuk saluran harga Donchain untuk menentukan saluran harga atas dan bawah. Saluran atas dikira dari harga tertinggi dan saluran bawah dari harga terendah.
Membina pengayun OBV menggunakan penunjuk kuantitatif OBV dan penunjuk EMA untuk menentukan kekuatan kenaikan dan penurunan. Nilai pengayun yang lebih besar daripada 0 menunjukkan kekuatan kenaikan melebihi kekuatan penurunan, dan sebaliknya jika kurang daripada 0.
Isyarat panjang dihasilkan apabila harga menembusi saluran atas dan osilator lebih besar daripada 0; Isyarat pendek dihasilkan apabila harga menembusi saluran bawah dan osilator kurang daripada 0.
Tutup kedudukan panjang apabila harga menarik balik ke saluran bawah; Tutup kedudukan pendek apabila harga menarik balik ke saluran atas.
Menggunakan saluran harga untuk menentukan trend mengelakkan ditipu oleh pasaran turun naik.
Memasukkan penunjuk kuantitatif untuk menilai kekuatan kenaikan dan penurunan memastikan arah perdagangan adalah konsisten dengan kekuatan pasaran.
Menggunakan perdagangan dua arah membolehkan keuntungan sama ada pasaran naik atau jatuh.
Menetapkan strategi stop loss berkesan menguruskan risiko.
Tetapan parameter saluran harga yang tidak betul boleh menyebabkan saluran yang terlalu longgar atau sempit, kehilangan peluang perdagangan atau menghasilkan isyarat yang salah.
Tetapan parameter penunjuk yang tidak betul juga boleh menyebabkan penjanaan isyarat yang tertunda atau terlalu awal.
Pergerakan tidak normal yang tiba-tiba daripada peristiwa boleh mencetuskan stop loss yang membawa kepada kerugian.
Perdagangan dua arah memerlukan pengurusan kedua-dua kedudukan panjang dan pendek pada masa yang sama menjadikannya lebih sukar untuk beroperasi.
Mengoptimumkan parameter saluran harga untuk mencari kombinasi yang optimum.
Uji dan optimumkan parameter osilator OBV untuk memastikan penilaian yang tepat dan tepat mengenai kekuatan kenaikan / penurunan.
Pertimbangkan untuk menggabungkan penunjuk lain seperti MACD, KD dll untuk meningkatkan ketepatan isyarat.
Uji kaedah stop loss yang berlainan, contohnya, stop pengesanan, stop peratusan dan lain-lain.
Uji produk yang berbeza untuk mencari mana yang paling sesuai dengan strategi.
Secara keseluruhan, ini adalah strategi perdagangan dua arah yang jelas dan mudah difahami yang menggabungkan tindakan harga dan penunjuk kuantitatif untuk menentukan trend dan kekuatan pasaran.
/*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)