Design of Order Synchronization Management System Based on FMZ Quant (2)
Tags: fmzquant, order, cryptocurrency, trading
Published: 2024-04-30 03:21:53

### Order Synchronization Management System (Synchronous Server)

Let's continue with the discussion from the previous article: Design of Order Synchronization Management System Based on FMZ Quantification (1) (https://www.fmz.com/digest-topic/9729) and start to design a strategy for synchronized order-following.

Think about several such design issues:

- 1. If you don't want to carry out the synchronous order-follwing temporarily, is it possible to pause it? Once suspended, it is forbidden to start from the extended API, it must be authenticated by the password.
Implement this function by adding 2 global variables:

```
var isStopFollow = false   // Used to mark whether the current order is being followed
var reStartPwd = null      // Used to record the restart password
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijkshexm63pdj5zo2lhh.png)

Then we add interactive controls on the strategy editing page for strategy pause/restart (not to stop the real bot, just logic pause, no more order-following). We can set a pause password when pausing, so that even with your real bot of extended API KEY of Order Synchronization Management System Class Library (Single Server) end, it can not wake up your strategy. When restarting the order-following, enter the preset password to wake up the order-following function.
Code for the implementation of the relevant functions:

```
...
          // Judge the interaction command
          if (arr.length == 2) {
          	// Buttons with controls
          	if (arr[0] == "stop/restart") {
          		// Pause/restart order-following
          		if (!isStopFollow) {
          		    isStopFollow = true
          		    reStartPwd = arr[1]
          		    Log("it has stopped the order-following,", "Set the restart password as:", reStartPwd, "#FF0000")
          		} else if (isStopFollow && arr[1] == reStartPwd) {
          			isStopFollow = false 
          			reStartPwd = null 
          			Log("it has restarted the order-following, ", "Clear the restart password.", "#FF0000")
          		} else if (isStopFollow && arr[1] != reStartPwd) {
          			Log("Restart password error!")
          		}
          	}
          	continue 
          }
```

- 2. You can specify the amount of orders to be followed or can be scaled in multiples
Add parameters to the strategy:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hq5t4mcaibl9jz4ioe29.png)

specifiedAmount: Specify the number of order-following, the default is -1, i.e. not specified.
zoomAmountRatio: Scaling according to the amount of orders sent, for example, if the signal sent is: ETH_USDT,swap,buy,1, multiply the value of the amount of orders by zoomAmountRatio. The default is -1, i.e. no scaling.

```
    var amount = specifiedAmount == -1 ? action.amount : specifiedAmount
    amount = zoomAmountRatio == -1 ? amount : amount * zoomAmountRatio
```

Here it is implemented to scale or specify a specific value for the amount of orders to be followed in the received signal.

- 3. The code shall be as simple as possible, use other template libraries to place an order.

The class library used by spot orders placed: https://www.fmz.com/strategy/10989
The class library used by future orders placed: https://www.fmz.com/strategy/203258

```
  function trade(action) {
      // Switch trading pairs and set up contracts
      exchange.SetCurrency(action.symbol)
      if (action.ct != "spot") {
          exchange.SetContractType(action.ct)        
      }        

      var retTrade = null 
      var amount = specifiedAmount == -1 ? action.amount : specifiedAmount
      amount = zoomAmountRatio == -1 ? amount : amount * zoomAmountRatio    

      if (action.direction == "buy") {
          retTrade = action.ct == "spot" ? $.Buy(amount) : $.OpenLong(exchange, action.ct, amount)
      } else if (action.direction == "sell") {
          retTrade = action.ct == "spot" ? $.Sell(amount) : $.OpenShort(exchange, action.ct, amount)
      } else if (action.direction == "closebuy") {
          retTrade = action.ct == "spot" ? $.Sell(amount) : $.CoverLong(exchange, action.ct, amount)
      } else if (action.direction == "closesell") {
          retTrade = action.ct == "spot" ? $.Buy(amount) : $.CoverShort(exchange, action.ct, amount)
      }
      return retTrade
  }
```

So we can see that placing an order just need one sentence: $.Sell(amount), $.Buy(amount), $.OpenLong(exchange, action.ct, amount). etc.

### Strategy code:
The temporary code of previous Order Synchronous Management System (Synchronous Server) was as follows:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/la0pwvts9gb9wbde66bg.png)

Now we start redesigning the Order Synchronization Management System (Synchronous Server):

```
// Global variables
var isStopFollow = false
var reStartPwd = null 

function trade(action) {
    // Switch trading pairs and set up contracts
    exchange.SetCurrency(action.symbol)
    if (action.ct != "spot") {
        exchange.SetContractType(action.ct)        
    }    

    var retTrade = null 
    var amount = specifiedAmount == -1 ? action.amount : specifiedAmount
    amount = zoomAmountRatio == -1 ? amount : amount * zoomAmountRatio

    if (action.direction == "buy") {
        retTrade = action.ct == "spot" ? $.Buy(amount) : $.OpenLong(exchange, action.ct, amount)
    } else if (action.direction == "sell") {
    	retTrade = action.ct == "spot" ? $.Sell(amount) : $.OpenShort(exchange, action.ct, amount)
    } else if (action.direction == "closebuy") {
    	retTrade = action.ct == "spot" ? $.Sell(amount) : $.CoverLong(exchange, action.ct, amount)
    } else if (action.direction == "closesell") {
    	retTrade = action.ct == "spot" ? $.Buy(amount) : $.CoverShort(exchange, action.ct, amount)
    }
    return retTrade
}

function parseCmd(cmd) {
	var objAction = {}
	// Parse cmd, such as: ETH_USDT,swap,buy,1
    var arr = cmd.split(",")
    if (arr.length != 4) {
    	return null 
    }
    objAction.symbol = arr[0]
    objAction.ct = arr[1]
    objAction.direction = arr[2]
    objAction.amount = arr[3]
    return objAction
}

function main() {
	// Clear all logs
    LogReset(1)  

    if (isSimulateOKEX) {
    	exchange.IO("simulate", true)
    	Log("Switch to OKEX demo!")
    }

    // Set accuracy
    exchange.SetPrecision(pricePrecision, amountPrecision)

    // Check zoom and specify it cannot be set at the same time
    if (specifiedAmount != -1 && zoomAmountRatio != -1) {
    	throw "it cannot specify simultaneous volume and scaling volume at the same time"
    }

    while (true) {
        var cmd = GetCommand()
        if (cmd) {
            Log("cmd: ", cmd)
            var arr = cmd.split(":")

            // Judge interaction commands
            if (arr.length == 2) {
            	// Buttons with controls
            	if (arr[0] == "stop/restart") {
            		// Pause/restart order-following
            		if (!isStopFollow) {
            		    isStopFollow = true
            		    reStartPwd = arr[1]
            		    Log("it has stopped the order-following.", "Set the restart password as.", reStartPwd, "#FF0000")
            		} else if (isStopFollow && arr[1] == reStartPwd) {
            			isStopFollow = false 
            			reStartPwd = null 
            			Log("it has restarted the order-following", "Clear the restart password.", "#FF0000")
            		} else if (isStopFollow && arr[1] != reStartPwd) {
            			Log("Restart password error!")
            		}
            	}
            	continue 
            }
            
            // Permission to follow orders
            if (!isStopFollow) {
                // Resolve the interaction instructions of order-following signal
                var objAction = parseCmd(cmd)
                if (objAction) {
            	    // The analysis is correct
            	    var ret = trade(objAction)
                } else {
                	Log("Wrong signal command cmd:", cmd)
                }
            }
        }
        
        // Display order-following status
        LogStatus(_D(), isStopFollow ? "Stop Synchronization" : "Keep Synchronization", "\n")

        Sleep(1000)
    }
}
```

### Test

We test the order-leading account by using the Binance real bot for this time, and we use the OKX account for order-following real bot. For order-leading, we still use the main function in the test function (Order Synchronization Management System Class Library (Single Server) in the template) used in the previous article.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/opcbusaw84hwae1e7tvm.png)

Here we change the direction of the transaction to "sell", and the volume of the transaction to 0.003 (Orders can be placed in decimal numbers for Binance USDT standard contracts). But order-following for OKEX account must be an integer number (OKEX exchange orders must be a whole number), so we specify the strategy parameter specifiedAmount as 1.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2vmwdirq2giuqlb2dd4e.png)

Next, let's test closing the position by changing the direction of the order in the test main function to close the short position by 0.003.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/53gm385rx9qwdkosxprn.png)

Then we run it again, which is responsible for the order-leading (Order Synchronization Management System Class Library (Single Server)).

The same operation was triggered by order-following real bot.

The strategy address:
Order Synchronization Management System Class Library (Single Server) (https://www.fmz.com/strategy/345171)
Order Synchronization Management System (Synchronous Server) (https://www.fmz.com/strategy/345172)

The strategy is designed for communication and learning only, please adjust and optimize according to the actual needs.

From: https://blog.mathquant.com/2022/10/25/design-of-order-synchronization-management-system-based-on-fmz-quant-2.html