
Chiến lược này là một chiến lược giao dịch hai chiều dựa trên tín hiệu đa luồng được tạo ra bởi dao động OBV của chỉ số kênh giá Donchain và chỉ số định lượng. Nó sử dụng chỉ số kênh giá để xác định giá phá vỡ và điều chỉnh, kết hợp với chỉ số định lượng để xác định sức mạnh đa luồng, tạo ra tín hiệu giao dịch.
Sử dụng chỉ số kênh giá của Donchain để xác định kênh giá lên xuống. Các kênh giá trên được tính bằng giá cao nhất và các kênh dưới được tính bằng giá thấp nhất.
Sử dụng chỉ số định lượng OBV và chỉ số EMA để xây dựng một rung OBV để đánh giá lực không khí. Khi rung lớn hơn 0, lực không khí được coi là lớn hơn lực không khí và nhỏ hơn 0 thì ngược lại.
Khi giá phá vỡ kênh lên và dao động lớn hơn 0 tạo ra tín hiệu nhiều; Khi giá phá vỡ kênh xuống và dao động nhỏ hơn 0 tạo ra tín hiệu trống.
Khi giá quay trở lại kênh xuống, vị trí trục trặc được thực hiện; khi giá quay trở lại kênh lên, vị trí trục trặc được thực hiện.
Sử dụng các kênh giá để đánh giá xu hướng, tránh bị sai lệch bởi các biến động.
Kết hợp với các chỉ số định lượng để đánh giá sức mạnh không gian, đảm bảo hướng giao dịch phù hợp với sức mạnh thị trường.
Sử dụng giao dịch hai chiều, bạn có thể kiếm được lợi nhuận dù thị trường tăng hay giảm.
Thiết lập chiến lược ngăn chặn thiệt hại, kiểm soát rủi ro hiệu quả.
Cài đặt tham số kênh giá không đúng có thể dẫn đến việc kênh quá rộng hoặc quá hẹp, bỏ lỡ cơ hội giao dịch hoặc tạo ra tín hiệu sai.
Thiết lập tham số chỉ số không đúng cũng có thể gây ra tín hiệu bị chậm hoặc sớm.
Các sự kiện bất ngờ dẫn đến hành vi bất thường nhanh chóng có thể gây ra tổn thất do lệnh ngăn chặn.
Giao dịch hai chiều đòi hỏi phải quản lý đồng thời các vị trí mua bán và bán, điều hành khó khăn hơn.
Tối ưu hóa các tham số kênh giá để tìm ra sự kết hợp tốt nhất.
Các tham số của bộ rung OBV cũng được thử nghiệm và tối ưu hóa để đảm bảo tính chính xác và kịp thời của lực trên không.
Có thể xem xét kết hợp với các chỉ số khác như MACD, KD để đánh giá xu hướng thị trường, cải thiện độ chính xác của tín hiệu.
Có thể thử nghiệm hiệu quả của các phương pháp dừng khác nhau, chẳng hạn như theo dõi dừng, tỷ lệ dừng.
Có thể thử nghiệm các giống khác nhau để tìm những giống phù hợp nhất với chiến lược này.
Chiến lược này nói chung là một chiến lược giao dịch hai chiều, đồng thời kết hợp với hoạt động giá cả và các chỉ số định lượng để đánh giá xu hướng thị trường và sức mạnh đa chiều, tư duy chiến lược rõ ràng và dễ hiểu. Không gian tối ưu hóa cũng khá lớn, thông qua tối ưu hóa tham số và kết hợp các chỉ số cũng có thể tiếp tục nâng cao tính ổn định và lợi nhuận của chiến lược.
/*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)