
A principal ideia da estratégia é usar a ruptura da linha média do nível superior para realizar a negociação de tendências. No período de tempo do nível superior, quando o preço quebra a linha média para cima ou para baixo, pode-se determinar o início da tendência, que pode ser seguido na direção apropriada.
A estratégia foi desenvolvida através da linguagem Pine Script e tem como principais componentes:
Period é o parâmetro de período médio definido, com o valor padrão de 200; K é o parâmetro de período de tempo definido, com o valor padrão de dia “D”.
Calcule a média móvel exponencial usando a função ta.ema.
Use as funções ta.crossover e ta.crossunder para determinar se o preço quebra ou fica abaixo da linha média.
Quando ocorrer uma ruptura, trace uma seta para cima ou para baixo na linha K.
A brecha ocorre quando a posição é aberta de forma seletiva e a distância de stop-loss é duplicada e a posição é liquidada.
A estratégia baseia-se principalmente na capacidade de discernimento de tendências de nível superior, e é uma estratégia de ruptura mais tradicional, que permite o acompanhamento de tendências por meio de operações de ruptura simples.
A estratégia tem as seguintes vantagens:
O conceito é simples, fácil de entender e de dominar.
A regulação de parâmetros é simples, com base apenas em um indicador de linha média.
A operação de ruptura é fácil de criar tendências e não é frequente.
Os ciclos de alto nível mostram claramente as grandes tendências e não são facilmente afetados por oscilações de curto prazo.
É possível configurar diferentes combinações de períodos de tempo para diferentes variedades.
A maioria das espécies de peixes não são capturadas, mas podem ser facilmente rastreadas por várias espécies, o que dificulta a sua captura.
A estratégia também apresenta alguns riscos:
O mercado de criptomoedas é um mercado de criptomoedas, e os criptomoedas não são criptomoedas, mas criptomoedas.
Não é possível tirar proveito de oportunidades de curta duração.
A perda pode ser muito maior quando a direção erra em seu julgamento.
Quando o ciclo da linha média não coincide com o ciclo de negociação, ocorrem situações de excesso de negociação ou perda.
Não é possível parar os prejuízos em tempo real, e é mais provável que os prejuízos aumentem.
As soluções para o risco incluem: combinação de indicadores de tendência, aumento das condições de filtragem, redução apropriada do período de detenção, ajuste dinâmico da posição de parada, etc.
A estratégia pode ser melhorada nos seguintes aspectos:
Aumentar a combinação de indicadores de tendência, como MACD, KD, etc., para aumentar a confiabilidade da ruptura.
Aumentar o volume de transações ou condições de filtragem como o canal de linhas de Brin para evitar falsas brechas.
Optimizar a correspondência dos períodos de parâmetros para que os períodos de posse correspondam melhor aos períodos de tendência.
Aumentar as estratégias de stop loss em tempo real para controlar as perdas individuais por meio do rastreamento de stop loss.
Considere a otimização dinâmica dos parâmetros, combinando a tecnologia de aprendizagem de máquina.
Tente uma variedade de portfólios de distribuição de ativos para aumentar a estabilidade geral.
A estratégia é geralmente simples e prática, com um simples rompimento da linha de equilíbrio para realizar o acompanhamento da tendência, é fácil de dominar e pode ser usada como uma das estratégias de entrada para a negociação quantitativa. Mas também há alguns problemas que precisam ser melhorados por meio de indicadores combinados, parâmetros de otimização, stop loss dinâmico, etc., para tornar a estratégia mais estável e eficiente.
/*backtest
start: 2023-09-29 00:00:00
end: 2023-10-29 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// @version=5
// Open-Range-Breakout strategy
// No license. Free and Open Source.
strategy('Strategy: ORB', shorttitle="ORB", overlay=true , currency=currency.NONE, initial_capital=100000)
// Inputs
period = input.int(defval=15, title="TimeRange", tooltip="The range in minutes (default: 15m)")
sessionInput = input(defval="0915-0930", title="Time Range", group="ORB settings", tooltip='What is the timeperiod (default 9:15AM to 9:30AM, exchange timezone')
hide = input.bool(defval = false, title="Hide ORB Range", group="ORB setting", tooltip = 'Hide the ORB range drawing')
// SL Related
slAtrLen = input.int(defval=14, title="ATR Period for placing SL", group="StopLoss settings")
showSLLines = input.bool(defval=false, title="Show SL lines in chart", tooltip="Show SL lines also as dotted lines in chart. Note: chart may look untidy.", group="StopLoss settings")
// Further Filtering
ignoreMementumVolume = input.bool(defval=false, title="Ignore Momentum & Volume", tooltip="Ignore Momentum & Volume to find out trades", group="Strengh Settings")
rsiLen = input.int(defval=14, title="Momentum Period", group="Strengh Settings", tooltip = 'To determine the momentum, RSI period is set default to 100')
rsiBullish = input.int(defval=50, step=1, title="Bullish Momentum", group="Strengh Settings", tooltip = 'Bullish Momentum, default set to RSI as 50')
rsiBearish = input.int(defval=50, step=1, title="Bearish Momentum", group="Strengh Settings", tooltip = 'Bearish Momentum, default set to RSI as 50')
volAvg = input.int(defval=20, step=1, title="Volume Average Period", group="Strengh Settings", tooltip = 'To calculate average volume, how many historical bars are considered. Default: 20.')
volThreshold = input.float(defval=1, step=0.1, title="Volume Strengh", group="Strengh Settings", tooltip = 'Multiplier: How big the current bar volume compared to average of last 20')
trendPeriod = input.int(defval=200, step=1, title="Trend Period", group="Trend Settings", tooltip = 'To calculate trend, what period is considered. Default: 200.')
hideTrend = input.bool(defval = false, title="Hide the trend line", group="Trend Settings", tooltip = 'Hide the trend')
hidePDHCL = input.bool(defval = false, title="Hide the PDHCL (prev day High Close Low range)", tooltip = 'Hide the Previous Day High, Close, Low lines')
hideTable = input.bool(defval = false, title="Hide the Summary Table", tooltip = 'Hide the summary table.')
// Trade related
rrRatio = input.float(title='Risk:Reward', step=0.1, defval=2.0, group="Trade settings")
endOfDay = input.int(defval=1500, title="Close all trades, default is 3:00 PM, 1500 hours (integer)", group="Trade settings")
mktAlwaysOn = input.bool(defval=true, title="Markets that never closed (Crypto, Forex, Commodity)", tooltip="Some markers never closes. For those cases, make this checked.", group="Trade settings")
lotSize = input.int(title='Lot Size', step=1, defval=1, group="Trade settings")
// Util method
is_newbar(res) =>
timeframe.change(time(res)) != 0
// print table
printTable(txt) =>
var table t = table.new(position.bottom_right, 1, 1)
table.cell(t, 0, 0, txt, text_halign = text.align_left, bgcolor = color.lime)
// globals
t = time(timeframe.period, sessionInput + ":1234567") // everyday
in_session = not na(t)
is_first = in_session and not in_session[1]
is_end_session = in_session[1] and not in_session
green(open, close) => close > open ? true : false
red(open, close) => close < open ? true : false
var float orb_high = na
var float orb_low = na
if is_first
orb_high := high
orb_low := low
else
orb_high := orb_high[1]
orb_low := orb_low[1]
if high > orb_high and in_session
orb_high := high
if low < orb_low and in_session
orb_low := low
plot(hide ? na : orb_high, style=plot.style_line, color=orb_high[1] != orb_high ? na : color.green, title="ORB High", linewidth=2)
plot(hide ? na : orb_low, style=plot.style_line, color=orb_low[1] != orb_low ? na : color.red, title="ORB Low", linewidth=2)
// PDHCL (Previous Day High Close Low)
[dh,dl,dc] = request.security(syminfo.ticker, "D", [high[1],low[1], close[1]], lookahead=barmerge.lookahead_on)
plot(hidePDHCL ? na : dh, title="Prev High", color=color.red, linewidth=2, trackprice=true, show_last = 1)
plot(hidePDHCL ? na : dl, title="Prev Low", color=color.green, linewidth=2, trackprice=true, show_last = 1)
plot(hidePDHCL ? na : dc, title="Prev Close", color=color.black, linewidth=2, trackprice=true, show_last = 1)
plot(hidePDHCL ? na : ta.vwap(close), title="Prev VWAP", color=color.fuchsia, linewidth=2, trackprice=true, show_last = 1)
var l1 = label.new(bar_index, hidePDHCL ? na : dh, 'PDH', style=label.style_label_right)
// Previous Day WWAP
// For SL calculation
atr = ta.atr(slAtrLen)
highestHigh = ta.highest(high, 7)
lowestLow = ta.lowest(low, 7)
longStop = showSLLines ? lowestLow - (atr * 1) : na
shortStop = showSLLines ? highestHigh + (atr * 1) : na
plot(longStop, title="Buy SL", color=color.green, style=plot.style_cross)
plot(shortStop, title="Sell SL", color=color.red, style=plot.style_cross)
// Momentum: rsi
rsi = ta.rsi(close, rsiLen)
// trend: EMA200
ema = ta.ema(close, trendPeriod)
plot(hideTrend ? na : ema, "EMA Trend", color=close > ema ? color.green : color.red, linewidth = 1)
// Volume-Weighed Moving Average calculation
vwmaAvg = ta.vwma(close, volAvg)
vwma_latest = volume
// plotshape((barstate.isconfirmed and (vwma_latest > (vwmaAvg * volThreshold))), title='VolumeData', text='', location=location.abovebar, style=shape.diamond, color=color.gray, textcolor=color.gray, size=size.tiny)
// Trade signals
longCond = barstate.isconfirmed and (ta.crossover(close, orb_high) or ta.crossover(close, dh)) and green(open, close) and (ignoreMementumVolume ? true : rsi > rsiBullish and (vwma_latest > (vwmaAvg * volThreshold)))
shortCond = barstate.isconfirmed and (ta.crossunder(close, orb_low) or ta.crossunder(close, dl)) and red(open, close) and (ignoreMementumVolume ? true : rsi < rsiBearish and (vwma_latest > (vwmaAvg * volThreshold)))
plotshape(longCond, title='Breakout', text='BO', location=location.belowbar, style=shape.triangleup, color=color.green, textcolor=color.green)
plotshape(shortCond, title='Breakout', text='BD', location=location.abovebar, style=shape.triangledown, color=color.red, textcolor=color.red)
// Trade execute
h = hour(time('1'), syminfo.timezone)
m = minute(time('1'), syminfo.timezone)
hourVal = h * 100 + m
totalTrades = strategy.opentrades + strategy.closedtrades
if (mktAlwaysOn or (hourVal < endOfDay))
// Entry
var float sl = na
var float target = na
if (longCond)
strategy.entry("enter long", strategy.long, lotSize, limit=na, stop=na, comment="Enter Long")
sl := longStop
target := close + ((close - longStop) * rrRatio)
alert('Buy:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar)
if (shortCond)
strategy.entry("enter short", strategy.short, lotSize, limit=na, stop=na, comment="Enter Short")
sl := shortStop
target := close - ((shortStop - close) * rrRatio)
alert('Sell:' + syminfo.ticker + ' ,SL:' + str.tostring(math.floor(sl)) + ', Target:' + str.tostring(target), alert.freq_once_per_bar)
// Exit: target or SL
if ((close >= target) or (close <= sl))
strategy.close("enter long", comment=close < sl ? "Long SL hit" : "Long target hit")
if ((close <= target) or (close >= sl))
strategy.close("enter short", comment=close > sl ? "Short SL hit" : "Short target hit")
else if (not mktAlwaysOn)
// Close all open position at the end if Day
strategy.close_all(comment = "Close all entries at end of day.")
// Plotting table
if (not hideTable and is_end_session)
message = syminfo.ticker + " :\n\nORB Upper: " + str.tostring(math.round(orb_high)) + "\nORB Lower: " + str.tostring(math.round(orb_low)) + "\nPDH: " + str.tostring(math.round(dh)) + "\nPDC: " + str.tostring(math.round(dc)) + "\nPDL: " + str.tostring(math.round(dl)) + "\nVWAP: " + str.tostring(math.round(ta.vwap(close)))
printTable(message)
alert(message, alert.freq_once_per_bar_close)