
이 전략은 Donchain 가격 채널 지표와 양적 지표 OBV 진동기가 생성하는 다공이 신호를 기반으로 양방향 거래를 하는 전략이다. 그것은 가격 채널 지표를 사용하여 가격 돌파구를 판단하고 회귀를 결정하고 양적 지표와 결합하여 다공이 힘을 판단하여 거래 신호를 생성한다.
돈체인 (Donchain) 가격 채널 지표를 사용하여 가격의 상하 채널을 판단한다. 가격의 상하 채널은 최고 가격으로 계산되고, 하하 채널은 최저 가격으로 계산된다.
OBV 계량 지표와 EMA 지표를 사용하여 OBV 진동기를 구성하여 공중력을 판단한다. 진동기가 0보다 크면 공중력보다 큰 다중력으로 간주되며 0보다 작으면 반대로 본다.
가격이 상류 채널을 뚫고 진동기가 0보다 크면 다중 신호가 발생하고, 가격이 하류 채널을 뚫고 진동기가 0보다 작으면 공백 신호가 발생한다.
가격이 하향 채널로 회귀할 때 평점 포지션을 상점으로; 가격이 상향 채널로 회귀할 때 평점 포지션을 상점으로 한다.
가격 채널을 사용하여 추세를 판단하여 변동 현상을 오해하지 마십시오.
양적 지표와 함께 다공력 판단을 통해 거래 방향이 시장력과 일치하는지 확인한다.
양방향 거래는 시장이 상승하거나 하락하더라도 수익을 창출할 수 있습니다.
스탠포드 대학 (University of Maryland) 에서 재학 중인 학생입니다.
가격 통로 파라미터를 잘못 설정하면 통로가 너무 느슨하거나 너무 좁아지고 거래 기회가 놓쳐지거나 잘못된 신호가 발생할 수 있습니다.
지표 매개 변수 설정이 잘못되면 신호가 지연되거나 조기 발생하기도 한다.
급격한 비정상적인 사고로 인한 갑작스러운 사고는 손해배상 청구서를 유발할 수 있습니다.
양방향 거래는 동시에 관리해야 하는 과잉 거래와 적폐 거래의 경우, 운영의 어려움이 더 크다.
가격 통로 매개 변수를 최적화하여 최적의 매개 변수 조합을 찾습니다.
OBV 진동기 파라미터를 테스트하고 최적화하여 다공력 (多空力) 을 적시에 정확하게 판단할 수 있도록 한다.
MACD, KD 등과 같은 다른 지표와 결합하여 시장 추세를 판단하여 신호 정확도를 향상시킬 수 있습니다.
다른 방법으로도 효과를 테스트할 수 있습니다. 예를 들어, 손실 추적, 손실 비율 등입니다.
다양한 품종을 테스트하여 이 전략에 가장 적합한 품종을 찾을 수 있습니다.
이 전략은 전체적으로 양방향 거래 전략이며, 가격 행태와 양적 지표와 결합하여 시장 추세와 다공간 힘을 판단하는 전략 아이디어는 명확하고 이해하기 쉽습니다. 최적화 공간도 상대적으로 넓으며, 매개 변수 최적화 및 지표 조합을 통해 전략의 안정성과 수익성을 향상시킬 수 있습니다.
/*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)