Type/to search
8
Follow
1361
Followers
Balanced Pending Order Strategy (Teaching Strategy)
Discussions
Created 2022-12-19 17:19:44  Updated 2024-12-10 10:16:29
 0
 853

img

Balanced Pending Order Strategy (Teaching Strategy)

The essence of the strategy described in this article is a dynamic balance strategy, that is, the value of the balance currency is always equal to the value of the valuation currency. However, the strategy logic is very simple when it is designed as pre-pending order. The main purpose of writing this strategy is to show all aspects of strategy design.

  • Strategy logic encapsulation
    Encapsulate the strategy logic with some data and tag variables at runtime (encapsulated as objects).

  • Code for strategy processing initialization
    The initial account information is recorded in the initial run for profit calculation. At the initial runtime, you can choose whether to restore data according to the parameters.

  • Code for strategy interaction processing
    A simple interactive processing of pause and resume is designed.

  • Code for strategy profit calculation
    The currency standard calculation method is used to calculate the profit.

  • Mechanism of key data persistence in the strategy
    Designing mechanisms for recovering data.

  • Code for displaying strategy processing information
    Status bar data display.

Strategy code

pine
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() }

Backtesting

img
img
img
img

Optimization and extension

  • A virtual pending order mechanism can be added. Some exchanges have limited price on pending orders, so the order may not be actually placed. You need to wait until the price is close to the real pending order.
  • Add futures trading.
  • Expand a multi-species and multi-exchange version.

Strategies are for educational purposes only and should be used with caution in real bot trading.
Strategy address: https://www.fmz.com/strategy/225746

Comment
All comments (0)
No data
No data
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)