Sistema de rastreamento de tendências de reequilíbrio de posição dinâmico

Autora:ChaoZhang, Data: 2024-01-26 14:41:08
Tags:

img

Resumo

Esta estratégia integra o sistema de cruzamento de média móvel exponencial e o sistema de negociação de tartaruga, duas estratégias de negociação sistemática populares.

Estratégia lógica

A estratégia contém duas sub-estratégias: estratégia de tendência e estratégia de ruptura.

A estratégia de tendência usa EMA rápida e crossovers de EMA lenta como sinais de negociação. O período de EMA rápida é definido pelo usuário e o período de EMA lenta é 5 vezes a EMA rápida. O sinal é gerado dividindo a diferença de EMA pelo desvio padrão de retorno de 252 períodos, que é ajustado à volatilidade para produzir sinais mais confiáveis.

A estratégia de breakout usa a média dos preços mais altos e mais baixos em um período de retrospectiva fixo como linha de base.

O dimensionamento da posição é baseado na volatilidade recente dos preços e no alvo de risco anual definido pelo usuário.

As paradas duras são definidas como múltiplos da faixa média verdadeira.

Análise das vantagens

As principais vantagens desta estratégia incluem:

  1. A combinação de sub-estratégias de rastreamento de tendências e de ruptura adapta-se a diferentes ambientes de mercado com forte robustez.

  2. A aplicação de técnicas avançadas de dimensionamento das posições e de gestão de riscos permite gerir dinamicamente a posição e controlar eficazmente o risco.

  3. As posições ajustadas à volatilidade com base na volatilidade recente e no risco anual-alvo mantêm um risco de carteira relativamente estável em regimes de alta/baixa volatilidade.

  4. A definição de stop loss com base na flutuação real dos preços evita perdas pequenas desnecessárias de stop runs.

  5. Ajustar o trailing stop em tempo real de forma flexível segue as tendências para registar lucros e para fora em tempo hábil.

Análise de riscos

Os principais riscos desta estratégia são:

  1. Confiança na otimização de parâmetros: diferentes parâmetros afetam consideravelmente o desempenho da estratégia, por isso é necessário um teste abrangente para encontrar parâmetros ideais.

  2. A largura da perda de parada pode ser relaxada e os mecanismos de parada optimizados.

  3. Sensibilidade ao capital inicial e aos custos de negociação: o capital inicial insuficiente e os elevados custos de negociação têm um impacto negativo na rendibilidade.

  4. Confiança em estimativas precisas de volatilidade para dimensionamento de posições e controlos de risco.

Orientações de otimização

As principais direcções de otimização incluem:

  1. Procure por conjuntos de parâmetros ideais através de mais backtesting com um conjunto de dados histórico maior.

  2. Melhorar os mecanismos de parada testando várias paradas como paradas em movimento, paradas de tempo, paradas de volatilidade, etc.

  3. Otimizar o dimensionamento das posições e a gestão do risco, testando diferentes alvos de risco para encontrar o melhor perfil de risco-retorno.

  4. Tente mais indicadores auxiliares para melhorar a precisão do sinal e a robustez da estratégia.

  5. Testar diferentes períodos de retenção, auxiliando as decisões com sinais de prazo mais longo para melhorar a precisão da alocação de posições.

Conclusão

Esta estratégia integra duas grandes categorias de estratégias de negociação: tendência seguindo e breakouts. Aplicando técnicas avançadas de ajuste de posição dinâmica, ele efetivamente controla o risco enquanto acompanha os movimentos do mercado para o lucro. Demonstra forte potencial de lucro e vale a pena testar e otimizar ainda mais.


/*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)

Mais.