Strategi Stop Loss Pelancongan Tetap

Penulis:ChaoZhang, Tarikh: 2023-11-03 14:31:21
Tag:

img

Ringkasan

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.

Prinsip Strategi

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.

Kelebihan

Strategi stop loss yang tetap ini mempunyai kelebihan berikut:

  1. 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.

  2. 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.

  3. 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.

  4. Kemampuan strategi untuk menyesuaikan stop loss dalam masa nyata untuk stop loss yang berturut-turut membantu mengunci lebih banyak keuntungan.

  5. 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.

  6. Struktur kod yang bersih. Struktur kod adalah jelas dan modular, menjadikannya mudah difahami dan dioptimumkan.

Risiko

Walaupun kelebihan, terdapat beberapa risiko yang perlu diperhatikan untuk strategi:

  1. 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.

  2. Stop loss tetap mungkin terlalu mekanikal. Harga pasaran sering jurang. Stop loss tetap mungkin terlalu bergantung kepada peraturan dan kurang fleksibel dalam penyesuaian.

  3. Tidak ada had terhadap kekerapan perdagangan. Strategi tidak mengehadkan kekerapan perdagangan dan mungkin berdagang terlalu kerap. Peraturan lain diperlukan untuk mengehadkan kekerapan.

  4. Penetapan jumlah stop loss tetap adalah penting untuk kawalan risiko keseluruhan dan perlu mempertimbangkan saiz modal, selera risiko dll.

  5. 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.

  6. 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:

  1. Menambah penunjuk untuk menapis kualiti isyarat, contohnya MACD, KD dll.

  2. Menggabungkan penunjuk kekuatan pecah untuk menilai kualiti. Sebagai contoh, menilai kekuatan melalui perubahan jumlah.

  3. Menambah had kekerapan perdagangan terbuka, contohnya satu dagangan sehari.

  4. Mengoptimumkan logik stop loss tetap, contohnya stop loss berasaskan peratusan di atas ambang.

  5. Menambah penapis lain, contohnya turun naik, meningkatkan stop loss dan lain-lain.

  6. Menggabungkan strategi mengambil keuntungan, contohnya mengambil keuntungan berhampiran rintangan.

Arahan pengoptimuman

Berdasarkan analisis, strategi ini boleh dioptimumkan dalam aspek berikut:

  1. Menambah penapis untuk meningkatkan kualiti isyarat menggunakan pelbagai penunjuk teknikal dan menilai kualiti trend.

  2. Mengoptimumkan stop loss untuk lebih fleksibiliti. Boleh beralih ke stop trailing berasaskan peratusan selepas retracement tertentu. Juga boleh mengoptimumkan secara dinamik berdasarkan turun naik.

  3. Mengendalikan kekerapan perdagangan untuk mengelakkan perdagangan berlebihan dengan menambah penapis pada tempoh masa atau kekerapan.

  4. Memasukkan penunjuk trend untuk meningkatkan masa, contohnya menunggu pengesahan trend.

  5. Mengoptimumkan strategi mengambil keuntungan untuk meningkatkan keuntungan melalui sasaran keuntungan, berhenti keuntungan, berhenti turun naik dan lain-lain.

  6. Mengoptimumkan parameter risiko berdasarkan backtests, seperti jumlah berhenti tetap, tempoh pecah dll.

  7. Refactoring kod untuk kebolehluasan yang lebih baik dengan melepaskan lagi modul isyarat, penapis, risiko, keuntungan.

  8. 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.

Kesimpulan

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)


Lebih lanjut