Ini adalah strategi perdagangan grid dinamis beradaptasi multi-ruang yang ditulis berdasarkan Pine Script. Ide inti dari strategi ini adalah untuk secara otomatis menghitung batas atas dan bawah dari sebuah grid berdasarkan harga tertinggi dan terendah atau rata-rata bergerak sederhana terbaru, dan kemudian membagi rentang tersebut menjadi beberapa garis grid. Ketika harga menyentuh garis grid tertentu, posisi akan dibuka atau ditutup di tempat itu. Dengan cara ini, strategi dapat terus membuka posisi kosong dan mendapatkan keuntungan dari selisih harga dalam situasi yang bergolak.
Menghitung garis atas bawah grid. Berdasarkan pilihan pengguna, garis atas bawah dapat didasarkan pada titik tertinggi dan terendah dari garis N-root K terdekat, dan dapat diatur untuk memperbesar atau mengecilkan persentase; juga dapat didasarkan pada rata-rata bergerak sederhana dari harga penutupan garis N-root K terdekat, dan mengatur rasio penyimpangan ke atas ke bawah.
Hasilkan array baris grille. Berdasarkan jumlah baris grille yang ditetapkan, perbandingan area grille untuk menghasilkan array baris grille yang sesuai dengan harga.
Masuk/meningkatkan posisi. Melalui garis grid dari bawah ke atas, jika harga penutupan saat ini lebih rendah dari harga garis grid tertentu dan garis grid tersebut belum memegang posisi, maka bukalah opsi di posisi tersebut. Dengan demikian, posisi akan terus meningkat ketika harga menyentuh garis grid yang lebih tinggi.
Keluar/menurunkan posisi. Berjalan dari atas ke bawah melalui garis grid, jika harga penutupan saat ini lebih besar dari harga suatu garis grid dan garis grid yang lebih rendah memiliki posisi, maka matikan multipel dari garis grid yang lebih rendah. Dengan demikian, penurunan posisi akan berlanjut ketika harga kembali.
Jika Anda memilih fungsi grid dinamis, setiap baris K akan menghitung ulang batas atas dan bawah grid dan baris grid array, sehingga grid dapat terus beradaptasi dengan perubahan situasi.
Adaptif. Strategi perdagangan grid dapat beradaptasi dengan situasi goncangan dan tren. Dalam situasi goncangan, strategi grid dapat terus membuka posisi kosong, mendapatkan selisih harga; Dalam situasi tren, karena grid mengikuti pergerakan harga, juga dapat mempertahankan posisi tertentu, mendapatkan keuntungan tren.
Risiko dapat dikontrol. Ukuran posisi setiap kali membuka posisi ditentukan oleh jumlah grid yang disetel, celah risiko tunggal kecil dan dapat dikontrol. Selain itu, karena harga menyentuh garis grid di atas, posisi akan mendapatkan keuntungan, dan potensi kerugian terlindungi.
Tingkat otomatisasi yang tinggi. Strategi ini dapat beroperasi secara otomatis, tanpa intervensi manusia, dan cocok untuk investor yang membutuhkan pengembalian yang stabil dan jangka panjang.
Parameter Fleksibel. Pengguna dapat secara fleksibel mengatur jumlah baris grid, parameter grid dinamis, dan lain-lain sesuai dengan karakteristik pasar untuk mengoptimalkan kinerja strategi.
Risiko Black Swan. Jika terjadi penurunan harga yang ekstrem, harga langsung melompat ke bawah garis grid terendah, maka strategi ini akan penuh posisi dan menghadapi penarikan besar. Untuk mengurangi risiko ini, Anda dapat mengatur kondisi stop loss, dan jika kerugian mencapai nilai terendah, Anda akan menutup seluruh posisi.
Parameter grid tidak diatur dengan benar. Jika grid terlalu besar, perbedaan harga setiap kali membuka posisi kosong akan sangat kecil, dan biaya proses dapat mengikis sebagian besar keuntungan. Jika grid terlalu lebar, rasio membuka posisi sekali pakai akan tinggi, dan celah risiko besar.
Strategi ini didasarkan pada harga saat ini yang ditetapkan untuk membuka posisi terbuka. Di pasar seperti futures, jika harga kontrak berbeda jauh dari harga yang ditetapkan, harga posisi terbuka yang sebenarnya mungkin lebih jauh dari yang diharapkan.
Strategi grid tidak bekerja dengan baik dalam tren satu sisi, Anda dapat menambahkan indikator tren sebagai filter, seperti hanya mengaktifkan grid ketika ADX berada di bawah titik terendah tertentu, dan menutup grid ketika tren jelas, hanya memegang posisi satu sisi.
Optimasi sinyal. Anda dapat menumpuk sinyal lain di atas dasar grid, seperti grid + garis rata-rata, yaitu sebagian besar grid memutuskan untuk membuka posisi terbuka, tetapi jika harga melewati garis rata-rata tertentu, maka Anda akan membuka posisi, jika tidak, Anda tidak akan membuka posisi. Dengan demikian, Anda dapat mengurangi biaya yang disebabkan oleh sering membuka posisi terbuka.
Manajemen Posisi. Posisi per barisan strategi saat ini adalah tetap, dapat diatur untuk menurunkan posisi per barisan bila harga jauh dari harga rata-rata pasar, dan meningkatkan posisi ketika mendekati harga rata-rata pasar, untuk meningkatkan efisiensi pemanfaatan dana.
Mengadaptasi kepadatan grid. Mengadaptasi kepadatan grid secara dinamis sesuai dengan fluktuasi harga, jumlah grid dapat ditingkatkan dengan tepat saat fluktuasi tinggi, jumlah grid dapat dikurangi saat fluktuasi rendah. Dengan demikian, lebar grid dapat dioptimalkan, meningkatkan pemanfaatan dana.
Strategi ini adalah strategi kuantitatif linier menengah yang sangat adaptif dengan menyesuaikan diri dengan kisi-kisi dinamis, dapat sering membuka posisi untuk mengambil harga dalam situasi goyah, dan dapat mempertahankan arah celah tertentu untuk mendapatkan keuntungan tren dalam situasi tren. Dengan mengatur logika pemicu dan manajemen posisi grid secara wajar, keuntungan yang stabil dapat dicapai. Namun, perlu memperhatikan risiko pergerakan ekstrem dan harga yang melompat, yang perlu diatur dengan kondisi yang tepat untuk mengendalikan kerugian. Selain itu, ada ruang untuk pengoptimalan lebih lanjut dalam pengaturan parameter dan manajemen risiko, yang dapat meningkatkan stabilitas dan keuntungan yang lebih kuat dari strategi dengan memperkenalkan penyaringan tren, overlay sinyal, manajemen posisi, dan metode kepadatan grid yang adaptif.
// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © jcloyd
//@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)