
Idea utama strategi ini adalah untuk menggunakan arah trend pengiktirafan jalur perlanggaran untuk pengurusan risiko, digabungkan dengan hentian tetap. Strategi ini mula mengira harga tertinggi dan terendah dalam tempoh tertentu, membentuk jalur perlanggaran.
Strategi ini terdiri daripada empat bahagian utama: pengurusan kedudukan, pengenalan jalur penembusan, penetapan stop loss dan pengiraan kuantiti.
Pertama sekali, strategi untuk menentukan sama ada ada kedudukan yang dipegang pada masa ini. Jika ia telah dipegang, maka tidak akan ada isyarat baru.
Kedua, strategi ini akan mengira harga tertinggi dan terendah dalam tempoh tertentu, membentuk jalur pecah. Apabila harga dari dalam jalur pecah ke luar, menghasilkan isyarat perdagangan. Secara khusus, jika harga menembusi jalur pecah, menghasilkan isyarat banyak; jika harga menembusi jalur turun, menghasilkan isyarat kosong.
Di samping itu, apabila berlaku banyak isyarat, strategi akan menetapkan titik tengah jalur penembusan sebagai titik berhenti. Apabila isyarat penembusan berlaku, ia juga akan menetapkan titik berhenti. Untuk menjejaki berhenti, strategi juga akan menyesuaikan titik berhenti dalam masa nyata semasa memegang kedudukan.
Akhirnya, strategi membolehkan untuk menetapkan jumlah berhenti tetap. Apabila isyarat berlaku, strategi akan mengira jarak titik dari titik berhenti kepada harga semasa, dan kemudian menggabungkan unit tawaran, kadar pertukaran dan faktor-faktor lain, untuk mengira jumlah yang diwakili oleh perubahan harga antara titik berhenti.
Ini adalah prinsip utama strategi. Dengan mengenal pasti arah trend melalui jalur pecah, dan mengawal risiko dengan menggunakan stop loss tetap, ini adalah idea utama strategi.
Strategi penutupan tetap dengan jalur pecah ini mempunyai kelebihan berikut:
Stop loss idea lebih maju. Strategi menggunakan jumlah stop loss tetap dan bukannya jarak stop loss tetap. Ini mengelakkan masalah risiko yang tidak dapat ditetapkan yang disebabkan oleh perbezaan nilai titik antara pelbagai jenis. Dari sudut pengurusan risiko, jumlah stop loss tetap lebih maju.
Kaedah ini dapat mengira jumlah dagangan dengan bijak berdasarkan jumlah stop loss tetap, sehingga setiap kerugian dapat dikawal, sehingga mengawal risiko dengan wajar.
Pengenalan terobosan mudah dan berkesan. Pengenalan jalur terobosan mudah dan langsung, dan dapat mengenal pasti arah trend dengan berkesan. Pengesanan jalur terobosan seperti itu dapat mengelakkan lebih banyak isyarat palsu yang keluar dari arah trend berbanding dengan hanya melangkaui tahap harga tertentu.
Tracking stop loss meningkatkan keuntungan. Strategi dapat menyesuaikan kedudukan stop loss dalam masa nyata, untuk menjejaki stop loss, membantu mengunci lebih banyak keuntungan.
Keupayaan yang luas. Strategi ini boleh digunakan untuk mana-mana jenis, dan dengan parameter yang betul, anda boleh melakukan kawalan risiko untuk menghentikan kerugian dengan jumlah tetap, sehingga mempunyai aplikasi yang sangat luas.
Struktur kod yang jelas. Struktur kod strategi yang jelas, modul fungsi yang terpecahkan dengan baik, mudah difahami dan dioptimumkan selanjutnya.
Walaupun terdapat kelebihan yang disebutkan di atas, strategi ini mempunyai risiko yang perlu diperhatikan:
Kualiti bentuk pecah tidak dapat dinilai. Kualiti bentuk pecah yang tidak dapat dinilai dalam strategi mungkin menghasilkan beberapa isyarat berkualiti rendah. Penapisan perlu dilakukan bersama dengan petunjuk lain.
Hentian tetap mungkin terlalu mekanikal. Harga pasaran sering mempunyai ciri-ciri pergerakan melompat, Hentian tetap mungkin terlalu bergantung pada peraturan dan tidak dapat disesuaikan dengan fleksibel.
Tidak boleh membatasi frekuensi transaksi. Strategi tidak boleh membatasi frekuensi transaksi, mungkin terlalu kerap bermain. Perlu digabungkan dengan peraturan lain untuk membatasi frekuensi.
Penetapan parameter bergantung kepada penangguhan tetap. Penetapan jumlah penangguhan tetap adalah berkaitan dengan kawalan celah keseluruhan, yang perlu disesuaikan dengan pelbagai aspek berdasarkan saiz dana, keutamaan risiko dan sebagainya.
Arah penembusan mungkin menghasilkan isyarat yang salah. Isyarat penembusan yang salah mungkin dihasilkan apabila harga bergoyang atau berpatah balik.
Kurangnya tetapan penangguhan. Strategi tidak mempunyai mekanisme penangguhan pada masa ini, tidak dapat menentukan keuntungan secara proaktif. Ini boleh menyebabkan keuntungan yang tidak sesuai.
Untuk mengatasi risiko ini, kita boleh mengoptimumkan dari beberapa aspek:
Tambahkan penunjuk untuk menilai bentuk, penapis kualiti isyarat. Contohnya MACD, KD dan sebagainya.
Kaedah ini digunakan untuk menilai kualiti penembusan dengan menggunakan penunjuk kekuatan penembusan.
Peningkatan had frekuensi pembukaan kedudukan. Sebagai contoh, hanya berdagang sekali sehari atau peraturan serupa.
Mengoptimumkan logik tetapan stop loss tetap. Contohnya, ubah stop loss menjadi peratusan berdasarkan nilai terendah tertentu.
Menambah syarat penapisan lain. Contohnya, peningkatan stop loss, kadar turun naik harga dan sebagainya.
Tambah strategi penangguhan. Sebagai contoh, berhenti ketika mendekati titik rintangan.
Berdasarkan analisis di atas, strategi ini boleh dioptimumkan dalam beberapa aspek:
Menambah syarat penapisan, meningkatkan kualiti isyarat. Anda boleh memasukkan pelbagai petunjuk teknikal, menilai kualiti trend, dan mengelakkan isyarat penembusan yang tidak sesuai. Anda juga boleh menilai kekuatan penembusan.
Mengoptimumkan strategi berhenti kerugian, menjadikannya lebih fleksibel. Ia boleh diubah menjadi berhenti peratusan selepas jarak penyesuaian yang terhad. Ia juga boleh mengoptimumkan jarak berhenti kerugian secara real-time berdasarkan kadar turun naik.
Mengendalikan kekerapan perdagangan, mengelakkan perdagangan berlebihan. Anda boleh menetapkan syarat penapisan untuk tempoh masa atau bilangan kali, mengurangkan kekerapan perdagangan.
Menggabungkan indikator penilaian trend, memilih masa masuk ke lapangan. Sebagai contoh, mengoptimumkan untuk masuk semula setelah trend disahkan.
Mengoptimumkan strategi hentian dan meningkatkan keuntungan. Anda boleh menetapkan sasaran keuntungan, bergerak hentian, hentian turun naik dan sebagainya.
Tetapan parameter risiko yang dioptimumkan. Anda boleh menetapkan kombinasi parameter yang lebih baik berdasarkan hasil tinjauan semula, seperti jumlah berhenti tetap, kitaran pecah, dan sebagainya.
Peningkatan struktur kod, peningkatan kebolehgunaan. Modul penjanaan isyarat, penapisan, kawalan angin, dan keuntungan dapat dikesan lebih lanjut.
Uji lebih banyak ruang lelang varieti. Menilai kelebihan lelang dalam gabungan varieti yang berbeza.
Dengan mengoptimumkan pelbagai aspek di atas, anda dapat meningkatkan lagi kestabilan dan keuntungan strategi penangguhan kerugian terobosan ini. Ia juga membina asas untuk pengembangan ke lebih banyak strategi strategi di masa depan.
Strategi keseluruhan adalah munasabah, menggunakan trend pengenalan jalur penembusan, dan menggunakan kerugian tetap untuk mengawal risiko. Ini adalah progresif dalam pengurusan risiko. Tetapi, strategi ini dapat dioptimumkan dengan pelbagai cara untuk meningkatkan kualiti isyarat, fleksibiliti strategi hentian, dan keseimbangan keuntungan.
/*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)