A estratégia do Golfo da Especulação é uma estratégia de negociação quantitativa que rastreia tendências. Ela usa a curva parabólica SAR como o principal sinal de negociação, com filtros adicionais de EMA, Momentum de Espremimento e Oscilador de Volatilidade para identificar pontos de reversão de tendência com parâmetros SAR e alcançar o rastreamento de tendências de baixo risco. Esta estratégia é adequada para investimentos de médio a longo prazo.
A estratégia usa o SAR parabólico como o principal indicador de sinal de negociação. O SAR pode determinar efetivamente os pontos de reversão da tendência de preços. Quando o sinal SAR muda, isso significa que a tendência se invertiu. Esta estratégia geralmente gera sinais de compra ou venda quando o SAR vira.
Além disso, a estratégia também fornece uma opção de ruptura SAR - gerando sinais quando o preço atravessa o último valor SAR antes da SAR virar completamente.
Para filtrar os falsos sinais, a estratégia introduz também o EMA, o Squeeze Momentum e o Oscilador de Volatilidade como três filtros auxiliares, que podem ser utilizados isoladamente ou em combinação para confirmar a fiabilidade das tendências de preços e dos sinais de negociação.
Por último, a estratégia prevê três tipos de métodos de stop loss - stop loss fixo, take profit fixo e ratio de risco-recompensação.
O SAR pode determinar com precisão as inversões da tendência dos preços e capturar em tempo útil novas tendências dos preços, adequado para o acompanhamento da tendência a médio e longo prazo.
Os filtros múltiplos reduzem a probabilidade de falhas e melhoram a fiabilidade do sinal.
Configuração simples e flexível, parâmetros personalizáveis para os diferentes instrumentos de negociação.
Fornece vários tipos de take profit e stop loss para equilibrar risco e recompensa.
Pode conectar-se diretamente a bots de negociação para negociação automatizada.
Em mercados que não apresentam tendências, pode haver um aumento das ocorrências de sinais falsos e negociações ineficazes.
As configurações inadequadas dos parâmetros SAR também afectam a precisão dos julgamentos do sinal.
Como uma estratégia de tendência, flutuações significativas no mercado podem facilmente atingir a linha de stop loss.
Para abordar os riscos acima, ajuste adequadamente os parâmetros SAR ou parâmetros de filtro para reduzir a probabilidade de negociações inválidas.
Otimização de parâmetros SAR. Otimize os parâmetros de incremento e passo SAR através de dados de backtest históricos para obter uma estratégia de negociação mais estável e eficiente.
Adicionar indicadores de julgamento de tendências auxiliares como MACD e DMI para melhorar as capacidades de julgamento de tendências.
Otimizar a relação risco-retorno Ajustar a percentagem fixa de stop loss e a relação risco-retorno para assumir riscos mais elevados para retornos mais elevados.
Suporte para mais instrumentos. Atualmente, apenas a criptomoeda é suportada, pode ser estendida para suportar Forex, commodities e instrumentos de negociação de valores mobiliários.
A estratégia do Golfo da Especulação é uma tendência muito prática seguindo a estratégia quantitativa. Tem sinais responsivos, julgamentos confiáveis e pode alcançar retornos estáveis de longo prazo através da gestão de stop loss. Com a otimização apropriada de parâmetros e regras, a eficiência da estratégia pode ser melhorada. Esta é uma estratégia quantitativa eficiente que vale a pena usar a longo prazo.
/*backtest start: 2023-10-23 00:00:00 end: 2023-11-22 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //VERSION ================================================================================================================= //@version=5 // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // This strategy is intended to study. // It can also be used to signal a bot to open a deal by providing the Bot ID, email token and trading pair in the strategy settings screen. // As currently written, this strategy uses a SAR PARABOLIC to send signal, and EMA, Squeeze Momentum, Volatility Oscilator as filter. // There are two enter point, when SAR Flips, or Breakout Point - the last SAR Value before it Flips. // There are tree options for exit: SAR Flips, Fixed Stop Loss ande Fixed Take Profit in % and Risk Reward tha can be set, 0.5/1, 1/1, 1/2 etc. //Autor M4TR1X_BR //▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ //STRATEGY ================================================================================================================ strategy(title = 'BT-SAR Ema, Squeeze, Voltatility', shorttitle = 'SAR ESV', overlay = true) //▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ // INPUTS ================================================================================================================= // TIME INPUTS usefromDate = input.bool(defval = true, title = 'Start date', inline = '0', group = "Time Filters") initialDate = input(defval = timestamp('01 Jan 2022 00:00 UTC'), title = '', inline = "0",group = 'Time Filters',tooltip="This start date is in the time zone of the exchange ") usetoDate = input.bool(defval = true, title = 'End date', inline = '1', group = "Time Filters") finalDate = input(defval = timestamp('31 Dec 2029 23:59 UTC'), title = '', inline = "1",group = 'Time Filters',tooltip="This end date is in the time zone of the exchange") // TIME LOGIC inTradeWindow = true // SAR PARABOLIC INPUTS ================================================================================================== string sargroup= "SAR PARABOLIC =========================================" start = input.float(defval=0.02,title='Start',inline='',group = sargroup) increment = input.float(defval=0.02,title='Increment',inline='',group = sargroup) maximum = input.float(defval=0.2,title='Maximo',inline='',group = sargroup) // SAR PARABOLIC LOGIC out = ta.sar(start, increment, maximum) // SAR FLIP OR BREAKOUT OPTIONS string bkgroup ='SAR TRADE SIGNAL ====================================== ' sarTradeSignal =input.string(defval='SAR Flip',title='SAR Trade Signal', options= ['SAR Flip','SAR Breakout'],group=bkgroup, tooltip='SAR Flip: Once the parabolic SAR flips it will send a signal, SAR Breakout: Will wait the price cross last Sar Value before it flips.') nBars = input.int(defval=4,title='Bars',group=bkgroup, tooltip ='Define the number of bars for a entry when the price cross breakout point') float sarBreakoutPoint= ta.valuewhen((close[1] < out[1]) and (close > out),out[1],0) //Get Sar Breakout Point bool check = (close[1] < out[1]) and (close > out) //Verify when sar flips bool BreakoutPrice = sarTradeSignal=='SAR Breakout'? (ta.barssince(check) < nBars) and ((open < sarBreakoutPoint) and (close > sarBreakoutPoint)): (ta.barssince(check) < nBars) and (close > out) barcolor (check? color.yellow:na,title="Signal Bar color" ) // MOVING AVERAGES INPUTS ================================================================================================ string magroup = "Moving Average ========================================" useEma = input.bool(defval = true, title = 'Moving Average Filter',inline='', group= magroup,tooltip='This will enable or disable Exponential Moving Average Filter on Strategy') emaType=input.string (defval='Ema',title='Type',options=['Ema','Sma'],inline='', group= magroup) emaSource = input.source(defval=close,title=" Source",inline="", group= magroup) emaLength = input.int(defval=100,title="Length",minval=0,inline='', group= magroup) // MOVING AVERAGE LOGIC float ema = emaType=='Ema'? ta.ema(emaSource,emaLength): ta.sma(emaSource,emaLength) // VOLATILITY OSCILLATOR ================================================================================================= string vogroup = "VOLATILITY OSCILLATOR =================================" useVltFilter=input.bool(defval=true,title="Volatility Oscillator Filter",inline='',group= vogroup,tooltip='This will enable or disable Volatility Oscillator filter on Strategy') vltFilterLength = input.int(defval=100,title="Volatility Oscillator",inline='',group=vogroup) vltFilterSpike = close - open vltFilterX = ta.stdev(vltFilterSpike,vltFilterLength) vltFilterY = ta.stdev(vltFilterSpike,vltFilterLength) * -1 // SQUEEZE MOMENTUM INPUTS ============================================================================================== string sqzgroup = "SQUEEZE MOMENTUM =====================================" useSqzFilter=input.bool(defval=true,title="Squeeze Momentum Filter",inline='',group= sqzgroup, tooltip='This will enable or disable Squeeze Momentum filter on Strategy') sqzFilterlength = input.int(defval=20, title='Bollinger Bands Length',inline='',group= sqzgroup) sqzFiltermult = input.float(defval=2.0, title='Boliinger Bands Mult',inline='',group= sqzgroup) keltnerLength = input.int(defval=20, title='Keltner Channel Length',inline='',group= sqzgroup) keltnerMult = input.float(defval=1.5, title='Keltner Channel Mult',inline='',group= sqzgroup) useTrueRange = input(true, title='Use TrueRange (KC)', inline='',group= sqzgroup) // CALCULATE BOLLINGER BANDS sqzFilterSrc = close basis = ta.sma(sqzFilterSrc, sqzFilterlength) dev = keltnerMult * ta.stdev(sqzFilterSrc, sqzFilterlength) upperBB = basis + dev lowerBB = basis - dev // CALCULATE KELTNER CHANNEL sma = ta.sma(sqzFilterSrc, keltnerLength) range_1 = useTrueRange ? ta.tr : high - low rangema = ta.sma(range_1, keltnerLength) upperKC = sma + rangema * keltnerMult lowerKC = sma - rangema * keltnerMult // CHECK IF BOLLINGER BANDS IS IN OR OUT OF KELTNER CHANNEL sqzOn = lowerBB > lowerKC and upperBB < upperKC sqzOff = lowerBB < lowerKC and upperBB > upperKC noSqz = sqzOn == false and sqzOff == false // SQUEEZE MOMENTUM LOGIC val = ta.linreg(sqzFilterSrc - math.avg(math.avg(ta.highest(high, keltnerLength), ta.lowest(low, keltnerLength)),ta.sma(close, keltnerLength)), keltnerLength, 0) // ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ // TAKE PROFIT STOP LOSS INPUTS ========================================================================================= string tkpgroup='Take Profit ==================================================' tpType = input.string(defval = 'SAR Flip', title='Take Profit and Stop Loss', options=['SAR Flip','Fixed % TP/SL', 'Risk Reward TP/SL'], group=tkpgroup ) longTakeProfitPerc = input.float(defval = 1.5, title = 'Fixed TP %', minval = 0.05, step = 0.5, group=tkpgroup, tooltip = 'The percentage increase to set the take profit price target.')/100 longLossPerc = input.float(defval=1.0, title="Fixed Long SL %", minval=0.1, step=0.5, group = tkpgroup, tooltip = 'The percentage increase to set the Long Stop Loss price target.') * 0.01 //shortLossPerc = input.float(defval=1.5, title="Fixed Short SL (%)", minval=0.1, step=0.5, group = tkpgroup, tooltip = 'The percentage increase to set the Short Stop Loss price target.') * 0.01 longTakeProfitRR = input.float(defval = 1, title = 'Risk Reward TP', minval = 0.25, step = 0.25, group=tkpgroup, tooltip = 'The Risk Reward parameter.') var plotStopLossRR = input.bool(defval=false, title='Show RR Stop Loss', group=tkpgroup) //enableStopLossRR = input.bool(defval = false, title = 'Enable Risk Reward TP',group=tkpgroup, tooltip = 'Enable Variable Stop Loss.') string trpgroup='Traling Profit ===============================================' enableTrailing = input.bool(defval = false, title = 'Enable Trailing',group=trpgroup, tooltip = 'Enable or disable the trailing for take profit.') trailingTakeProfitDeviationPerc = input.float(defval = 0.1, title = 'Trailing Take Profit Deviation %', minval = 0.01, maxval = 100, step = 0.01, group=trpgroup, tooltip = 'The step to follow the price when the take profit limit is reached.') / 100 // BOT MESSAGES string msgroup='Alert Message For Bot =========================================' messageEntry = input.string("", title="Strategy Entry Message",group=msgroup) messageExit =input.string("",title="Strategy Exit Message",group=msgroup) messageClose = input.string("", title="Strategy Close Message",group=msgroup) // ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ // POSITIONS ============================================================================================================= //VERIFY IF THE BUY FILTERS ARE ON OR OFF bool emaFilterBuy = useEma? (close > ema):(close >= ema) or (close <= ema) bool volatilityFilterBuy = useVltFilter? (vltFilterSpike > vltFilterX) : (vltFilterSpike >= 0) or (vltFilterSpike <= 0) bool sqzFilterBuy = useSqzFilter? (val > val[1]): (val >= val[1] or val <=val[1]) bool sarflip = (close > out) //LONG / SHORT POSITIONS LOGIC //Var 'check' will verify if the SAR flips and if the exit price occurs it will limit in bars number a new entry on the same signal. bool limitEntryNumbers = (ta.barssince(check) < nBars) bool openLongPosition = sarTradeSignal == 'SAR Flip'? (sarflip and emaFilterBuy and volatilityFilterBuy and sqzFilterBuy and limitEntryNumbers) :sarTradeSignal=='SAR Breakout'? (BreakoutPrice and emaFilterBuy and volatilityFilterBuy and sqzFilterBuy): na bool openShortPosition = na bool closeLongPosition= tpType=='SAR Flip'? (close < out):na bool closeShortPosition=na // CHEK OPEN POSITONS ===================================================================================================== // open signal when not already into a position bool validOpenLongPosition = openLongPosition and strategy.opentrades.size(strategy.opentrades - 1) <= 0 bool longIsActive = validOpenLongPosition or strategy.opentrades.size(strategy.opentrades - 1) > 0 // ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ // TAKE PROFIT STOP LOSS CONFIG ========================================================================================== // FIXED TAKE PROFIT IN % float posSize = strategy.opentrades.entry_price(strategy.opentrades - 1) //Get the entry price var float longTakeProfitPrice = na longTakeProfitPrice := if (longIsActive) if (openLongPosition and not (strategy.opentrades.size(strategy.opentrades - 1) > 0)) posSize * (1 + longTakeProfitPerc) else nz(longTakeProfitPrice[1], close * (1 + longTakeProfitPerc)) else na longTrailingTakeProfitStepTicks = longTakeProfitPrice * trailingTakeProfitDeviationPerc / syminfo.mintick // FIXED STOP LOSS IN % longStopPrice = strategy.position_avg_price * (1 - longLossPerc) //shortStopPrice = strategy.position_avg_price * (1 + shortLossPerc) // TAKE PROFIT BY RISK/REWARD // Set stop loss tta = not (strategy.opentrades.size(strategy.opentrades - 1) > 0) float lastb = ta.valuewhen(check and tta,ta.lowest(low,5),0) - (10 * syminfo.mintick) // TAKE PROFIT CALCULATION float stopLossRisk = (posSize - lastb) float takeProfitRR = posSize + (longTakeProfitRR * stopLossRisk) // ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ // POSITION ORDERS ===================================================================================================== // LOGIC =============================================================================================================== // getting into LONG position if (openLongPosition) and (inTradeWindow) strategy.entry(id = 'Long Entry', direction = strategy.long, alert_message=messageEntry) //submit exit orders for trailing take profit price if (longIsActive) and (inTradeWindow) strategy.exit(id = 'Long Take Profit', from_entry = 'Long Entry', limit = enableTrailing ? na : tpType=='Fixed % TP/SL'? longTakeProfitPrice: tpType == 'Risk Reward TP/SL'? takeProfitRR:na, trail_price = enableTrailing ? longTakeProfitPrice : na, trail_offset = enableTrailing ? longTrailingTakeProfitStepTicks : na, stop = tpType =='Fixed % TP/SL' ? longStopPrice: tpType == 'Risk Reward TP/SL'? lastb:na) //, alert_message='{ "action": "close_at_market_price", "message_type": "bot", "bot_id": 9330698, "email_token": "392265bc-84eb-4a54-a99c-758383ff9449", "delay_seconds": 0,"pair":"USDT_{{ticker}}" }') if (closeLongPosition) strategy.close(id = 'Long Entry', alert_message='{ "action": "close_at_market_price", "message_type": "bot", "bot_id": 9330698, "email_token": "392265bc-84eb-4a54-a99c-758383ff9449", "delay_seconds": 0,"pair":"USDT_{{ticker}}" }') // ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ // PLOTS =============================================================================================================== // TRADE WINDOW ======================================================================================================== bgcolor(color = inTradeWindow ? color.new(#089981,90):na, title = 'Time Window') // SAR PARABOLIC var sarColor = color.new(#00bcd4,0) plot(out, "ParabolicSAR", color=sarColor, linewidth=1,style=plot.style_cross) //BREAKOUT LINE var plotBkPoint = input.bool(defval=false, title='Show Breakout Point', group=bkgroup) plot(series = (sarTradeSignal=='SAR Breakout' and plotBkPoint == true)? sarBreakoutPoint:na, title = 'Breakout line', color =color.new(#ffeb3b,50) , linewidth = 1, style = plot.style_linebr, offset = 0) // EMA/SMA var emafilterColor = color.new(color.white, 0) plot(series=useEma? ema:na, title = 'EMA Filter', color = emafilterColor, linewidth = 2, style = plot.style_line) // ENTRY PRICE var posColor = color.new(#2962ff, 0) plot(series = strategy.opentrades.entry_price(strategy.opentrades - 1), title = 'Position', color = posColor, linewidth = 1, style = plot.style_linebr,offset=0) // FIXED TAKE PROFIT var takeProfitColor = color.new(#ba68c8, 0) plot(series = tpType=='Fixed % TP/SL'? longTakeProfitPrice:na, title = 'Fixed TP', color = takeProfitColor, linewidth = 1, style = plot.style_linebr, offset = 0) // FIXED STOP LOSS var stopLossColor = color.new(#ff0000, 0) plot(series = tpType=='Fixed % TP/SL' ? longStopPrice:na, title = 'Fixed SL', color = stopLossColor, linewidth = 1, style = plot.style_linebr, offset = 0) // RISK REWARD TAKE PROFIT var takeProfitRRColor = color.new(#ba68c8, 0) plot(series=tpType == 'Risk Reward TP/SL'? takeProfitRR:na,title='Risk Reward TP',color=takeProfitRRColor,linewidth=1,style=plot.style_linebr) // STOP LOSS RISK REWARD plot(series = (check and plotStopLossRR)? lastb:na, title = 'Last Bottom', color =color.new(#ff0000,0), linewidth = 2, style = plot.style_linebr, offset = 0) // ======================================================================================================================