Strategi perdagangan jaringan
(www.fmz.com)
Ide dasar dari perdagangan grid sangat sederhana. Alih-alih menempatkan satu perdagangan, kita menempatkan beberapa perdagangan membentuk pola grid. Biasanya ini dimasukkan sebagai
Apa itu perdagangan grid dan bagaimana cara kerjanya?
Perdagangan grid adalah permainan pada volatilitas pasar. Ada dua alasan mengapa itu disukai oleh pedagang. Yang pertama adalah bahwa itu tidak
Yang kedua adalah bahwa itu bekerja dengan baik di pasar yang tidak stabil, di mana tidak ada tren yang jelas
perdagangan grid adalah jenis perdagangan analisis teknis yang didasarkan pada pergerakan dalam pola grid tertentu. perdagangan grid populer dalam perdagangan valuta asing. secara keseluruhan teknik ini bertujuan untuk memanfaatkan volatilitas harga normal di pasar dengan menempatkan pesanan beli dan jual pada interval reguler tertentu di atas dan di bawah harga dasar yang telah ditentukan sebelumnya. pesanan beli dan jual tersebut, umumnya berjarak pada interval 10 atau 15 unit, membuat grid perdagangan.
Grid dapat menyesuaikan arah
Operasi perdagangan dasar: beli dulu dan kemudian jual.
Grid akan mulai mengirim order pembelian pada harga yang di bawah harga pertama, yang merupakan harga yang diikuti oleh harga pertama (harga pembelian terbaru kedua, harga pembelian terbaru ketiga...dan seterusnya).
Setelah setiap pesanan pembelian selesai, program akan berdasarkan harga pembelian, menambahkan harga dari
Menjual pendek pertama dan kemudian membeli untuk menutupi: operasi adalah kebalikan
Risiko terbesar dari strategi ini adalah ketika tren pasar bergerak secara sepihak, dan fluktuasi harga melebihi grid.
Kode berikut telah membuat grid dengan stop loss otomatis dan fungsi gerakan.
Komentar:
Strategi ini menggunakan desain pesanan tertunda virtual, yang menyediakan banyak pemrosesan untuk pertukaran untuk membatasi jumlah pesanan tertunda, dan memecahkan masalah secara fleksibel.
Logika grid fleksibel dalam desain dan cerdas dalam struktur.
Perhitungan keuntungan dan kerugian, setiap algoritma statistik numerik dapat digunakan sebagai referensi, dan setiap desain deteksi kondisi yang ketat.
Kode sumber sangat layak dipelajari.
Untuk informasi lebih lanjut, silakan lihat:
https://www.fmz.com/strategy/112633
Kode sumber:
// Kode sumber: /* Parameter antarmuka (ditampilkan sebagai variabel global dalam kode) OpType Grid Direction Drop-down box (dipilih) Beli dulu lalu jual. FirstPriceAuto harga awal otomatis boolean (benar/salah) benar FirstPrice@!FirstPriceAuto harga awal numerik (nomor) 100 AllNumber total jumlah numerik (jumlah) 10 PriceGrid Interval harga numerik (nomor) 1 PriceDiff spread numerik (nomor) 2 JumlahJenis ukuran pesanan kotak drop-down (dipilih) membeli dan menjual jumlah yang sama AmountOnce@AmountType==0 Jumlah transaksi tunggal numerik (nomor) 0.1 BAmountOnce@AmountType==1 Ukuran pesanan pembelian numerik (nomor) 0.1 SAmountOnce@AmountType==1 Ukuran pesanan penjualan numerik (nomor) 0.1 JumlahCoefficient@AmountType==0 Perbedaan kuantitas String (string) *1 JumlahDot Titik desimal numerik (angka) 3 EnableProtectDiff Mengaktifkan perlindungan spread Boolean (benar/salah) false ProtectDiff@EnableProtectDiff Spread Entry Perlindungan harga numerik (nomor) 20 CancelAllWS stop membatalkan semua pesanan yang menunggu Boolean (benar/salah) benar CheckInterval nomor interval pemungutan suara numerik (nomor) 2000 Interval kegagalan interval percobaan ulang numerik (nomor) 1300 RestoreProfit mengembalikan keuntungan terakhir Boolean (benar/salah) false LastProfit@RestoreProfit Keuntungan terakhir Nomor (nomor) 0 ProfitAsOrg@RestoreProfit Keuntungan terakhir dihitung sebagai harga rata-rata Boolean (benar/salah) false EnableAccountCheck memungkinkan verifikasi saldo Boolean (benar/salah) benar EnableStopLoss@EnableAccountCheck buka Stop Loss Boolean (benar/salah) false StopLoss@EnableStopLoss kerugian maksimum yang mengambang numerik (jumlah) 100 StopLossMode@EnableStopLoss Operasi stop loss drop-down box (dipilih) Daur ulang dan keluar EnableStopWin@EnableAccountCheck Mengaktifkan Take Profit Boolean (benar/salah) false StopWin@EnableStopWin Keuntungan maksimum variabel Jenis nomor (nomor) 120 StopWinMode@EnableStopWin kotak drop-down operasi setelah mengambil keuntungan (dipilih) Daur ulang dan keluar AutoMove@EnableAccountCheck auto Move Boolean (benar/salah) false MaxDistance@AutoMove jarak maksimum numerik (nomer) 20 MaxIdle@AutoMove maksimal kosong (detik) numerik (nomor) 7200 EnableDynamic Menghidupkan order yang sedang menunggu secara dinamis Boolean (benar/salah) false DynamicMax@EnableDynamic order expiry distance Nomor (nomor) 30 ResetData menghapus semua data pada startup Boolean (true/false) true Harga presisi panjang desimal numerik (angka) 5 */
fungsi hasOrder ((order, orderId) { // Periksa apakah ada order dengan order ID dalam parameter order for (var i = 0; i < orders.length; i++) { // Melalui perintah untuk memeriksa apakah ada id yang sama, jika ada maka kembali benar jika (perintah[i].Id == orderId) { kembali benar; {\cH00FFFF} {\cH00FFFF} kembali false; // Semua dilalui, tidak ada pemicu jika berarti belum menemukan urutan dengan ID orderId, kembali false {\cH00FFFF}
fungsi cancelPending() { // Batalkan semua fungsi pesanan yang sedang menunggu var ret = false; // Tentukan variabel tag keberhasilan kembali sementara (benar) { // sementara loop jika (ret) { // Jika ret benar maka tidur untuk waktu tertentu Tidur ((Interval); {\cH00FFFF} var orders = _C(exchange.GetOrders); // Panggil API untuk mendapatkan informasi pesanan yang tidak dieksekusi pertukaran. if (orders.length == 0) { // Jika array kosong dikembalikan, pertukaran tidak memiliki perintah yang belum dilaksanakan. istirahat; // Melompat keluar dari loop sementara {\cH00FFFF}
for (var j = 0; j < orders.length; j++) { // Traverse the unfinished order array and use orders[j].Id one by one to cancel the order based on the index j.
exchange.CancelOrder(orders[j].Id, orders[j]);
ret = true; // Once there is a cancel operation, ret is assigned a value of true. Used to trigger above Sleep, wait for re-exchange.GetOrders detection
}
}
return ret; // return ret
}
nilai fungsiToString(nilai, pos) { // Nilai dikonversi ke string
var result =
fungsi Trader() { // Trader fungsi, menggunakan penutupan.
var vId = 0; // ID peningkatan pesanan
var orderBooks = []; // Buku pesanan
var hisBooks = []; // Buku urutan historis
var orderBooksLen = 0; // Panjang buku pesanan
this.Buy = fungsi ((harga, jumlah, tambahan) { // Fungsi pembelian, parameter: harga, kuantitas, informasi lanjutan
if (typeof(extra) ===
jika (order[i].Id == order.Id) { // Ketika Anda menemukan order dengan id order yang sama di orderBooks, atributkan nilai true untuk menemukan, yang berarti menemukan.
ditemukan = benar;
istirahat; // Melompat keluar dari loop saat ini
{\cH00FFFF}
{\cH00FFFF}
if (!found) { // Jika tidak ditemukan, tekan orderBooks[orderId] ke order.
orders.push ((orderBooks[orderId]); // Mengapa Anda ingin mendorong seperti ini?
{\cH00FFFF}
{\cH00FFFF}
perintah kembali; // perintah kembali
{\cH00FFFF}
ini.GetOrder = fungsi ((orderId) { // Dapatkan order
if (typeof(orderId) ===
var pfn = order.Type == ORDER_TYPE_BUY ? exchange.Buy : exchange.Sell; // Assign the corresponding API function reference to pfn according to the type of the order.
// That is, if the order type is a buy order, pfn is a reference to the exchange.Buy function, the same as the sell order.
if (order.Id == 0 && diff <= priceDiff) { // If the order order in the order book is not activated (ie Id is equal to 0) and the current price is less than or
// equal to the order plan price, the priceDiff passed in the parameter.
var realId = pfn(order.Price, order.Amount, order.Extra + "(distance: " + diff + (order.Type == ORDER_TYPE_BUY ? (" ask price: " + ticker.Buy) : (" bid price: " + ticker.Sell))+")");
// Execute order function, parameter passing price, quantity, order extension information + pending order distance + market data (ask price or bid price), return exchange order id
if (typeof(realId) === 'number') { // If the returned realId is a numeric type
order.Id = realId; // Assign the Id attribute of the current order order to the order book.
}
} else if (order.Id > 0 && diff > (priceDiff + 1)) { // If the order is active and the current distance is greater than the distance passed in by the parameter
var ok = true; // Declare a variable for tagging Initially set true
do { // Execute "do" first and then judge while
ok = true; // Ok assign true
exchange.CancelOrder(order.Id, "unnecessary" + (order.Type == ORDER_TYPE_BUY ? "buying" : "selling"), "placed order price:", order.Price, "volume:", order.Amount, ", distance:",
diff, order.Type == ORDER_TYPE_BUY ? ("ask price: " + ticker.Buy) : ("bid price: " + ticker.Sell));
// Cancel the pending order that is out of range. After canceling the order, print the current order information and the current distance diff.
Sleep(200); // Wait 200 milliseconds
orders = _C(exchange.GetOrders); // Call the API to get an uncompleted order in the exchange.
for (var i = 0; i < orders.length; i++) { // Traverse these unfinished orders.
if (orders[i].Id == order.Id) { // If the cancelled order is found in the list of orders that have not been completed by the exchange
ok = false; // Assign ok this variable to false, that is, no cancellation is successful.
}
}
} while (!ok); // If ok is false, then !ok is true and while will continue to repeat the loop, continue to cancel the order,
// and check if the cancellation is successful.
order.Id = 0; // Assigning a value of 0 to order.Id means that the current order is inactive.
}
}
};
}
function balanceAccount ((orgAccount, initAccount) { // Balance Account Function Parameter Initial account information when the strategy is started (Inisial informasi akun ketika strategi dimulai)
Call the custom function cancelPending (); // Call the custom function cancelPending ();) to cancel all pending orders (); // Call the custom function cancelPending (); // Call the custom function cancelPending ();) to cancel all pending orders (); // Call the custom function cancelPending (); // Call the custom function cancelPending ()) to cancel all pending orders ().
Var nowAccount = _C ((exchange.GetAccount); // Declare a variable nowAccount to record the latest information about the account at the moment (Deklarasikan variabel nowAccount untuk merekam informasi terbaru tentang akun saat ini).
Set the slip price when placing the order as 0.2 Set the slip price when placing the order as 0.2 Set the slip price when placing the order as 0.2
var ok = true; // Tag variable initially set true
while (true) { // sementara loop
var diff = _N ((nowAccount.Stocks - initAccount.Stocks); // Calculate the difference between the current account and the initial account diff
if (Math.abs(diff) < exchange.GetMinStock()) { // If the absolute value of the currency difference is less than the minimum transaction volume of the exchange, maka nilai absolut dari perbedaan mata uang adalah
// the break jumps out of the loop dan tidak melakukan balancing operations.
"Mengenai apa yang terjadi?"
Aku tidak tahu.
var depth = _C ((exchange.GetDepth); // Get the exchange depth information Assign to the declared depth variable (Mendapatkan informasi tentang kedalaman pertukaran Atur ke variabel kedalaman yang dinyatakan)
var books = diff > 0? depth.Bids : depth.Asks; // According to the difference of the currency is greater than 0 or less than 0, extract the buy order array or
// sell order array in depth (equal to 0 tidak akan diproses, it is break when it is judged to be less than GetMinStock)
// The difference between the coins is greater than 0 to sell the balance, so look at the buy order array, dan lihatlah di sini.
// the difference between the coins is less than 0 is the opposite. / the difference between the coins is less than 0 is the opposite. / the difference between the coins is less than 0 is the opposite. / the difference between the coins is less than 0 is the opposite.
var n = 0; // Statement n initial is 0
harga var = 0;
for (var i = 0; i < books.length; i++) { // Traversing the buy or sell order array
n += books[i].Amount; // Accumulate Amount (order quantity) for each order based on the index i traversed Jumlah untuk setiap order berdasarkan indeks yang saya lalui
if (n >= Math.abs ((diff)) { // If the cumulative order quantity n is greater than or equal to the currency difference, then:
price = books[i].Price; // Get the price of the current indexed order, assign it to price (Mendapatkan harga dari pesanan terindeks saat ini, atasi ke harga)
break; // Jump out of the current for traversal cycle (Jump keluar dari arus untuk siklus traversal)
Aku tidak tahu.
Aku tidak tahu.
VAR Pfn = diff > 0? exchange.Sell: exchange.Buy; // Pass the sell order API (exchange.Sell) or the next buy order API (exchange.Buy) reference to the declared pfn
// berdasarkan perbedaan mata uang lebih besar dari 0 atau kurang dari 0
var amount = Math.abs(diff); // The amount of the order to be balanced is diff, the difference in the currency, assigned to the declared amount variable.
var price = diff > 0? (price - slidePrice) : (price + slidePrice); // The direction of buying and selling according to the difference in the currency, increase or decrease the
// Slip price based on the price (slip price is to make it easier to trade), and then assign it to price (harga slip adalah untuk memudahkan perdagangan), dan kemudian atasi ke harga
Log ((
var STATE_WAIT_OPEN = 0; // Digunakan untuk status setiap node di fishTable var STATE_WAIT_COVER = 1; //... var STATE_WAIT_CLOSE = 2; //... var ProfitCount = 0; // Catatan laba rugi var BuyFirst = benar; // Parameter antarmuka awal var IsSupportGetOrder = true; // menentukan pertukaran dukungan fungsi GetOrder API, variabel global, digunakan untuk menentukan awal fungsi utama var LastBusy = 0; // Catat objek waktu yang diproses terakhir
fungsi setBusy() { // Set Busy time LastBusy = new Date(); // Atur LastBusy ke objek waktu saat ini {\cH00FFFF}
fungsi isTimeout() { // Menentukan apakah waktu keluar jika (MaxIdle <= 0) { // Waktu kosong maksimum (berdasarkan apakah grid dipindahkan secara otomatis), // jika maksimum waktu kosong MaxIdle ditetapkan kurang dari atau sama dengan 0 return false; // Mengembalikan false, tidak menilai timeout. yaitu, selalu mengembalikan false tanpa timeout. {\cH00FFFF} var now = new Date ((); // Dapatkan objek waktu saat ini jika (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { // Gunakan fungsi getTime dari objek waktu saat ini untuk mendapatkan timestamp dan timestamp LastBusy untuk menghitung perbedaan, // Berbagi dengan 1000 untuk menghitung jumlah detik antara dua objek waktu. // Tentukan apakah lebih besar dari waktu kosong maksimum MaxIdle LastBusy = sekarang; // Jika lebih besar dari, update LastBusy ke objek waktu saat ini sekarang return true; // Mengembalikan true, yang merupakan timeout. {\cH00FFFF} return false; // Return false tidak ada timeout {\cH00FFFF}
fungsi onexit() { // Fungsi penutupan ketika program keluar.
if (CancelAllWS) { // Untuk membatalkan semua pesanan yang menunggu saat berhenti, panggil cancelPending() untuk membatalkan semua pesanan yang menunggu.
Log ((
fungsi perikanan ((orgAngka, ikanAngka) { // Parameter casting: informasi akun, jumlah casting
setBusy(); // Atur LastBuys ke timestamp saat ini
var account = _C(exchange.GetAccount); // Mengisyaratkan variabel akun untuk mendapatkan informasi akun saat ini dan menugaskannya.
Log ((account); // Output informasi akun pada awal panggilan ke fungsi memancing.
var InitAccount = account; // Mengisyaratkan variabel InitAccount dan menugaskannya dengan account.
// ini casting, digunakan untuk menghitung keuntungan dan kerugian mengambang.
var ticker = _C(exchange.GetTicker); // Dapatkan nilai penawaran yang ditugaskan pada variabel ticker yang dinyatakan
var amount = _N(AmountOnce); // Sesuai dengan jumlah parameter antarmuka, gunakan _N untuk memproses tempat desimal (_N default ke 2 bit) dan menetapkannya ke jumlah.
var amountB = [jumlah]; // Mengisyaratkan variabel yang disebut jumlahB adalah array, menginisialisasi elemen dengan jumlah
var amountS = [jumlah]; // Mengumumkan variabel yang disebut jumlahS...
if (typeof(AmountType)!==
{\cH00FFFF}
// Inisialisasi tabel ikan
var fishTable = {}; // Mendeklarasikan objek kisi
var uuidTable = {}; // Objek tabel kode identifikasi
var needStocks = 0; // Variabel koin yang dibutuhkan
var needMoney = 0; // Variabel uang yang dibutuhkan
var actualNeedMoney = 0; // Sebenarnya membutuhkan uang
var actualNeedStocks = 0; // Koin yang sebenarnya dibutuhkan
var notEnough = false; // Variabel tag yang kurang didanai, awalnya ditetapkan menjadi false
var canNum = 0; // Grid yang tersedia
untuk (var idx = 0; idx < AllNum; idx++) { // Struktur dilalui sesuai dengan jumlah kisi AllNum.
var price = _N((BuyFirst? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), Keakuratan);
// Saat melintasi konstruksi, pengaturan harga indeks idx saat ini ditetapkan sesuai dengan BuyFirst. Jarak antara setiap harga indeks adalah PriceGrid.
needStocks += amountS[idx]; // Jumlah koin yang terjual secara bertahap terkumpul dengan siklus. (dikumpulkan oleh array kuantitas pesanan jual untuk needStocks satu per satu)
needMoney += harga * jumlahB[idx]; // Jumlah uang yang diperlukan untuk membeli secara bertahap terakumulasi dengan siklus.
jika (BuyFirst) { // Mengatasi beli pertama
jika (_N(needMoney) <= _N(account.Balance)) { // Jika grid membutuhkan lebih sedikit uang daripada jumlah uang yang tersedia di akun
actualNeedMondy = needMoney; // Ditugaskan untuk jumlah uang yang sebenarnya diperlukan
actualNeedStocks = needStocks; // Menugaskan jumlah koin yang sebenarnya diperlukan.
canNum++; // Jumlah kumulatif kisi-kisi yang tersedia
Jika kondisi ini tidak terpenuhi, atur variabel tag underfunded menjadi true
notEnough = benar;
{\cH00FFFF}
} lainnya { // penanganan menjual pertama
jika (_N(needStocks) <= _N(account.Stocks)) { // Periksa apakah jumlah koin yang diperlukan kurang dari jumlah koin yang tersedia di akun
actualNeedMondy = needMoney; // Penugasan
actualNeedStock = needStock;
canNum++; // Jumlah kumulatif kisi-kisi yang tersedia
{\cH00FFFF} lainnya
notEnough = true; // Tentukan true jika kondisi pendanaan tidak terpenuhi
{\cH00FFFF}
{\cH00FFFF}
fishTable[idx] = STATE_WAIT_OPEN; // Berdasarkan indeks idx saat ini, atur status anggota idx (node grid) dari objek grid,
// awalnya STATE_WAIT_OPEN (menunggu untuk membuka posisi)
uuidTable[idx] = -1; // Objek bernomor juga menginisialisasi nilai idx sendiri (nodus yang sesuai dengan fishTable) menjadi -1 berdasarkan idx saat ini.
{\cH00FFFF}
if (!EnableAccountCheck && (canNum < AllNum)) { // Jika pemeriksaan dana tidak diaktifkan, dan jumlah kisi (jumlah total node) di mana node lebih kecil
// dari pengaturan parameter antarmuka dapat dibuka.
Log ((
throw
var trader = new Trader(); // Constructs a Trader object, assigning it to the trader variable declared here.
var OpenFunc = BuyFirst ? exchange.Buy : exchange.Sell; // According to whether to buy and sell first, set the open function OpenFunc to refer to exchange.Buy or exchange.Sell
var CoverFunc = BuyFirst ? exchange.Sell : exchange.Buy; // same as above
if (EnableDynamic) { // Set OpenFunc/CoverFunc again according to whether the interface parameter EnableDynamic is enabled.
OpenFunc = BuyFirst ? trader.Buy : trader.Sell; // The member function Buy that references the trader object is used for dynamic pending orders (mainly because
// some exchanges limit the number of pending orders, so virtual dynamic pending orders are required)
CoverFunc = BuyFirst ? trader.Sell : trader.Buy; // same as above
}
var ts = new Date(); // Create a time object at this time (assigned to ts) to record the time at the moment.
var preMsg = ""; // Declare a variable to record the last message, the initial set to empty string
var profitMax = 0; // Maximum return
while (true) { // The main logic after the grid is casted
var now = new Date(); // Record the time when the current cycle started
var table = null; // Declare a variable
if (now.getTime() - ts.getTime() > 5000) { // Calculate whether the difference between the current time now and the recorded time ts is greater than 5000 milliseconds
if (typeof(GetCommand) == 'function' && GetCommand() == "Receiving grid") { // Check if the strategy interaction control command "receives the grid" is received,
// stops and balances to the initial state.
Log("Start executing commands to perform grid operations"); // Output information
balanceAccount(orgAccount, InitAccount); // Perform a balancing function to balance the number of coins to the initial state
return false; // This time the grid function is fishing and return false
}
ts = now; // Update ts with current time now for next comparison time
var nowAccount = _C(exchange.GetAccount); // Declare the nowAccount variable and initially been set as the current account information.
var ticker = _C(exchange.GetTicker); // Declare the ticker variable and initially been set as the current market information.
if (EnableDynamic) { // If you enable dynamic pending orders
trader.Poll(ticker, DynamicMax); // Call the Poll function of the trader object to detect and process all orders based on the
// current ticker market and the interface parameter DynamicMax.
}
var amount_diff = (nowAccount.Stocks + nowAccount.FrozenStocks) - (InitAccount.Stocks + InitAccount.FrozenStocks); // Calculate the current coin difference
var money_diff = (nowAccount.Balance + nowAccount.FrozenBalance) - (InitAccount.Balance + InitAccount.FrozenBalance); // Calculate the current money difference
var floatProfit = _N(money_diff + (amount_diff * ticker.Last)); // Calculate the current floating profit and loss of this time of casting grid
var floatProfitAll = _N((nowAccount.Balance + nowAccount.FrozenBalance - orgAccount.Balance - orgAccount.FrozenBalance) + ((nowAccount.Stocks + nowAccount.FrozenStocks
- orgAccount.Stocks - orgAccount.FrozenStocks) * ticker.Last));
// Calculate the overall floating profit and loss
var isHold = Math.abs(amount_diff) >= exchange.GetMinStock(); // If the absolute value of the coin difference at this moment is greater than the minimum trading
// volume of the exchange, it means that the position has been held.
if (isHold) { // If you have already held a position, execute the setBusy() function, which will update the LastBusy time.
setBusy(); // That is, after opening the position, the opening of the opening mechanism is started.
}
profitMax = Math.max(floatProfit, profitMax); // Refresh the maximum floating profit and loss
if (EnableAccountCheck && EnableStopLoss) { // If you initiate account detection and start a stop loss
if ((profitMax - floatProfit) >= StopLoss) { // If the maximum floating profit or loss minus the current floating profit or loss is greater than or equal to
// the maximum floating loss value, execute the code inside the curly braces
Log("Current floating profit a