Bản chất của chiến lược được mô tả trong bài viết này là một chiến lược cân bằng năng động, nghĩa là giá trị của đồng tiền cân bằng luôn bằng giá trị của đồng tiền định giá. Tuy nhiên, logic chiến lược rất đơn giản khi nó được thiết kế như một lệnh chờ. Mục đích chính của việc viết chiến lược này là để hiển thị tất cả các khía cạnh của thiết kế chiến lược.
Chiến lược logic encapsulation Tích hợp logic chiến lược với một số biến dữ liệu và thẻ tại thời gian chạy (được đóng gói dưới dạng đối tượng).
Mã để khởi tạo xử lý chiến lược Thông tin tài khoản ban đầu được ghi lại trong lần chạy ban đầu để tính toán lợi nhuận.
Mã xử lý tương tác chiến lược Một quá trình xử lý tương tác đơn giản của tạm dừng và tiếp tục được thiết kế.
Mã tính toán lợi nhuận chiến lược Phương pháp tính toán tiêu chuẩn tiền tệ được sử dụng để tính lợi nhuận.
Cơ chế duy trì dữ liệu chính trong chiến lược Thiết kế các cơ chế phục hồi dữ liệu.
Mã để hiển thị thông tin xử lý chiến lược Hiển thị dữ liệu thanh trạng thái.
var Shannon = {
// member
e : exchanges[0],
arrPlanOrders : [],
distance : BalanceDistance,
account : null,
ticker : null,
initAccount : null,
isAskPending : false,
isBidPending : false,
// function
CancelAllOrders : function (e) {
while(true) {
var orders = _C(e.GetOrders)
if(orders.length == 0) {
return
}
Sleep(500)
for(var i = 0; i < orders.length; i++) {
e.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
}
},
Balance : function () {
if (this.arrPlanOrders.length == 0) {
this.CancelAllOrders(this.e)
var acc = _C(this.e.GetAccount)
this.account = acc
var askPendingPrice = (this.distance + acc.Balance) / acc.Stocks
var bidPendingPrice = (acc.Balance - this.distance) / acc.Stocks
var askPendingAmount = this.distance / 2 / askPendingPrice
var bidPendingAmount = this.distance / 2 / bidPendingPrice
this.arrPlanOrders.push({tradeType : "ask", price : askPendingPrice, amount : askPendingAmount})
this.arrPlanOrders.push({tradeType : "bid", price : bidPendingPrice, amount : bidPendingAmount})
} else if(this.isAskPending == false && this.isBidPending == false) {
for(var i = 0; i < this.arrPlanOrders.length; i++) {
var tradeFun = this.arrPlanOrders[i].tradeType == "ask" ? this.e.Sell : this.e.Buy
var id = tradeFun(this.arrPlanOrders[i].price, this.arrPlanOrders[i].amount)
if(id) {
this.isAskPending = this.arrPlanOrders[i].tradeType == "ask" ? true : this.isAskPending
this.isBidPending = this.arrPlanOrders[i].tradeType == "bid" ? true : this.isBidPending
} else {
Log("Pending order failed, clear!")
this.CancelAllOrders(this.e)
return
}
}
}
if(this.isBidPending || this.isAskPending) {
var orders = _C(this.e.GetOrders)
Sleep(1000)
var ticker = _C(this.e.GetTicker)
this.ticker = ticker
if(this.isAskPending) {
var isFoundAsk = false
for (var i = 0; i < orders.length; i++) {
if(orders[i].Type == ORDER_TYPE_SELL) {
isFoundAsk = true
}
}
if(!isFoundAsk) {
Log("Selling order filled, cancel the order, reset")
this.CancelAllOrders(this.e)
this.arrPlanOrders = []
this.isAskPending = false
this.isBidPending = false
LogProfit(this.CalcProfit(ticker))
return
}
}
if(this.isBidPending) {
var isFoundBid = false
for(var i = 0; i < orders.length; i++) {
if(orders[i].Type == ORDER_TYPE_BUY) {
isFoundBid = true
}
}
if(!isFoundBid) {
Log("Buying order filled, cancel the order, reset")
this.CancelAllOrders(this.e)
this.arrPlanOrders = []
this.isAskPending = false
this.isBidPending = false
LogProfit(this.CalcProfit(ticker))
return
}
}
}
},
ShowTab : function() {
var tblPlanOrders = {
type : "table",
title : "Plan pending orders",
cols : ["direction", "price", "amount"],
rows : []
}
for(var i = 0; i < this.arrPlanOrders.length; i++) {
tblPlanOrders.rows.push([this.arrPlanOrders[i].tradeType, this.arrPlanOrders[i].price, this.arrPlanOrders[i].amount])
}
var tblAcc = {
type : "table",
title : "Account information",
cols : ["type", "Stocks", "FrozenStocks", "Balance", "FrozenBalance"],
rows : []
}
tblAcc.rows.push(["Initial", this.initAccount.Stocks, this.initAccount.FrozenStocks, this.initAccount.Balance, this.initAccount.FrozenBalance])
tblAcc.rows.push(["This", this.account.Stocks, this.account.FrozenStocks, this.account.Balance, this.account.FrozenBalance])
return "Time:" + _D() + "\n `" + JSON.stringify([tblPlanOrders, tblAcc]) + "`" + "\n" + "ticker:" + JSON.stringify(this.ticker)
},
CalcProfit : function(ticker) {
var acc = _C(this.e.GetAccount)
this.account = acc
return (this.account.Balance - this.initAccount.Balance) + (this.account.Stocks - this.initAccount.Stocks) * ticker.Last
},
Init : function() {
this.initAccount = _C(this.e.GetAccount)
if(IsReset) {
var acc = _G("account")
if(acc) {
this.initAccount = acc
} else {
Log("Failed to restore initial account information! Running in initial state!")
_G("account", this.initAccount)
}
} else {
_G("account", this.initAccount)
LogReset(1)
LogProfitReset()
}
},
Exit : function() {
Log("Cancel all pending orders before stopping...")
this.CancelAllOrders(this.e)
}
}
function main() {
// Initialization
Shannon.Init()
// Main loop
while(true) {
Shannon.Balance()
LogStatus(Shannon.ShowTab())
// Interaction
var cmd = GetCommand()
if(cmd) {
if(cmd == "stop") {
while(true) {
LogStatus("Pause", Shannon.ShowTab())
cmd = GetCommand()
if(cmd) {
if(cmd == "continue") {
break
}
}
Sleep(1000)
}
}
}
Sleep(5000)
}
}
function onexit() {
Shannon.Exit()
}
Các chiến lược chỉ dành cho mục đích giáo dục và nên được sử dụng thận trọng trong giao dịch bot thực sự. Địa chỉ chiến lược:https://www.fmz.com/strategy/225746