Ini adalah strategi perdagangan grid cryptocurrency adaptif berdasarkan metodologi perdagangan grid untuk arbitrase. Ini dapat secara otomatis menyesuaikan kisaran harga perdagangan grid berdasarkan fluktuasi pasar dan melakukan perdagangan arbitrase yang efisien dalam kisaran harga tersebut.
Ide inti dari strategi ini adalah:
Menghitung rentang harga grid perdagangan secara dinamis berdasarkan harga tinggi dan rendah historis.
Tetapkan N garis grid pada interval yang sama dalam kisaran harga ini.
Ketika harga menembus setiap garis grid, buka posisi panjang atau pendek dengan jumlah tetap.
Arbitrage antara garis grid berdekatan dan posisi dekat untuk keuntungan.
Ketika harga kembali memasuki kisaran grid, terus membuka posisi dengan biaya marginal dari jalur grid.
Ulangi siklus ini untuk perdagangan arbitrase frekuensi tinggi dalam kisaran harga grid.
Secara khusus, strategi pertama menghitung batas atas dan bawah grid secara real time sesuai dengan jendela lookback yang dikonfigurasi (i_boundLookback) dan rentang volatilitas (i_boundDev) parameter.
Kemudian N garis grid (i_gridQty) dibagi rata antara batas atas dan bawah. Harga garis grid ini disimpan dalam array gridLineArr.
Ketika harga menembus garis grid, jumlah tetap (modal strategi dibagi dengan jumlah grid) digunakan untuk membuka posisi panjang atau pendek.
Ketika harga menembus garis grid yang berdekatan lagi, itu dapat dicocokkan dengan pesanan sebelumnya untuk arbitrase dan posisi tertutup untuk keuntungan.
Ulangi siklus ini untuk arbitrage frekuensi tinggi dalam kisaran fluktuasi harga.
Dibandingkan dengan strategi jaringan tradisional, keuntungan terbesar dari strategi ini adalah bahwa rentang jaringan disesuaikan secara otomatis untuk beradaptasi dengan fluktuasi pasar, dengan karakteristik berikut:
sepenuhnya otomatis, tidak perlu intervensi manual.
Mampu menangkap tren harga dan perdagangan ke arah tren.
Risiko yang dapat dikendalikan, menghindari risiko mengejar secara sepihak.
Frekuensi perdagangan yang tinggi dan margin keuntungan.
Mudah dimengerti, konfigurasi sederhana.
Penggunaan modal tinggi, tidak mudah terperangkap.
Mencerminkan perubahan pasar secara real time, cocok untuk perdagangan algoritmik.
Meskipun strategi ini memiliki banyak keuntungan, ada juga beberapa risiko, terutama terkonsentrasi di:
Potensi kerugian yang lebih besar dalam perubahan harga yang ekstrim.
Membutuhkan periode kepemilikan yang tepat dan pasangan perdagangan untuk mendapatkan keuntungan.
Skala modal harus sesuai dengan rentang volatilitas.
Mungkin memerlukan pemantauan dan optimalisasi parameter yang sering.
Tindakan penanggulangan meliputi:
Meningkatkan jarak grid untuk memperluas jangkauan grid.
Pilih pasangan perdagangan yang lebih stabil.
Sesuaikan skala modal untuk likuiditas yang cukup.
Menetapkan mekanisme pemantauan dan peringatan otomatis.
Strategi dapat dioptimalkan dalam aspek berikut:
Grid dinamis: secara otomatis menyesuaikan parameter grid berdasarkan volatilitas.
Mekanisme Stop Loss: menetapkan lokasi stop loss yang wajar untuk membatasi risiko ekstrem.
Grid komposit: menggabungkan grid menggunakan parameter yang berbeda untuk periode yang berbeda untuk memaksimalkan penggunaan waktu.
Pembelajaran mesin: menggunakan jaringan saraf untuk mengoptimalkan parameter secara otomatis alih-alih aturan.
Arbitrage lintas pasar: arbitrase antara bursa atau pasangan mata uang.
Singkatnya, ini adalah strategi perdagangan grid crypto yang sangat praktis untuk arbitrase. Dibandingkan dengan strategi grid tradisional, fitur terbesarnya adalah penyesuaian otomatis kisaran grid berdasarkan perubahan pasar, yang memungkinkan pedagang untuk mengkonfigurasi kisaran perdagangan mereka sendiri. Logika strategi jelas dan mudah dipahami dan dikonfigurasi, cocok untuk investor individu dengan beberapa dasar dan juga sebagai templat untuk algoritma perdagangan. Dengan penyesuaian parameter yang tepat, efisiensi pemanfaatan modal yang sangat tinggi dapat dicapai.
/*backtest start: 2024-01-11 00:00:00 end: 2024-01-18 00:00:00 period: 1m basePeriod: 1m 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 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 strategy.initial_capital = 50000 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)