Strategi Perdagangan Grid Teori Samudra

Penulis:ChaoZhang, Tanggal: 2023-10-13 17:07:39
Tag:

Gambaran umum

Strategi ini memanfaatkan metode perdagangan grid dalam teori lautan untuk menempatkan pesanan beli dan jual dalam kisaran harga yang telah ditetapkan sebelumnya.

Logika Strategi

Strategi ini pertama-tama menghitung batas atas dan bawah dari grid harga berdasarkan pilihan pengguna atau pengaturan default. Ada dua cara perhitungan: mendapatkan harga tertinggi dan terendah dalam periode backtesting, atau menghitung moving average selama jangka waktu. Kemudian garis grid didistribusikan secara merata sesuai dengan jumlah grid yang ditetapkan oleh pengguna.

Sinyal perdagangan dihasilkan berdasarkan hubungan antara harga dan garis grid. Ketika harga berada di bawah garis grid, posisi panjang dibuka pada harga garis grid dengan kuantitas tetap; ketika harga naik di atas garis grid, posisi ditutup di garis grid di bawah. Karena harga berfluktuasi di dalam grid, posisi berubah sesuai untuk mendapatkan keuntungan.

Secara khusus, strategi ini mempertahankan array harga garis kisi dan array bool yang menunjukkan apakah pesanan ditempatkan di setiap baris. Ketika harga berada di bawah garis tanpa pesanan, posisi panjang dibuka di baris; ketika harga berada di atas garis sementara pesanan ada di baris di bawah, posisi ditutup di garis bawah.

Keuntungan

  1. Jangkauan grid dihitung secara otomatis, menghindari kesulitan pengaturan manual.

  2. Garis grid didistribusikan secara merata untuk menghindari overtrading karena grid yang padat.

  3. Metode perdagangan grid secara efektif mengendalikan risiko. Keuntungan dapat diperoleh selama harga berfluktuasi dalam grid.

  4. Tidak ada asumsi arah harga, cocok untuk pasar yang terikat kisaran.

  5. Pengaturan komisi dan ukuran posisi yang dapat disesuaikan untuk instrumen perdagangan yang berbeda.

  6. Visualisasi garis grid membantu memahami situasi perdagangan.

Risiko

  1. Pelanggaran batas atas atau bawah jaringan dapat menyebabkan kerugian yang lebih besar.

  2. Risiko ruang jaringan yang berlebihan. Jaringan yang terlalu longgar tidak dapat memperoleh keuntungan dengan mudah sementara yang terlalu sempit meningkatkan biaya. Keseimbangan diperlukan.

  3. Risiko kepemilikan jangka panjang membuat keuntungan sulit namun meningkatkan biaya.

  4. Risiko pengaturan parameter yang tidak tepat. Periode backtesting atau periode rata-rata bergerak dapat mempengaruhi perhitungan rentang grid jika ditetapkan secara tidak tepat.

  5. Risiko pasar sistemik. Lebih cocok untuk pasar yang terikat rentang daripada pasar yang cenderung jangka panjang.

Peningkatan

  1. Mengoptimalkan parameter grid. secara komprehensif mempertimbangkan kondisi pasar, biaya, dll untuk mengoptimalkan jumlah grid, periode lookback, dll.

  2. Memperkenalkan penyesuaian rentang grid dinamis. Mengadaptasi rentang grid ketika terjadi perubahan pasar yang signifikan.

  3. Mengintegrasikan mekanisme stop loss. Menetapkan garis stop loss yang tepat untuk membatasi kerugian. Dapat disesuaikan secara dinamis.

  4. Tambahkan filter menggunakan indikator lain seperti Bollinger Bands, indikator tren dll untuk menghindari perdagangan yang tidak benar.

  5. Meningkatkan efisiensi penggunaan modal. Memperkenalkan analisis volatilitas untuk mengurangi perdagangan selama periode yang stabil.

Kesimpulan

Strategi ini mewujudkan perdagangan rentang yang dapat dikontrol risiko dengan memanfaatkan prinsip perdagangan grid. Perhitungan grid otomatis dan distribusi seragam menawarkan keuntungan yang sesuai dengan berbagai pasar melalui penyesuaian parameter. Risiko terbatas dan mudah dioperasikan. Namun, keterbatasan ada dan perbaikan terus-menerus diperlukan untuk beradaptasi dengan pasar yang berkembang. Secara keseluruhan, strategi ini memberikan pendekatan standar dan parametris untuk menerapkan perdagangan grid.


/*backtest
start: 2023-09-12 00:00:00
end: 2023-10-12 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("(IK) Grid Script", overlay=true, pyramiding=14, close_entries_rule="ANY", default_qty_type=strategy.cash, initial_capital=100.0, currency="USD", commission_type=strategy.commission.percent, commission_value=0.1)
i_autoBounds    = input(group="Grid Bounds", title="Use Auto Bounds?", defval=true, type=input.bool)                             // calculate upper and lower bound of the grid automatically? This will theorhetically be less profitable, but will certainly require less attention
i_boundSrc      = input(group="Grid Bounds", title="(Auto) Bound Source", defval="Hi & Low", options=["Hi & Low", "Average"])     // should bounds of the auto grid be calculated from recent High & Low, or from a Simple Moving Average
i_boundLookback = input(group="Grid Bounds", title="(Auto) Bound Lookback", defval=250, type=input.integer, maxval=500, minval=0) // when calculating auto grid bounds, how far back should we look for a High & Low, or what should the length be of our sma
i_boundDev      = input(group="Grid Bounds", title="(Auto) Bound Deviation", defval=0.10, type=input.float, maxval=1, minval=-1)  // if sourcing auto bounds from High & Low, this percentage will (positive) widen or (negative) narrow the bound limits. If sourcing from Average, this is the deviation (up and down) from the sma, and CANNOT be negative.
i_upperBound    = input(group="Grid Bounds", title="(Manual) Upper Boundry", defval=0.285, type=input.float)                      // for manual grid bounds only. The upperbound price of your grid
i_lowerBound    = input(group="Grid Bounds", title="(Manual) Lower Boundry", defval=0.225, type=input.float)                      // for manual grid bounds only. The lowerbound price of your grid.
i_gridQty       = input(group="Grid Lines",  title="Grid Line Quantity", defval=8, maxval=15, minval=3, type=input.integer)       // how many grid lines are in your grid
strategy.initial_capital = 50000
f_getGridBounds(_bs, _bl, _bd, _up) =>
    if _bs == "Hi & Low"
        _up ? highest(close, _bl) * (1 + _bd) : lowest(close, _bl)  * (1 - _bd)
    else
        avg = sma(close, _bl)
        _up ? avg * (1 + _bd) : avg * (1 - _bd)

f_buildGrid(_lb, _gw, _gq) =>
    gridArr = array.new_float(0)
    for i=0 to _gq-1
        array.push(gridArr, _lb+(_gw*i))
    gridArr

f_getNearGridLines(_gridArr, _price) =>
    arr = array.new_int(3)
    for i = 0 to array.size(_gridArr)-1
        if array.get(_gridArr, i) > _price
            array.set(arr, 0, i == array.size(_gridArr)-1 ? i : i+1)
            array.set(arr, 1, i == 0 ? i : i-1)
            break
    arr

var upperBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true) : i_upperBound  // upperbound of our grid
var lowerBound      = i_autoBounds ? f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false) : i_lowerBound // lowerbound of our grid
var gridWidth       = (upperBound - lowerBound)/(i_gridQty-1)                                                       // space between lines in our grid
var gridLineArr     = f_buildGrid(lowerBound, gridWidth, i_gridQty)                                                 // an array of prices that correspond to our grid lines
var orderArr        = array.new_bool(i_gridQty, false)                                                              // a boolean array that indicates if there is an open order corresponding to each grid line

var closeLineArr    = f_getNearGridLines(gridLineArr, close)                                                        // for plotting purposes - an array of 2 indices that correspond to grid lines near price
var nearTopGridLine = array.get(closeLineArr, 0)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line above current price
var nearBotGridLine = array.get(closeLineArr, 1)                                                                    // for plotting purposes - the index (in our grid line array) of the closest grid line below current price

for i = 0 to (array.size(gridLineArr) - 1)
    if close < array.get(gridLineArr, i) and not array.get(orderArr, i) and i < (array.size(gridLineArr) - 1)
        buyId = i
        array.set(orderArr, buyId, true)
        strategy.entry(id=tostring(buyId), long=true, qty=(strategy.initial_capital/(i_gridQty-1))/close, comment="#"+tostring(buyId))
    if close > array.get(gridLineArr, i) and i != 0
        if array.get(orderArr, i-1)
            sellId = i-1
            array.set(orderArr, sellId, false)
            strategy.close(id=tostring(sellId), comment="#"+tostring(sellId))

if i_autoBounds
    upperBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, true)
    lowerBound  := f_getGridBounds(i_boundSrc, i_boundLookback, i_boundDev, false)
    gridWidth   := (upperBound - lowerBound)/(i_gridQty-1)
    gridLineArr := f_buildGrid(lowerBound, gridWidth, i_gridQty)

closeLineArr    := f_getNearGridLines(gridLineArr, close)
nearTopGridLine := array.get(closeLineArr, 0)
nearBotGridLine := array.get(closeLineArr, 1)



Lebih banyak