Idea utama strategi ini adalah untuk menggunakan band pecah untuk mengenal pasti arah trend dan menggabungkan stop loss tetap untuk pengurusan risiko. Strategi pertama mengira harga tertinggi dan terendah dalam tempoh tertentu untuk membentuk band pecah. Apabila harga memecahkan band pecah, isyarat perdagangan dihasilkan. Di samping itu, strategi ini membolehkan peniaga menetapkan jumlah stop loss tetap. Setiap kali perdagangan diletakkan, sistem akan mengira saiz kedudukan berdasarkan jumlah stop loss tetap, sehingga setiap kerugian ditetapkan.
Strategi ini terdiri daripada empat bahagian utama: pengurusan kedudukan, pengenalan jalur pecah, penetapan stop loss dan saiz kedudukan.
Pertama, strategi ini memeriksa sama ada terdapat sebarang kedudukan terbuka.
Kedua, strategi ini mengira harga tertinggi dan terendah dalam tempoh untuk membentuk band pecah. Apabila harga keluar dari band, isyarat perdagangan dihasilkan. Khususnya, jika harga pecah di atas band atas, isyarat panjang dihasilkan. Jika harga pecah di bawah band bawah, isyarat pendek dihasilkan.
Selain itu, apabila isyarat panjang dihasilkan, strategi menetapkan titik tengah jalur pecah sebagai kerugian berhenti. Begitu juga untuk isyarat pendek. Untuk mengikuti kerugian berhenti, strategi juga menyesuaikan kerugian berhenti dalam masa nyata apabila berada di kedudukan.
Akhirnya, strategi ini membolehkan menetapkan jumlah stop loss tetap. Apabila isyarat dihasilkan, strategi ini mengira jumlah pips dari stop loss ke harga semasa, dan menggabungkan faktor seperti saiz tanda dan kadar pertukaran, untuk menentukan perubahan harga antara stop loss dan harga semasa dalam istilah kewangan. Saiz kedudukan kemudian dikira berdasarkan jumlah stop loss tetap.
Di atas adalah prinsip-prinsip utama strategi. mengenal pasti arah trend dengan jalur pecah dan mengawal risiko dengan stop loss tetap adalah konsep teras.
Strategi stop loss yang tetap ini mempunyai kelebihan berikut:
Konsep stop loss lanjutan. Strategi ini menggunakan jumlah stop loss tetap dan bukannya jarak stop loss tetap. Ini mengelakkan masalah tidak dapat menetapkan risiko di seluruh produk dengan nilai tik yang berbeza. Dari perspektif pengurusan risiko, stop loss monetari tetap lebih maju.
Ukuran kedudukan yang munasabah. Strategi ini boleh mengira saiz kedudukan dengan bijak berdasarkan jumlah stop loss tetap, supaya kerugian setiap perdagangan dikawal, dengan itu menguruskan pendedahan risiko dengan munasabah.
Pengesanan penembusan yang mudah dan berkesan. Pengesanan penembusan dengan pita adalah mudah dan langsung, dan dapat mengenal pasti arah trend dengan berkesan. Berbanding dengan penembusan satu tahap harga, pengenalan pita penembusan ini dapat mengelakkan lebih banyak isyarat palsu dari trend.
Kemampuan strategi untuk menyesuaikan stop loss dalam masa nyata untuk stop loss yang berturut-turut membantu mengunci lebih banyak keuntungan.
Penggunaan yang luas. Strategi ini boleh digunakan untuk mana-mana produk. Selagi parameter ditetapkan dengan betul, kawalan risiko stop loss jumlah tetap dapat dicapai, menjadikan strategi ini sangat serba boleh.
Struktur kod yang bersih. Struktur kod adalah jelas dan modular, menjadikannya mudah difahami dan dioptimumkan.
Walaupun kelebihan, terdapat beberapa risiko yang perlu diperhatikan untuk strategi:
Kualiti corak pecah tidak diuji. Strategi ini tidak menilai kualiti corak pecah dan mungkin menghasilkan beberapa isyarat berkualiti rendah. Penunjuk lain diperlukan untuk menapis isyarat.
Stop loss tetap mungkin terlalu mekanikal. Harga pasaran sering jurang. Stop loss tetap mungkin terlalu bergantung kepada peraturan dan kurang fleksibel dalam penyesuaian.
Tidak ada had terhadap kekerapan perdagangan. Strategi tidak mengehadkan kekerapan perdagangan dan mungkin berdagang terlalu kerap. Peraturan lain diperlukan untuk mengehadkan kekerapan.
Penetapan jumlah stop loss tetap adalah penting untuk kawalan risiko keseluruhan dan perlu mempertimbangkan saiz modal, selera risiko dll.
Arah penembusan mungkin memberikan isyarat yang salah. Isyarat penembusan yang salah mungkin berlaku semasa turun naik atau penurunan harga. Lebih banyak keadaan diperlukan untuk mengoptimumkan strategi.
Tidak ada mekanisme mengambil keuntungan. Strategi kini tidak mempunyai keupayaan mengambil keuntungan untuk mengunci keuntungan secara aktif. Ini boleh membawa kepada keuntungan yang tidak memuaskan.
Untuk menangani risiko ini, beberapa cara untuk mengoptimumkan strategi termasuk:
Menambah penunjuk untuk menapis kualiti isyarat, contohnya MACD, KD dll.
Menggabungkan penunjuk kekuatan pecah untuk menilai kualiti. Sebagai contoh, menilai kekuatan melalui perubahan jumlah.
Menambah had kekerapan perdagangan terbuka, contohnya satu dagangan sehari.
Mengoptimumkan logik stop loss tetap, contohnya stop loss berasaskan peratusan di atas ambang.
Menambah penapis lain, contohnya turun naik, meningkatkan stop loss dan lain-lain.
Menggabungkan strategi mengambil keuntungan, contohnya mengambil keuntungan berhampiran rintangan.
Berdasarkan analisis, strategi ini boleh dioptimumkan dalam aspek berikut:
Menambah penapis untuk meningkatkan kualiti isyarat menggunakan pelbagai penunjuk teknikal dan menilai kualiti trend.
Mengoptimumkan stop loss untuk lebih fleksibiliti. Boleh beralih ke stop trailing berasaskan peratusan selepas retracement tertentu. Juga boleh mengoptimumkan secara dinamik berdasarkan turun naik.
Mengendalikan kekerapan perdagangan untuk mengelakkan perdagangan berlebihan dengan menambah penapis pada tempoh masa atau kekerapan.
Memasukkan penunjuk trend untuk meningkatkan masa, contohnya menunggu pengesahan trend.
Mengoptimumkan strategi mengambil keuntungan untuk meningkatkan keuntungan melalui sasaran keuntungan, berhenti keuntungan, berhenti turun naik dan lain-lain.
Mengoptimumkan parameter risiko berdasarkan backtests, seperti jumlah berhenti tetap, tempoh pecah dll.
Refactoring kod untuk kebolehluasan yang lebih baik dengan melepaskan lagi modul isyarat, penapis, risiko, keuntungan.
Uji lebih banyak produk untuk peluang arbitrage. Menilai kelebihan merentasi kombinasi produk yang berbeza.
Melalui dimensi pengoptimuman ini, strategi stop loss pecah boleh menjadi lebih kukuh dan menguntungkan. Ia juga meletakkan asas untuk berkembang ke dalam lebih banyak kombinasi strategi.
Secara keseluruhan, strategi ini adalah munasabah dalam menggunakan pita pecah untuk mengenal pasti trend dan berhenti jumlah tetap untuk kawalan risiko. Konsep-konsep ini adalah progresif untuk pengurusan risiko. Logik saiz kedudukan juga baik untuk mengawal kerugian setiap perdagangan. Tetapi strategi ini boleh ditingkatkan melalui pelbagai pengoptimuman untuk meningkatkan kualiti isyarat, fleksibiliti dalam kehilangan berhenti, keuntungan dan lain-lain. Dengan menggabungkan penapis trend, meningkatkan pengambilan keuntungan, dan mengawal kekerapan perdagangan dengan ketat, peningkatan yang ketara dapat dicapai.
/*backtest start: 2023-10-26 00:00:00 end: 2023-10-28 03:00:00 period: 10m basePeriod: 1m 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/ //@version=4 //@author=Takazudo strategy("Fixed price SL", overlay=true, default_qty_type=strategy.fixed, initial_capital=0, currency=currency.USD) var COLOR_TRANSPARENT = color.new(#000000, 100) var COLOR_ENTRY_BAND = color.new(#43A6F5, 30) //============================================================================ // config //============================================================================ // Money management _g1 = 'Money management' var config_riskPrice = input(100, minval=1, title="Risk price for each entry", group=_g1) var config_depositCurrency = input(title="Deposit currency", type=input.string, defval="USD", options=["USD"], group=_g1) // Entry strategy _g2 = 'Entry strategy' var config_entryBandBars = input(defval = 100, title = "Entry band bar count", minval=1, group=_g2) // Backtesting range _g3 = 'Backtesting range' fromYear = input(defval = 2018, title = "From Year", minval = 1970, group=_g3) fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12, group=_g3) fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31, group=_g3) toYear = input(defval = 2020, title = "To Year", minval = 1970, group=_g3) toMonth = input(defval = 12, title = "To Month", minval = 1, maxval = 12, group=_g3) toDay = input(defval = 31, title = "To Day", minval = 1, maxval = 31, group=_g3) //============================================================================ // exchange caliculations //============================================================================ // mico pip size caliculation // ex1: AUDCAD -> 0.0001 // ex2: USDJPY -> 0.01 f_calcMicroPipSize() => _base = syminfo.basecurrency _quote = syminfo.currency _result = 0.0001 if _quote == 'JPY' _result := _result * 100 if _base == 'BTC' _result := _result * 100 _result // convert price to pips f_convertPriceToPips(_price) => _microPipSize = f_calcMicroPipSize() _price / _microPipSize // caliculate exchange rate between deposit and quote currency f_calcDepositExchangeSymbolId() => _result = '' _deposit = config_depositCurrency _quote = syminfo.currency if (_deposit == 'USD') and (_quote == 'USD') _result := na if (_deposit == 'USD') and (_quote == 'AUD') _result := 'OANDA:AUDUSD' if (_deposit == 'EUR') and (_quote == 'USD') _result := 'OANDA:EURUSD' if (_deposit == 'USD') and (_quote == 'GBP') _result := 'OANDA:GBPUSD' if (_deposit == 'USD') and (_quote == 'NZD') _result := 'OANDA:NZDUSD' if (_deposit == 'USD') and (_quote == 'CAD') _result := 'OANDA:USDCAD' if (_deposit == 'USD') and (_quote == 'CHF') _result := 'OANDA:USDCHF' if (_deposit == 'USD') and (_quote == 'JPY') _result := 'OANDA:USDJPY' _result // Let's say we need CAD to USD exchange // However there's only "OANDA:USDCAD" symbol. // Then we need to invert the exhchange rate. // this function tells us whether we should invert the rate or not f_calcShouldInvert() => _result = false _deposit = config_depositCurrency _quote = syminfo.currency if (_deposit == 'USD') and (_quote == 'CAD') _result := true if (_deposit == 'USD') and (_quote == 'CHF') _result := true if (_deposit == 'USD') and (_quote == 'JPY') _result := true _result // caliculate how much quantity should I buy or sell f_calcQuantitiesForEntry(_depositExchangeRate, _slPips) => _microPipSize = f_calcMicroPipSize() _priceForEachPipAsDeposit = _microPipSize * _depositExchangeRate _losePriceOnSl = _priceForEachPipAsDeposit * _slPips floor(config_riskPrice / _losePriceOnSl) //============================================================================ // Quantity caliculation //============================================================================ depositExchangeSymbolId = f_calcDepositExchangeSymbolId() // caliculate deposit exchange rate rate = security(depositExchangeSymbolId, timeframe.period, hl2) shouldInvert = f_calcShouldInvert() depositExchangeRate = if config_depositCurrency == syminfo.currency // if USDUSD, no exchange of course 1 else // else, USDCAD to CADUSD invert if we need shouldInvert ? (1 / rate) : rate //============================================================================ // Range Edge caliculation //============================================================================ f_calcEntryBand_high() => _highest = max(open[3], close[3]) for i = 4 to (config_entryBandBars - 1) _highest := max(_highest, open[i], close[i]) _highest f_calcEntryBand_low() => _lowest = min(open[3], close[3]) for i = 4 to (config_entryBandBars - 1) _lowest := min(_lowest, open[i], close[i]) _lowest entryBand_high = f_calcEntryBand_high() entryBand_low = f_calcEntryBand_low() entryBand_height = entryBand_high - entryBand_low plot(entryBand_high, color=COLOR_ENTRY_BAND, linewidth=1) plot(entryBand_low, color=COLOR_ENTRY_BAND, linewidth=1) rangeBreakDetected_long = entryBand_high < close rangeBreakDetected_short = entryBand_low > close shouldMakeEntryLong = (strategy.position_size == 0) and rangeBreakDetected_long shouldMakeEntryShort = (strategy.position_size == 0) and rangeBreakDetected_short //============================================================================ // SL & Quantity //============================================================================ var sl_long = hl2 var sl_short = hl2 entryQty = 0 slPips = 0.0 // just show info bubble f_showEntryInfo(_isLong) => _str = 'SL pips: ' + tostring(slPips) + '\n' + 'Qty: ' + tostring(entryQty) _bandHeight = entryBand_high - entryBand_low _y = _isLong ? (entryBand_low + _bandHeight * 1/4) : (entryBand_high - _bandHeight * 1/4) _style = _isLong ? label.style_label_up : label.style_label_down label.new(bar_index, _y, _str, size=size.large, style=_style) if shouldMakeEntryLong sl_long := (entryBand_high + entryBand_low) / 2 slPips := f_convertPriceToPips(close - sl_long) entryQty := f_calcQuantitiesForEntry(depositExchangeRate, slPips) if shouldMakeEntryShort sl_short := (entryBand_high + entryBand_low) / 2 slPips := f_convertPriceToPips(sl_short - close) entryQty := f_calcQuantitiesForEntry(depositExchangeRate, slPips) // trailing SL if strategy.position_size > 0 sl_long := max(sl_long, entryBand_low) if strategy.position_size < 0 sl_short := min(sl_short, entryBand_high) //============================================================================ // backtest duration //============================================================================ // Calculate start/end date and time condition startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00) finishDate = timestamp(toYear, toMonth, toDay, 00, 00) //============================================================================ // make entries //============================================================================ if (true) if shouldMakeEntryLong strategy.entry(id="Long", long=true, stop=close, qty=entryQty) f_showEntryInfo(true) if shouldMakeEntryShort strategy.entry(id="Short", long=false, stop=close, qty=entryQty) f_showEntryInfo(false) strategy.exit('Long-SL/TP', 'Long', stop=sl_long) strategy.exit('Short-SL/TP', 'Short', stop=sl_short) //============================================================================ // plot misc //============================================================================ sl = strategy.position_size > 0 ? sl_long : strategy.position_size < 0 ? sl_short : na plot(sl, color=color.red, style=plot.style_cross, linewidth=2, title="SL") value_bgcolor = rangeBreakDetected_long ? color.green : rangeBreakDetected_short ? color.red : COLOR_TRANSPARENT bgcolor(value_bgcolor, transp=95)