Strategi Teluk Spekulasi adalah strategi perdagangan kuantitatif yang mengesan trend. Ia menggunakan kurva Parabolik SAR sebagai isyarat perdagangan utama, dengan penapis EMA, Squeeze Momentum dan Volatility Oscillator tambahan untuk mengenal pasti titik pembalikan trend dengan parameter SAR, dan mencapai pengesanan trend berisiko rendah. Strategi ini sesuai untuk pelaburan jangka menengah hingga panjang.
Strategi ini menggunakan SAR Parabolik sebagai penunjuk isyarat perdagangan utama. SAR dapat menentukan titik pembalikan trend harga dengan berkesan. Apabila isyarat SAR berubah, ia bermakna trend telah berbalik. Strategi ini biasanya menghasilkan isyarat beli atau jual apabila SAR membalik.
Di samping itu, strategi ini juga menyediakan pilihan SAR breakout - menjana isyarat apabila harga memecahkan nilai SAR terakhir sebelum SAR berbalik sepenuhnya.
Untuk menapis isyarat palsu, strategi ini juga memperkenalkan EMA, Squeeze Momentum dan Volatility Oscillator sebagai tiga penapis tambahan, yang boleh digunakan secara bersendirian atau dalam kombinasi untuk mengesahkan kebolehpercayaan trend harga dan isyarat perdagangan.
Akhirnya, strategi ini menyediakan tiga jenis kaedah stop loss - stop loss tetap, mengambil keuntungan tetap dan nisbah risiko ganjaran stop loss. ini membolehkan strategi untuk menyesuaikan diri dengan fleksibel dengan ciri-ciri pelbagai jenis instrumen dagangan.
SAR boleh menentukan pembalikan trend harga dengan tepat dan menangkap trend harga baru tepat pada masanya, sesuai untuk penjejakan trend jangka sederhana dan panjang.
Pelbagai penapis mengurangkan kemungkinan pecah palsu dan meningkatkan kebolehpercayaan isyarat.
Konfigurasi mudah dan fleksibel, parameter yang boleh disesuaikan untuk menyesuaikan instrumen perdagangan yang berbeza.
Menyediakan pelbagai jenis mengambil keuntungan dan berhenti kerugian untuk mengimbangi risiko dan ganjaran.
Boleh menyambung secara langsung ke bot perdagangan untuk perdagangan automatik.
Di pasaran yang tidak mempunyai trend, mungkin terdapat peningkatan kejadian isyarat palsu dan perdagangan yang tidak berkesan.
Tetapan parameter SAR yang tidak betul juga mempengaruhi ketepatan penilaian isyarat.
Sebagai trend mengikuti strategi, turun naik yang ketara di pasaran boleh dengan mudah memukul garis stop loss.
Untuk menangani risiko di atas, sesuaikan parameter SAR atau parameter penapis dengan sewajarnya untuk mengurangkan kebarangkalian perdagangan yang tidak sah.
Peningkatan Parameter SAR. Peningkatan peningkatan SAR dan parameter langkah melalui data backtest sejarah untuk mendapatkan strategi perdagangan yang lebih stabil dan cekap.
Memperkenalkan Indikator Penghakiman Trend. Tambah penunjuk penghakiman trend tambahan seperti MACD dan DMI untuk meningkatkan keupayaan penghakiman trend.
Mengoptimumkan nisbah risiko - pulangan. Sesuaikan peratusan stop loss tetap dan nisbah risiko - pulangan untuk mengambil risiko yang lebih tinggi untuk pulangan yang lebih tinggi.
Sokong lebih banyak instrumen. Pada masa ini hanya crypto yang disokong, boleh diperluaskan untuk menyokong instrumen perdagangan Forex, komoditi dan sekuriti.
Strategi Teluk Spekulasi adalah trend yang sangat praktikal mengikuti strategi kuantitatif. Ia mempunyai isyarat responsif, penilaian yang boleh dipercayai dan dapat mencapai pulangan yang stabil jangka panjang melalui pengurusan stop loss. Dengan pengoptimuman parameter dan peraturan yang sesuai, kecekapan strategi dapat ditingkatkan lagi. Ini adalah strategi kuantitatif yang cekap yang bernilai digunakan dalam jangka panjang.
/*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) // ======================================================================================================================