Estratégia de negociação de alta-aberta

Autora:ChaoZhang, Data: 2023-10-18 11:22:57
Tags:

img

Resumo

Esta estratégia gera sinais de negociação baseados no cruzamento entre preços abertos e altos. Ele vai longo quando o preço aberto cruza acima do preço alto e vai curto quando o preço aberto cruza abaixo do preço alto. As médias móveis podem ser usadas para suavizar os dados de preços e reduzir os negócios ruidosos. Vários tipos e parâmetros de médias móveis são configuráveis.

Estratégia lógica

  1. Determine se deve utilizar uma resolução alternativa com base no parâmetro de entrada useRes. Se habilitado, defina a resolução com stratRes.

  2. Decidir se deve utilizar a média móvel (useMA) com base no parâmetro de entrada.

  3. Obter dados de séries de preço aberto (aberto) e preço fechado (fechado). Aplicar MA selecionado com parâmetros configurados se useMA habilitado.

  4. Compare o preço aberto atual x com a série aberta openSeries. Se x for maior que openSeries, defina o trendState para longo, caso contrário para curto.

  5. Gerar sinal longo longCond quando o preço aberto cruza acima da série MA aberta. Gerar sinal curto shortCond quando o preço aberto cruza abaixo da série MA aberta.

  6. Introduza posições longas ou curtas com base em sinais longos e curtos.

Vantagens

  1. Utiliza duas séries de preços diferentes, aberta e alta, evitando as limitações de uma única série.

  2. As técnicas de MA filtram o ruído a curto prazo e concentram-se na tendência principal.

  3. Configuração flexível dos tipos e parâmetros de MA para um efeito óptimo.

  4. Opção de stop loss para controlar o risco e garantir os lucros.

  5. Alto espaço de otimização para ajustar parâmetros para diferentes produtos e ambientes de mercado.

Riscos

  1. Uma única fonte de sinal leva a sinais escassos e a negociações potencialmente perdidas.

  2. O atraso da MA pode resultar em oportunidades perdidas a curto prazo.

  3. A configuração inadequada de stop loss pode conduzir a uma saída prematura ou a um excesso de perda.

  4. A má afinação dos parâmetros pode causar trocas fictícias excessivas que afetam a performance ao vivo.

  5. A otimização de parâmetros é um desafio para diferentes produtos e ambientes.

  6. Adicionar mais indicadores ou modelos de ML para enriquecer fontes de sinal. Ajustar os tipos e parâmetros MA. Definir stop loss cuidadosamente com algum buffer para capturar mais lucro. Testar e otimizar os parâmetros.

Orientações de otimização

  1. Incorporar indicadores adicionais como Bandas de Bollinger, KD etc. para expandir as fontes de sinal.

  2. Aplicar modelos de aprendizagem de máquina para geração de sinais.

  3. Otimizar os parâmetros MA para encontrar as melhores configurações.

  4. Equilíbrio dos níveis de stop loss entre o risco e a captura de lucros.

  5. Adicione métodos de otimização de parâmetros para encontrar automaticamente configurações ótimas.

  6. Desenvolver modelos de parâmetros especializados para diferentes produtos.

  7. Construir quadros de backtesting quantitativo para iterações rápidas de estratégia.

Resumo

Esta estratégia gera sinais baseados em crossovers abertos e altos e usa MA para filtrar ruído. Oferece flexibilidade através de parâmetros configuráveis. A estratégia tem vantagens, mas também alguns problemas como sinais escassos e lag. Mais melhorias podem ser feitas através de mais indicadores, modelos de aprendizado de máquina, etc. É necessário ajuste e otimização de parâmetros extensivos para o melhor desempenho em diferentes produtos e ambientes de mercado.


/*backtest
start: 2022-10-17 00:00:00
end: 2023-10-17 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2

//strategy(title = "Open Close Cross Strategy", shorttitle = "OCC Strategy", overlay = true, pyramiding = 0, default_qty_type = strategy.percent_of_equity, default_qty_value = 10)

// Revision:        1
// Author:          @JayRogers
//
// Description:
//  - Strategy based around Open-Close Crossovers.
// Setup:
//  - I have generally found that setting the strategy resolution to 3-4x that of the chart you are viewing
//    tends to yield the best results, regardless of which MA option you may choose (if any)
//  - Don't aim for perfection. Just aim to get a reasonably snug fit with the O-C band, with good runs of
//    green and red.
//  - Option to either use basic open and close series data, or pick your poison with a wide array of MA types.
//  - Optional trailing stop for damage mitigation if desired (can be toggled on/off)
//  - Positions get taken automagically following a crossover - which is why it's better to set the resolution
//    of the script greater than that of your chart, so that the trades get taken sooner rather than later.
//  - If you make use of the trailing stops, be sure to take your time tweaking the values. Cutting it too fine
//    will cost you profits but keep you safer, while letting them loose could lead to more drawdown than you
//    can handle.

// === INPUTS ===
useRes      = input(defval = true, title = "Use Alternate Resolution? ( recommended )")
stratRes    = input(defval = "120", title = "Set Resolution ( should not be lower than chart )")
useMA       = input(defval = true, title = "Use MA? ( otherwise use simple Open/Close data )")
basisType   = input(defval = "DEMA", title = "MA Type: SMA, EMA, DEMA, TEMA, WMA, VWMA, SMMA, HullMA, LSMA, ALMA ( case sensitive )")
basisLen    = input(defval = 14, title = "MA Period", minval = 1)
offsetSigma = input(defval = 6, title = "Offset for LSMA / Sigma for ALMA", minval = 0)
offsetALMA  = input(defval = 0.85, title = "Offset for ALMA", minval = 0, step = 0.01)
useStop     = input(defval = true, title = "Use Trailing Stop?")
slPoints    = input(defval = 200, title = "Stop Loss Trail Points", minval = 1)
slOffset    = input(defval = 400, title = "Stop Loss Trail Offset", minval = 1)
// === /INPUTS ===

// === BASE FUNCTIONS ===
// Returns MA input selection variant, default to SMA if blank or typo.
variant(type, src, len, offSig, offALMA) =>
    v1 = sma(src, len)                                                  // Simple
    v2 = ema(src, len)                                                  // Exponential
    v3 = 2 * v2 - ema(v2, len)                                          // Double Exponential
    v4 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len)               // Triple Exponential
    v5 = wma(src, len)                                                  // Weighted
    v6 = vwma(src, len)                                                 // Volume Weighted
    v7 = na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len    // Smoothed
    v8 = wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len)))   // Hull
    v9 = linreg(src, len, offSig)                                       // Least Squares
    v10 = alma(src, len, offALMA, offSig)                               // Arnaud Legoux
    type=="EMA"?v2 : type=="DEMA"?v3 : type=="TEMA"?v4 : type=="WMA"?v5 : type=="VWMA"?v6 : type=="SMMA"?v7 : type=="HullMA"?v8 : type=="LSMA"?v9 : type=="ALMA"?v10 : v1
// security wrapper for repeat calls
reso(exp, use, res) => use ? request.security(syminfo.tickerid, res, exp) : exp
// === /BASE FUNCTIONS ===

// === SERIES SETUP ===
// open/close
//closeSeries = useMA ? reso(variant(basisType, close, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(close, useRes, stratRes)
openSeries  = useMA ? reso(variant(basisType, open, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(open, useRes, stratRes)
x = openSeries[1]
trendState  = x > openSeries ? true : x < openSeries ? false : trendState[1]
// === /SERIES ===

// === PLOTTING ===
barcolor(color = x > openSeries ? #006600 : #990000, title = "Bar Colours")
// channel outline
closePlot   = plot(x, title = "Close Line", color = #009900, linewidth = 2, style = line, transp = 90)
openPlot    = plot(openSeries, title = "Open Line", color = #CC0000, linewidth = 2, style = line, transp = 90)
// channel fill
closePlotU  = plot(trendState ? x : na, transp = 100, editable = false)
openPlotU   = plot(trendState ? openSeries : na, transp = 100, editable = false)
closePlotD  = plot(trendState ? na : x, transp = 100, editable = false)
openPlotD   = plot(trendState ? na : openSeries, transp = 100, editable = false)
fill(openPlotU, closePlotU, title = "Up Trend Fill", color = #009900, transp = 40)
fill(openPlotD, closePlotD, title = "Down Trend Fill", color = #CC0000, transp = 40)
// === /PLOTTING ===

// === STRATEGY ===
// conditions
longCond    = crossover(openSeries, x)
shortCond   = crossunder(openSeries, x)
// entries and base exit
strategy.entry("long", true, when = longCond)
strategy.entry("short", false, when = shortCond)
// if we're using the trailing stop
//if (useStop)
//    strategy.exit("XL", from_entry = "long", trail_points = slPoints, trail_offset = slOffset)
//    strategy.exit("XS", from_entry = "short", trail_points = slPoints, trail_offset = slOffset)
// not sure needed, but just incase..
//strategy.exit("XL", from_entry = "long", when = shortCond)
//strategy.exit("XS", from_entry = "short", when = longCond)
// === /STRATEGY ===

Mais.