Длинная и короткая двунаправленная торговая стратегия, основанная на длинных и коротких сигналах количественных индикаторов


Дата создания: 2023-12-13 17:30:13 Последнее изменение: 2023-12-13 17:30:13
Копировать: 0 Количество просмотров: 690
1
Подписаться
1621
Подписчики

Длинная и короткая двунаправленная торговая стратегия, основанная на длинных и коротких сигналах количественных индикаторов

Обзор

Эта стратегия является двунаправленной стратегией торговли, основанной на многополосных сигналах, генерируемых Donchain Price Channel Indicator и количественным OBV Oscillator. Она использует индикатор ценового канала для определения ценовых прорывов и отклонений, в сочетании с количественными индикаторами для определения многополосных сил, для создания торговых сигналов.

Стратегический принцип

  1. Используйте индикатор ценового канала Donchain для определения ценового потока вверх и вниз. Ценовой канал вверх рассчитывается по наивысшей цене, а низкий канал - по наименьшей цене.

  2. Используйте количественные показатели OBV и показатели EMA, чтобы построить OBV-ассилятор для определения воздушной силы. Когда осциллятор больше 0, то многоголовое силы рассматривается как больше, чем воздушной силы, а меньше, чем 0, наоборот.

  3. При прорыве цены в верхнем канале и большом количестве колебателей, появляются многосигналы; при прорыве цены в нижнем канале и меньшем количестве колебателей, появляются пустые сигналы.

  4. Когда цена возвращается в нижний канал, она становится более низкой; когда цена возвращается в верхний канал, она становится более низкой.

Стратегические преимущества

  1. Используйте ценовые каналы для оценки тенденций, чтобы избежать ошибочного восприятия шокового тренда.

  2. В сочетании с количественными показателями, чтобы оценить силу воздушного пространства, убедитесь, что направление торговли соответствует рыночной силе.

  3. При использовании двусторонних сделок вы можете получать прибыль, независимо от того, растет или падает рынок.

  4. Установка стратегии сдерживания убытков, эффективное управление рисками

Стратегический риск

  1. Неправильная настройка параметров ценового канала может привести к тому, что канал станет слишком широким или слишком узким, пропустят торговые возможности или получат ошибочные сигналы.

  2. Неправильная настройка параметров индикатора также может привести к задержке или предварительному появлению сигнала.

  3. Внезапные события, вызванные быстрой аномалией, могут привести к убыткам.

  4. Двухсторонние сделки требуют одновременного управления как позицией, находящейся в плюсе, так и позицией, находящейся в минусе.

Направление оптимизации стратегии

  1. Оптимизация параметров ценового канала, чтобы найти оптимальную комбинацию параметров.

  2. Оптимизация параметров OBV-осцилляторов также должна быть проверена, чтобы обеспечить своевременное и точное определение гипертензии.

  3. Для определения рыночных тенденций можно использовать другие индикаторы, такие как MACD, KD и т. д., чтобы повысить точность сигналов.

  4. Можно проверить эффективность различных методов остановки, таких как отслеживание остановки, процентное остановка и т. д.

  5. Можно тестировать разные сорта, чтобы найти наиболее подходящие для этой стратегии.

Подвести итог

Стратегия в целом является двунаправленной торговой стратегией, в то же время в сочетании с ценовыми событиями и количественными показателями определяет рыночные тенденции и многолетние силы. Стратегическая идея ясна и понятна.

Исходный код стратегии
/*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)