Implement a quantitative trading robot timed start or stop gadget by using Python
Tags: python, robot, fmzquant, trading
Published: 2024-05-11 09:08:07

As a powerful, flexible and easy to use quantitative trading platform for the whole network, the FMZ Quant Trading Platform has very low barriers to use, and the robot program takes up few resources. But we still hope that the robot can start when it needs to run and stop when it doesn't need to run.
For example, the non-opening time accounts for the vast majority of the whole day when conducting program and quantitative trading of commodity futures. In this way, we do hope that the robot will only run at the opening time, and that it will only run at the opening time every day to save money. Isn't it exciting? To meet this requirement, we can use Python language to write a strategy robot running on the FMZ Quant Trading Platform, and let the robot control the start and stop of the robot at regular intervals through the extended API interface of the FMZ Quant Trading Platform.

### If there is a need, let's do it!
In fact, the whole code is very simple. The example of calling the FMZ Quant Trading Platform extension API interface can be used directly.

Address: https://www.fmz.com/api#simple example

Use the function in the example directly: def api (method, *args)
The interface we need to call is also very simple. The following two interfaces are used (can be found in the FMZ document)

- RestartRobot
Restart the robot interface and pass in the parameters into the robot ID.
Use specific id to call: api ('RestartRobot', id)

- StopRobot
To stop the robot interface, the parameters are also the robot ID.
Robot ID:

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

To call the FMZ Quant Trading Platform extension API, you need to use the API KEY of the FMZ Quant Trading Platform.
You can generate your own API KEY in account management.
We pass in the API KEY as a strategy parameter.
The screenshot of getting the FMZ Quant Trading Platform account API KEY:

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

The rest is to write timing logic, which is also very simple. Set timing parameters:
```
["175708,14:55:33-15:10:33", ...]
```
The ellipsis indicates that more settings like "175708,14:55:33-15:10:33" can be set.
The timing parameter is a JSON string, which will be parsed into a list in the strategy code. Each element in the list is a set of robot start/stop settings.
Namely:
```
"175708,14:55:33-15:10:33"
```
They are separated by commas. The part before the comma 175708 is the robot ID, and the part after the comma is the start time/stop time.
In the above example, the robot with ID 175708 starts at 14:55:33 and stops at 15:10:33.

Then, in the strategy, the robot will keeps rotating. Each round rotation will first obtain the current time, and then judge whether to trigger the start or stop of the robot according to the comparison between the current time and the timing time.
If triggered, call the api ('RestartRobot ', id) or api ('StopRobot', id) to start and stop the robot.

Complete strategy code:
```
# -*- coding: utf-8 -*-
import time
import json

try:
    import md5
    import urllib2
    from urllib import urlencode
except:
    import hashlib as md5
    import urllib.request as urllib2
    from urllib.parse import urlencode

def api(method, *args):
    d = {
        'version': '1.0',
        'access_key': accessKey,
        'method': method,
        'args': json.dumps(list(args)),
        'nonce': int(time.time() * 1000),
        }

    d['sign'] = md5.md5(('%s|%s|%s|%d|%s' % (d['version'], d['method'], d['args'], d['nonce'], secretKey)).encode('utf-8')).hexdigest()
    return json.loads(urllib2.urlopen('https://www.fmz.com/api/v1', urlencode(d).encode('utf-8')).read().decode('utf-8'))

RobotParams = json.loads(strRobotParams)

def main():
    global RobotParams 
    arrParams = []
    nowDay = 0
    strPush = ""
    if isPushMsg:
        strPush = "@"

    for i in range(len(RobotParams)):
        param = {}
        arr = RobotParams[i].split(",")
        if len(arr) != 2:
            raise Exception("String configuration error: delimiter,")
        param["id"] = arr[0]
        param["isProcessOpenThisDay"] = False
        param["isProcessCloseThisDay"] = False

        arr = arr[1].split("-")
        if len(arr) != 2:
            raise Exception("String configuration error: delimiter-")

        begin = arr[0]
        arrBegin = begin.split(":")
        if len(arrBegin) != 3:
            raise Exception("String configuration error: start time separator:")
        
        param["begin"] = {}
        param["begin"]["hour"] = float(arrBegin[0])
        param["begin"]["min"] = float(arrBegin[1])
        param["begin"]["sec"] = float(arrBegin[2])

        end = arr[1]
        arrEnd = end.split(":")
        if len(arrEnd) != 3:
            raise Exception("String configuration error: end time separator:")            
        
        param["end"] = {}
        param["end"]["hour"] = float(arrEnd[0])
        param["end"]["min"] = float(arrEnd[1])
        param["end"]["sec"] = float(arrEnd[2])
        arrParams.append(param)

    # Test
    Log("Output parameters", arrParams, "#FF0000")  

    while True:
        nowTime = time.localtime(time.time())
        nowHour = nowTime.tm_hour 
        nowMin = nowTime.tm_min
        nowSec = nowTime.tm_sec
        
        tbl = {
            "type" : "table", 
            "title" : "msg", 
            "cols" : ["id", "begin", "end", "Did you perform a start today", "Did you perform a stop today"],
            "rows" : []
        }

        for i in range(len(arrParams)):
            tbl["rows"].append([arrParams[i]["id"], json.dumps(arrParams[i]["begin"]), json.dumps(arrParams[i]["end"]), arrParams[i]["isProcessOpenThisDay"], arrParams[i]["isProcessCloseThisDay"]])
            if nowDay != nowTime.tm_mday:
                arrParams[i]["isProcessOpenThisDay"] = False
                arrParams[i]["isProcessCloseThisDay"] = False

            if arrParams[i]["isProcessOpenThisDay"] == False:
                if nowTime.tm_hour == arrParams[i]["begin"]["hour"] and nowTime.tm_min >= arrParams[i]["begin"]["min"] and nowTime.tm_sec >= arrParams[i]["begin"]["sec"]:
                    ret = api('RestartRobot', int(arrParams[i]["id"]))                    
                    arrParams[i]["isProcessOpenThisDay"] = True
                    Log("Robot ID:", arrParams[i]["id"], "Execution started, please log in to the platform to check if it started successfully", "Extended API return value:", ret, strPush)

            if arrParams[i]["isProcessCloseThisDay"] == False:
                if nowTime.tm_hour == arrParams[i]["end"]["hour"] and nowTime.tm_min >= arrParams[i]["end"]["min"] and nowTime.tm_sec >= arrParams[i]["end"]["sec"]:
                    ret = api('StopRobot', int(arrParams[i]["id"]))
                    arrParams[i]["isProcessCloseThisDay"] = True
                    Log("Robot ID:", arrParams[i]["id"], "Execution stopped, please log in to the platform to check if it stopped successfully", "Extended API return value:", ret, strPush)
        
        if nowDay != nowTime.tm_mday:
            nowDay = nowTime.tm_mday

        LogStatus(_D(), nowTime, "\n`" + json.dumps(tbl) + "`")
        Sleep(500)
```
### Robot parameter settings:

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

### Strategy running:
Screenshots:

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

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

Strategy address: https://www.fmz.com/strategy/184600

### Ending
As an example, the FMZ Quant Trading Platform's extended API is still very powerful. It is no problem to build your own quantitative trading platform based on the FMZ platform with these extended APIs.
The timing robot is simple in design, it is to start at the time and stop at the time. It does not include mechanisms such as whether the startup is successful, inspection, exception retry, etc. If you are interested, you can add functions and expand them.
The strategy is for reference only.

From: https://blog.mathquant.com/2022/12/20/implement-a-quantitative-trading-robot-timed-start-or-stop-gadget-by-using-python.html