Chiến lược giao dịch lưới điện (www.fmz.com) Ý tưởng cơ bản của giao dịch lưới giao dịch rất đơn giản. Thay vì đặt một giao dịch, chúng ta đặt nhiều giao dịch tạo thành một mô hình lưới giao dịch. Thông thường chúng được nhập dưới dạng lệnh dừng hoặc giới hạn xung quanh mức giá hiện tại nhưng không phải lúc nào cũng vậy. Tôi sẽ giải thích chi tiết hơn về điều này dưới đây, nhưng đó là ý tưởng cơ bản.
Giao dịch lưới điện là gì và nó hoạt động như thế nào? Giao dịch lưới là một trò chơi về biến động thị trường. Có hai lý do tại sao nó được các nhà giao dịch ưa thích. Thứ nhất là nó không yêu cầu bạn có dự đoán xác định về hướng thị trường.
Thứ hai là nó hoạt động tốt trong thị trường biến động, nơi không có xu hướng rõ ràng
Giao dịch lưới là một loại giao dịch phân tích kỹ thuật dựa trên sự chuyển động trong các mô hình lưới cụ thể. Giao dịch lưới phổ biến trong giao dịch ngoại hối. Nhìn chung, kỹ thuật này tìm cách tận dụng sự biến động giá bình thường trên thị trường bằng cách đặt lệnh mua và bán ở khoảng thời gian thường xuyên nhất định trên và dưới một mức giá cơ bản đã xác định trước.
Mạng lưới có thể tùy chỉnh hướng
Hoạt động giao dịch cơ bản: mua trước và sau đó bán.
Mạng lưới sẽ bắt đầu gửi lệnh mua ở mức giá dưới mức giá đầu tiên, đó là mức giá theo sau mức giá đầu tiên (giá mua mới nhất thứ hai, giá mua mới nhất thứ ba... và vân vân).
Sau khi bất kỳ lệnh mua được hoàn thành, chương trình sẽ dựa trên giá mua, thêm giá của các tham số
Bán ngắn trước và sau đó mua để bảo hiểm: hoạt động chỉ là ngược lại
Rủi ro lớn nhất của chiến lược này là khi xu hướng thị trường chuyển động một bên, và biến động giá vượt quá lưới.
Mã sau đây đã tạo ra lưới với chức năng dừng mất tự động và chuyển động.
Nhận xét:
Chiến lược sử dụng thiết kế lệnh chờ ảo, cung cấp rất nhiều xử lý cho sàn giao dịch để hạn chế số lượng lệnh chờ, và giải quyết vấn đề một cách linh hoạt.
Khung logic là linh hoạt trong thiết kế và thông minh trong cấu trúc.
Tính toán lợi nhuận và lỗ, mỗi thuật toán thống kê số có thể được sử dụng để tham khảo, và mỗi thiết kế phát hiện điều kiện đều nghiêm ngặt. (để giảm thiểu khả năng BUG)
Mã nguồn rất đáng để học.
Để biết thêm thông tin, vui lòng xem:
https://www.fmz.com/strategy/112633
Mã nguồn:
// Mã nguồn: /* Các thông số giao diện (được hiển thị dưới dạng biến toàn cầu trong mã) Hộp thả xuống hướng OpType Grid (được chọn) Mua trước rồi bán. FirstPriceAuto giá ban đầu tự động boolean (true/false) true FirstPrice@!FirstPriceAuto giá ban đầu số (số) 100 AllNum tổng số số (số) 10 PriceGrid Dải giá số (số) 1 Giá khác nhau số (số) 2 Số tiềnTập kích thước đơn đặt hàng hộp thả xuống (được chọn) mua và bán cùng một số tiền AmountOnce@AmountType==0 Số lượng giao dịch duy nhất 0.1 BAmountOnce@AmountType==1 Đơn đặt hàng kích thước số (số) 0.1 SAmountOnce@AmountType==1 Kích thước đơn đặt hàng số (số) 0.1 AmountCoefficient@AmountType==0 Sự khác biệt số lượng Dòng (dòng) *1 AmountDot Số điểm thập phân (số) 3 EnableProtectDiff bật bảo vệ chênh lệch Boolean (true/false) false ProtectDiff@EnableProtectDiff Entry spread Giá bảo vệ số (số) 20 CancelAllWS stop hủy tất cả các lệnh đang chờ (true/false) true CheckInterval số khoảng thời gian bỏ phiếu số (số) 2000 Trọng trệ khoảng thời gian thử lại số (số) 1300 RestoreProfit khôi phục lại lợi nhuận cuối cùng Boolean (true/false) false Lợi nhuận cuối cùng (số) Lợi nhuậnAsOrg@RestoreProfit Lợi nhuận cuối cùng được tính là giá trung bình Boolean (true/false) false EnableAccountCheck cho phép xác minh số dư (true/false) EnableStopLoss@EnableAccountCheck mở Stop Loss Boolean (true/false) false StopLoss@EnableStopLoss số lượng lỗ lưu động tối đa (số) 100 StopLossMode@EnableStopLoss Hoạt động mất mát sau khi dừng Quảng trường thả xuống (được chọn) Quá khứ hồi và thoát ra. EnableStopWin@EnableAccountCheck bật Take Profit Boolean (true/false) false StopWin@EnableStopWin Lợi nhuận biến động tối đa Loại số (số) 120 StopWinMode@EnableStopWin hộp thả xuống sau khi thực hiện hoạt động kiếm lợi nhuận (được chọn) Phân chế và thoát ra. AutoMove@EnableAccountCheck tự động Di chuyển Boolean (true/false) false MaxDistance@AutoMove khoảng cách tối đa số (số) 20 MaxIdle@AutoMove tối đa trống (giây) số (số) 7200 EnableDynamic Chuyển các lệnh đang chờ động Boolean (true/false) false DynamicMax@EnableDynamic Distance order expiry Số (số) 30 ResetData xóa tất cả dữ liệu khi khởi động Boolean (true/false) true Giá chính xác chiều dài thập phân số (số) 5 */
function hasOrder ((orders, orderId) { // Kiểm tra xem có một lệnh với ID lệnh trong các lệnh tham số for (var i = 0; i < orders.length; i++) { // Chuyển qua các lệnh để kiểm tra xem có cùng id không, nếu có thì trả về true if (order[i].Id == orderId) { trả về true; } } trả về sai; // Tất cả đi qua, không kích hoạt nếu có nghĩa là chưa tìm thấy thứ tự với ID orderId, trả về sai }
function cancelPending() { // Hủy tất cả các chức năng đặt hàng đang chờ var ret = false; // Set return success tag biến while (true) { // while loop if (ret) { // Nếu ret là đúng sau đó ngủ trong một thời gian nhất định Giấc ngủ ((Interval); } var orders = _C(exchange.GetOrders); // Gọi API để nhận thông tin lệnh mà trao đổi đã không thực hiện. if (orders.length == 0) { // Nếu một mảng trống được trả về, trao đổi không có lệnh chưa thực hiện. break; // nhảy ra khỏi vòng lặp while }
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
}
function valuesToString(values, pos) { // Giá trị chuyển đổi thành một chuỗi
var result =
chức năng Trader() { // chức năng Trader, sử dụng đóng cửa.
var vId = 0; // ID tăng lệnh
var orderBooks = []; // Sổ đơn đặt hàng
var hisBooks = []; // Sách thứ tự lịch sử
var orderBooksLen = 0; // Chiều dài sổ đặt hàng
this.Buy = function ((giá, số tiền, thêm) { // Buying function, parameters: price, quantity, extended information
if (typeof(extra) ===
if (orders[i].Id == order.Id) { // Khi bạn tìm thấy một thứ tự với cùng một id thứ tự trong orderBooks, gán một giá trị của true để tìm, có nghĩa là tìm.
tìm thấy = true;
break; // nhảy ra khỏi vòng lặp hiện tại
}
}
if (!found) { // Nếu không tìm thấy, đẩy orderBooks[orderId] đến các lệnh.
orders.push ((orderBooks[orderId]); // Tại sao bạn muốn đẩy như thế này?
}
}
lệnh trả lại; // lệnh trả lại
}
this.GetOrder = function ((orderId) { // Get 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)
cancelPending ((); // Call the custom function cancelPending (()) to cancel all pending orders (gọi hàm tùy chỉnh cancelPending (()) để hủy tất cả các lệnh đang chờ.
var nowAccount = _C ((exchange.GetAccount); // Declare a variable nowAccount to record the latest information about the account at the moment.
var slidePrice = 0.2; // Set the slip price when placing the order as 0.2 Đặt giá trượt khi đặt lệnh là 0.2
var ok = true; // Tag variable initially set true (Tạm dịch:
while (true) { // while 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, thì giá trị tuyệt đối của sự khác biệt tiền tệ là nhỏ hơn so với khối lượng giao dịch tối thiểu của sàn giao dịch.
// the break jumps out of the loop and does not perform balancing operations. // the break nhảy ra khỏi vòng lặp và không thực hiện các hoạt động cân bằng.
break;
var STATE_WAIT_OPEN = 0; // Được sử dụng cho trạng thái của mỗi nút trong fishTable var STATE_WAIT_COVER = 1; //... var STATE_WAIT_CLOSE = 2; //... var ProfitCount = 0; // Hồ sơ lợi nhuận và lỗ var BuyFirst = true; // Các thông số giao diện ban đầu var IsSupportGetOrder = true; // xác định hỗ trợ trao đổi chức năng GetOrder API, một biến toàn cầu, được sử dụng để xác định sự khởi đầu của chức năng chính var LastBusy = 0; // ghi lại đối tượng thời gian được xử lý cuối cùng
function setBusy() { // Set Busy time LastBusy = new Date(); // Đặt LastBusy vào đối tượng thời gian hiện tại }
function isTimeout() { // Xác định nếu nó thời gian ra if (MaxIdle <= 0) { // Thời gian không hoạt động tối đa (dựa trên việc lưới được di chuyển tự động hay không), // nếu thời gian trống tối đa MaxIdle được đặt nhỏ hơn hoặc bằng 0 return false; // trả về false, không đánh giá thời gian hết. nghĩa là, luôn trả về false mà không có thời gian hết. } var now = new Date(); // Nhận đối tượng thời gian hiện tại if (((now.getTime() - LastBusy.getTime()) / 1000) >= MaxIdle) { // Sử dụng hàm getTime của đối tượng thời gian hiện tại để lấy dấu thời gian và dấu thời gian của LastBusy để tính toán sự khác biệt, // Chia cho 1000 để tính số giây giữa hai đối tượng thời gian. // Xác định nếu nó lớn hơn thời gian trống tối đa MaxIdle LastBusy = bây giờ; // Nếu nó lớn hơn, cập nhật LastBusy đối tượng thời gian hiện tại bây giờ trả về đúng; // trả về đúng, đó là một thời gian nghỉ. } trả về sai; // trả về sai không có thời gian hết }
chức năng onexit ((() { // Chức năng đóng khi chương trình kết thúc.
if (CancelAllWS) { // Để hủy tất cả các lệnh đang chờ khi dừng lại, gọi cancelPending() để hủy tất cả các lệnh đang chờ.
Log ((
chức năng đánh cá ((orgĐếm, đánh cáĐếm) { // Các thông số đúc: thông tin tài khoản, số lượng đúc
setBusy(); // Đặt LastBuys vào dấu thời gian hiện tại
var account = _C(exchange.GetAccount); // Xác định một biến tài khoản để có được thông tin tài khoản hiện tại và gán nó.
Log ((account); // Tạo ra thông tin tài khoản vào đầu cuộc gọi đến chức năng đánh bắt.
var InitAccount = tài khoản; // Xác định một biến InitAccount và gán nó với tài khoản.
// đúc này, được sử dụng để tính toán lợi nhuận và lỗ nổi.
var ticker = _C(exchange.GetTicker); // Nhận giá báo giá được gán cho biến ticker được tuyên bố
var amount = _N(AmountOnce); // Theo số tham số giao diện, sử dụng _N để xử lý các vị trí thập phân (_N mặc định là 2 bit) và gán chúng cho số lượng.
var amountB = [amount]; // Xác định một biến số gọi là amountB là một mảng, khởi tạo một phần tử với amount
var amountS = [amount]; // Xác định một biến gọi là amountS...
if (typeof(AmountType)!==
}
// Bắt đầu bảng cá
var fishTable = {}; // Xác định một đối tượng lưới
var uuidTable = {}; // Đối tượng bảng mã nhận dạng
var needStocks = 0; // Các đồng xu cần thiết biến
var needMoney = 0; // Chất biến tiền yêu cầu
var actualNeedMoney = 0;
var actualNeedStocks = 0; // Thực sự cần tiền xu
var notEnough = false; // Đổi biến thẻ thiếu tài trợ, ban đầu được đặt thành false
var canNum = 0; // Mạng lưới có sẵn
cho (var idx = 0; idx < AllNum; idx++) { // Cấu trúc được đi qua theo số lưới AllNum.
var price = _N((BuyFirst? FirstPrice - (idx * PriceGrid) : FirstPrice + (idx * PriceGrid)), Precision);
// Khi đi qua cấu trúc, cài đặt giá chỉ số idx hiện tại được đặt theo BuyFirst. Khoảng cách giữa mỗi giá chỉ số là PriceGrid.
needStocks += amountS[idx]; // Số lượng tiền xu bán được tích lũy dần dần theo chu kỳ. (được tích lũy bởi mảng số lượng lệnh bán cho needStocks từng cái một)
needMoney += giá * số tiềnB[idx]; // Số tiền cần mua được tích lũy dần dần theo chu kỳ. (.... mua mảng số lượng đơn đặt hàng một một...)
if (BuyFirst) { // xử lý mua trước
nếu (_N(needMoney) <= _N(account.Balance)) { // Nếu lưới yêu cầu ít tiền hơn số tiền có sẵn trên tài khoản
actualNeedMondy = needMoney; // Được gán cho số tiền thực tế cần thiết
actualNeedStocks = needStocks; // Đặt số lượng tiền xu thực tế cần thiết. Có gì sai với điều này không?
canNum++; // Số lượng tích lũy các lưới có sẵn
Nếu điều kiện này không được đáp ứng, hãy đặt biến tag underfunded thành true
notEnough = true;
}
} else { // xử lý bán đầu tiên
if (_N(needStocks) <= _N(account.Stocks)) { // Kiểm tra xem số lượng tiền xu cần có ít hơn số lượng tiền xu có sẵn trong tài khoản
actualNeedMondy = needMoney; // Assignment
actualNeedStocks = needStocks;
canNum++; // Số lượng tích lũy các lưới có sẵn
{ \ cHFFFFFF }
notEnough = true; // Đặt true nếu các điều kiện tài trợ không được đáp ứng
}
}
fishTable[idx] = STATE_WAIT_OPEN; // Theo chỉ số idx hiện tại, thiết lập trạng thái của thành viên idx (đường dây lưới) của đối tượng lưới,
// ban đầu STATE_WAIT_OPEN (chờ để mở vị trí)
uuidTable[idx] = -1; // Đối tượng được đánh số cũng khởi tạo giá trị idx của riêng nó (cốt tương ứng với fishTable) thành -1 dựa trên idx hiện tại.
}
if (!EnableAccountCheck && (canNum < AllNum)) { // Nếu kiểm tra quỹ không được bật, và số lưới (tổng số nút) nơi nút nhỏ hơn
// hơn là cài đặt tham số giao diện có thể được mở.
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