Динамическая система отслеживания тенденций с перебалансировкой позиции

Автор:Чао Чжан, Дата: 2024-01-26 14:41:08
Тэги:

img

Обзор

Эта стратегия объединяет экспоненциальную скользящую среднюю кроссоверную систему и торговой системы черепахи, две популярные систематические торговые стратегии.

Логика стратегии

Стратегия содержит две подстратегии: стратегию тренда и стратегию выхода.

Тенденционная стратегия использует быструю EMA и медленные перекрестки EMA в качестве торговых сигналов. Быстрый период EMA определяется пользователем, а медленный период EMA составляет 5 раз быструю EMA. Сигнал генерируется путем деления разницы EMA на стандартное отклонение возврата 252 периода, которое скорректировано по волатильности для получения более надежных сигналов. Он длится или короче при обнаружении новых формирований тренда.

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

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

Твердые остановки устанавливаются как кратные среднему истинному диапазону.

Анализ преимуществ

К основным преимуществам этой стратегии относятся:

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

  2. Применение передовых методов размещения позиций и управления рисками позволяет динамически управлять позициями и эффективно контролировать риск.

  3. Позиции с корректировкой волатильности на основе недавней волатильности и годовой целевой ставки риска поддерживают относительно стабильный риск портфеля в режимах высокой/низкой волатильности.

  4. Установка стоп-лосса на основе фактических колебаний цен позволяет избежать ненужных небольших потерь от стоп-лосса.

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

Анализ рисков

Основными рисками этой стратегии являются:

  1. Разнообразные параметры значительно влияют на эффективность стратегии, поэтому для поиска оптимальных параметров необходимо всестороннее тестирование.

  2. Частые остановки в колеблющихся тенденциях.

  3. Чувствительность к начальному капиталу и затратам на торговлю. Недостаточный начальный капитал и высокие затраты на торговлю негативно влияют на прибыльность.

  4. Неточные оценки волатильности приводят к чрезмерному или недостаточному размеру позиций.

Руководство по оптимизации

К основным направлениям оптимизации относятся:

  1. Поиск оптимальных наборов параметров с помощью большего обратного тестирования с большим историческим набором данных.

  2. Улучшить механизмы остановки путем тестирования различных остановок, таких как движущиеся остановки, временные остановки, остановки волатильности и т.д.

  3. Оптимизировать размещение позиций и управление рисками путем тестирования различных целей риска для поиска наилучшего профиля риска и доходности.

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

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

Заключение

Эта стратегия объединяет две основные категории торговых стратегий: следующие за трендом и прорывы. Применяя передовые методы динамической корректировки позиций, она эффективно контролирует риск при отслеживании движения рынка к прибыли. Она демонстрирует сильный потенциал прибыли и стоит дальнейшего тестирования и оптимизации.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
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/
// © Crunchster1

//@version=5
strategy(title="Crunchster's Turtle and Trend System", shorttitle="Turtle Trend", overlay=true, slippage=10, pyramiding=1, precision = 4, calc_on_order_fills = false, calc_on_every_tick = false, default_qty_value = 0.1, initial_capital = 1000, commission_value = 0.06, process_orders_on_close = true)

// Inputs and Parameters
src = input(close, 'Source', group='Strategy Settings')
length = input.int(title="Lookback period for fast EMA", defval=10, minval=2, group='Strategy Settings', tooltip='This sets the lookback period for the fast exponential moving average. The slow EMA is 5x the fast EMA length')
blength = input.int(title="Lookback period for Breakout", defval=20, minval=5, step=5, group='Strategy Settings')

long = input(true, 'Long', inline='08', group='Strategy toggle')
short = input(true, 'Short', inline='08', group='Strategy toggle', tooltip='Toggle long/short strategy on/off')

EMAwt = input(false, 'Trend', inline='01', group='Strategy toggle')
breakwt = input(true, 'Breakout', inline='01', group='Strategy toggle', tooltip='Toggle trend/breakout strategy on/off')

stopMultiple = input.float(2, 'Stop multiple', step=0.5, group='Risk Management Settings', tooltip='Multiple for ATR, setting hard stop loss from entry price')
trail = input.int(10, 'Trail lookback', step=5, group='Risk Management Settings', tooltip='Lookback period for the trailing stop')
lev = input.float(1, 'Max Leverage', step=0.5, group='Risk Management Settings', tooltip='Max leverage sets maximum allowable leverage of total capital (initial capital + any net profit), capping maximum volatility adjusted position size')
riskT = input.float(15, maxval=75, title='Annualised Volatility Target %', group='Risk Management Settings', tooltip='Specify annual risk target, used to determine volatility adjusted position size. Annualised daily volatility is referenced to this value and position size adjusted accordingly')
comp = input(true, 'Compounding', inline='09', group='Risk Management Settings')
Comppct = input.float(50, '%', step=5, inline='09', group='Risk Management Settings', tooltip='Toggle compounding of profit, and set % of profit to compound')

// Backtesting period
FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31, inline='04', group='Backtest range')
FromMonth = input.int(defval=1, title='From Mon', minval=1, maxval=12, inline='04', group='Backtest range')
FromYear = input.int(defval=2018, title='From Yr', minval=1900, inline='04', group='Backtest range', tooltip='Set start of backtesting period')
ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31, inline='05', group='Backtest range')
ToMonth = input.int(defval=1, title='To Mon', minval=1, maxval=12, inline='05', group='Backtest range')
ToYear = input.int(defval=9999, title='To Yr', minval=1900, inline='05', group='Backtest range', tooltip='Set end of backtesting period')

start = timestamp(FromYear, FromMonth, FromDay, 00, 00)
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)
window = time >= start and time <= finish

// Breakout strategy
lower = ta.lowest(low[1], blength)
upper = ta.highest(high[1], blength)
basis = math.avg(upper, lower)
signal = 20*(close - basis) / (upper - lower)

// Trend strategy
fEMA = ta.ema(close[1], length)
sEMA = ta.ema(close[1], length*5)
emadiff = fEMA - sEMA
nemadiff = 5*emadiff/(ta.stdev(close - close[1], 252))

//Risk Management formulae
strategy.initial_capital = 50000
tr = math.max(high - low, math.abs(high - close), math.abs(low - close)) //True range
stopL = ta.sma(tr, 14) //Average true range
stdev = ta.stdev(close-close[1], 14) //volatility of recent returns
maxcapital = strategy.initial_capital+strategy.netprofit //Maximum capital available to invest - initial capital net of profit
annvol = 100*math.sqrt(365)*stdev/close //converts recent volatility of returns into annualised volatility of returns - assumes daily timeframe

risk = 1.1
if comp
    risk := (strategy.initial_capital+(Comppct*strategy.netprofit/100))//adjust investment capital to include compounding
else
    risk := strategy.initial_capital

shares = (risk * (riskT/annvol)) / close //calculates volatility adjusted position size, dependent on user specified annualised risk target
if ((shares*close) > lev*maxcapital) //ensures position size does not exceed available capital multiplied by user specified maximum leverage
    shares := lev*maxcapital/close

//To set the price at the entry point of trade
Posopen() =>
    math.abs(strategy.position_size[1]) <= 0 and math.abs(strategy.position_size) > 0

var float openN = na
if Posopen()
    openN := stopL

// Trailing stop
tlower = ta.lowest(low[1], trail)
tupper = ta.highest(high[1], trail)
tbasis = math.avg(tupper, tlower)
tsignal = 20*(close - tbasis) / (tupper - tlower)

// Strategy Rules
if EMAwt
    if long
        longCondition2 = (nemadiff >2 and nemadiff[1] <2) and window
        exitlong = tsignal <= -10
        if (longCondition2)
            strategy.entry('Trend Long!', strategy.long, qty=shares)
        if strategy.position_size > 0    
            strategy.exit('Stop Long', from_entry = 'Trend Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
        if (exitlong)
            strategy.close('Trend Long!', immediately = true)

    if short
        shortCondition2 = (nemadiff <-1 and nemadiff[1] >-1) and window
        exitshort = tsignal >= 10
        if (shortCondition2)
            strategy.entry('Trend Short!', strategy.short, qty=shares)
        if strategy.position_size < 0   
            strategy.exit('Stop Short', from_entry = 'Trend Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
        if (exitshort)
            strategy.close('Trend Short!', immediately = true)

if breakwt
    if long
        longCondition1 = (signal >= 10) and window
        exitlong = tsignal <= -10
        if (longCondition1)
            strategy.entry('Break Long!', strategy.long, qty=shares)
        if strategy.position_size > 0    
            strategy.exit('Stop Long', from_entry = 'Break Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
        if (exitlong)
            strategy.close('Break Long!', immediately = true)

    if short
        shortCondition1 = (signal <= -10) and window
        exitshort = tsignal >= 10
        if (shortCondition1)
            strategy.entry('Break Short!', strategy.short, qty=shares)
        if strategy.position_size < 0   
            strategy.exit('Stop Short', from_entry = 'Break Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
        if (exitshort)
            strategy.close('Break Short!', immediately = true)

// Visuals of trend and direction
plot(nemadiff, title='EMA Forecast', color=color.black, display=display.none)
plot(ta.sma(ta.median(math.sqrt(math.pow(nemadiff,2)), 700), 350), 'Forecast mean', color=color.rgb(245, 0, 0), display=display.none)

MAColor = fEMA > sEMA ? #00ff00 : #ff0000
MA1 = plot(fEMA, title='Fast EMA', color=MAColor)
MA2 = plot(sEMA, title='Slow EMA', color=MAColor)
fill(MA1, MA2, title='Band Filler', color=MAColor)

Больше