Breakout dengan strategi stop loss tetap


Tanggal Pembuatan: 2023-11-03 14:31:21 Akhirnya memodifikasi: 2023-11-03 14:31:21
menyalin: 0 Jumlah klik: 398
1
fokus pada
1224
Pengikut

Breakout dengan strategi stop loss tetap

Ringkasan

Gagasan utama dari strategi ini adalah menggunakan breakband untuk mengidentifikasi arah tren dan melakukan manajemen risiko dalam kombinasi dengan stop loss tetap. Strategi ini pertama-tama menghitung harga tertinggi dan terendah dalam periode tertentu, membentuk breakband. Strategi ini menghasilkan sinyal perdagangan ketika harga menembus breakband.

Prinsip Strategi

Strategi ini terdiri dari empat bagian utama: manajemen posisi, identifikasi break-even, pengaturan stop loss, dan penghitungan jumlah.

Pertama, strategi menentukan apakah ada posisi yang dipegang saat ini. Jika sudah ada posisi yang dipegang, maka tidak akan ada sinyal baru.

Kedua, strategi ini menghitung harga tertinggi dan terendah dalam periode tertentu, membentuk sebuah breakband. Ketika harga dari dalam breakband ke luar, menghasilkan sinyal perdagangan. Secara khusus, jika harga menembus breakband ke atas, menghasilkan sinyal multitasking; Jika harga menembus breakband ke bawah, menghasilkan sinyal blanko.

Selain itu, ketika melakukan beberapa sinyal, strategi akan menetapkan titik tengah breakband sebagai stop loss. Ketika sinyal shorting terjadi, stop loss juga akan ditetapkan. Untuk melacak stop loss, strategi juga akan menyesuaikan stop loss secara real time selama memegang posisi.

Akhirnya, strategi memungkinkan untuk menetapkan jumlah stop loss yang tetap. Ketika sinyal terjadi, strategi akan menghitung jarak titik dari titik stop loss ke harga saat ini, kemudian menggabungkan unit penawaran, nilai tukar, dan faktor-faktor lainnya untuk menghitung jumlah yang diwakili oleh perubahan harga antara titik stop loss.

Ini adalah prinsip utama dari strategi tersebut. Mengidentifikasi arah tren melalui breakthrough dan menggunakan stop loss tetap untuk mengontrol risiko adalah ide inti dari strategi tersebut.

Analisis Keunggulan

Strategi Stop Loss Fixed Breakthrough ini memiliki keuntungan sebagai berikut:

  1. Stop loss adalah strategi yang lebih maju. Strategi ini menggunakan jumlah stop loss yang tetap dan bukan jarak stop loss yang tetap. Ini menghindari masalah risiko yang tidak dapat tetap karena nilai poin yang berbeda antara varietas.

  2. Perhitungan jumlah yang wajar. Strategi dapat secara cerdas menghitung jumlah transaksi berdasarkan jumlah stop loss tetap, sehingga setiap kerugian dapat dikendalikan, sehingga kontrol yang wajar terhadap risiko.

  3. Penembusan identifikasi sederhana dan efektif. Penembusan band identifikasi sederhana dan langsung, yang dapat secara efektif mengidentifikasi arah tren. Penembusan band identifikasi ini dapat mencegah lebih banyak sinyal palsu dari arah tren dibandingkan dengan hanya menembus tingkat harga tertentu.

  4. Pelacakan stop loss meningkatkan keuntungan. Strategi dapat menyesuaikan posisi stop loss secara real time, untuk melacak stop loss, membantu mengunci lebih banyak keuntungan.

  5. Strategi ini dapat digunakan untuk semua jenis, dengan parameter yang tepat, Anda dapat melakukan pengendalian risiko dengan jumlah yang tetap, sehingga memiliki aplikasi yang sangat luas.

  6. Struktur kode yang jelas. Struktur kode kebijakan yang cukup jelas, setiap modul fungsional terurai dengan baik, mudah dipahami dan dioptimalkan selanjutnya.

Analisis risiko

Meskipun strategi ini memiliki keuntungan seperti di atas, ada beberapa risiko yang perlu diperhatikan:

  1. Kualitas breakout tidak dapat dinilai. Kualitas breakout yang tidak dapat dinilai dalam strategi dapat menghasilkan beberapa sinyal berkualitas rendah. Filter diperlukan dalam kombinasi dengan indikator lain.

  2. Stop loss tetap mungkin terlalu mekanis. Harga pasar sering memiliki ciri-ciri pasar yang melompat, dan stop loss tetap mungkin terlalu bergantung pada aturan dan tidak dapat disesuaikan secara fleksibel.

  3. Tidak dapat membatasi frekuensi transaksi. Strategi tidak dapat membatasi frekuensi transaksi, mungkin terlalu sering bermain. Perlu digabungkan dengan aturan lain untuk membatasi frekuensi.

  4. Pengaturan parameter tergantung pada parameter penghentian tetap. Pengaturan jumlah penghentian tetap berkaitan dengan pengendalian celah keseluruhan, yang perlu diatur secara masuk akal sesuai dengan ukuran dana, preferensi risiko, dan banyak lagi.

  5. Breakout direction dapat menghasilkan sinyal yang salah. Breakout signal yang salah dapat dihasilkan ketika harga bergoyang atau berbalik. Perlu dioptimalkan dengan menggabungkan beberapa kondisi.

  6. Kurangnya pengaturan stop-loss. Strategi tidak memiliki mekanisme stop-loss saat ini, sehingga tidak dapat menentukan keuntungan secara proaktif. Ini dapat menyebabkan keuntungan yang tidak diinginkan.

Ada beberapa cara untuk mengoptimalkan risiko yang disebutkan di atas:

  1. Menambahkan indikator untuk menilai bentuk, memfilter kualitas sinyal. Misalnya MACD, KD dll.

  2. Menggabungkan indikator kekuatan terobosan untuk menilai kualitas terobosan. Misalnya, menilai kekuatan terobosan melalui perubahan volume transaksi.

  3. Peningkatan frekuensi pembukaan posisi. Misalnya, hanya berdagang satu kali sehari atau aturan serupa.

  4. Mengoptimalkan logika pengaturan stop loss tetap. Misalnya, mengubah stop loss menjadi persentase stop loss sesuai dengan threshold tertentu.

  5. Menambahkan kondisi penyaringan lainnya. Misalnya, meningkatkan stop loss, volatilitas harga, dan lain-lain.

  6. Tambahkan strategi stop. Misalnya stop saat mendekati resistance.

Arah optimasi

Berdasarkan analisis di atas, strategi ini dapat dioptimalkan dalam beberapa hal:

  1. Menambah kondisi filter, meningkatkan kualitas sinyal. Dapat menambahkan berbagai indikator teknis, menilai kualitas tren, menghindari sinyal breakout yang tidak diinginkan. Dapat juga menilai kekuatan breakout.

  2. Optimalkan strategi stop loss, sehingga lebih fleksibel. Anda dapat mengubah stop loss menjadi stop loss proporsional setelah melewati jarak tertentu. Anda juga dapat mengoptimalkan stop loss jarak secara real-time berdasarkan fluktuasi.

  3. Mengontrol frekuensi transaksi dan menghindari overtrading. Anda dapat mengatur kondisi filter untuk periode waktu atau frekuensi, mengurangi frekuensi transaksi.

  4. Menggabungkan indikator penilaian tren, dan memilih waktu masuk ke lapangan. Misalnya, mengoptimalkan untuk masuk kembali setelah tren dikonfirmasi.

  5. Mengoptimalkan strategi stop loss dan meningkatkan profitabilitas. Anda dapat mengatur target profit, bergerak stop loss, stop loss berfluktuasi dan sebagainya.

  6. Optimalkan pengaturan parameter risiko. Anda dapat mengatur kombinasi parameter yang lebih baik berdasarkan hasil pengukuran, seperti jumlah stop loss tetap, periode penembusan, dll.

  7. Peningkatan struktur kode, peningkatan skalabilitas. Modul-modul seperti signal generation, filter, wind control, dan profitability untuk dekomposisi lebih lanjut.

  8. Uji lebih banyak varietas ruang arbitrase. Evaluasi keuntungan arbitrase dari kombinasi varietas yang berbeda.

Dengan optimasi multi-faceted di atas, dapat meningkatkan stabilitas dan profitabilitas dari strategi breakthrough stop loss. Selain itu, juga membangun dasar untuk memperluas ke lebih banyak portofolio strategi di masa depan.

Meringkaskan

Strategi ini secara keseluruhan masuk akal, menggunakan tren identifikasi break-band, dan menggunakan stop loss tetap untuk pengendalian risiko. Ini adalah kemajuan dalam manajemen risiko. Selain itu, perhitungan jumlah transaksi juga lebih masuk akal, dapat mengontrol setiap kerugian. Namun, strategi ini dapat dioptimalkan dengan berbagai cara untuk meningkatkan kualitas sinyal, fleksibilitas strategi stop loss, dan kesetaraan keuntungan.

Kode Sumber Strategi
/*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)