使用Python實現量化交易機器人定時啓動或停止小工具

使用Python實現量化交易機器人定時啓動或停止小工具

作爲全網功能強大、靈活易用的量化交易平臺,發明者量化交易平臺雖然使用門檻非常低,機器人程序佔用資源很少。但是我們依然希望,讓機器人需要運行的時候啓動,不需要運行時停止。
例如,在做商品期貨程序化、量化交易時,非開市時間佔全天的絕大部分。這樣我們就非常希望只讓機器人在開市時間運行,每天只開市時間運行多節省費用,想想都激動。爲了這個需求,我們可以使用Python語言編寫一個在FMZ量化交易平臺上運行的策略機器人,讓這個機器人通過
發明者量化交易平臺的擴展API接口,定時控制機器人的啓動和停止。

有了需求,說幹就幹!

其實整個代碼非常簡單,調用發明者量化交易平臺擴展API接口的例子直接可以使用,地址:https://www.fmz.com/api#%E7%AE%80%E5%8D%95%E7%9A%84%E4%BE%8B%E5%AD%90
直接使用例子中的函數:def api(method, *args)
我們需要調用的接口也很簡單,用到以下兩個接口(在FMZ文檔上可以查詢到)

  • RestartRobot
    重啓機器人接口,參數傳入機器人ID即可。
    使用具體id,這樣調用即可:api('RestartRobot', id)

  • StopRobot
    停止機器人接口,參數也是機器人ID

    機器人ID查看、獲取,截圖:
    1706aa37f2b85e6bd6a0.png

調用發明者量化交易平臺擴展API需要使用發明者量化交易平臺的API KEY
可以在賬戶管理中生成自己的API KEY
我們把API KEY作爲策略的參數傳入。
獲取發明者量化交易平臺賬號API KEY截圖:
15d109c1f542500ecc0c.png

剩下的就是編寫定時邏輯了,也非常簡單,設置定時參數:

["175708,14:55:33-15:10:33", ...]

省略號代表可以設置更多的類似"175708,14:55:33-15:10:33"的設置。
定時參數是一個JSON字符串,策略代碼中會對其解析,解析爲一個列表。列表中每個元素就是一組機器人啓動/停止設置。
即:

"175708,14:55:33-15:10:33"

其中以逗號間隔。逗號之前的部分175708爲機器人ID,逗號後面的部分爲啓動時間/停止時間。
如上例子,是ID爲:175708的機器人,14:55:33啓動,15:10:33停止。

然後策略中不停輪尋,每次輪尋先獲取當前時間,然後根據當前時間和定時時間對比,判斷是否需要觸發啓動或者停止機器人。
如果觸發了,就調用api(‘RestartRobot’, id)或者api(‘StopRobot’, id) ,來啓動、停止機器人。

完整的策略代碼:

# -*- 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("字符串配置錯誤:分隔符號,")
        param["id"] = arr[0]
        param["isProcessOpenThisDay"] = False
        param["isProcessCloseThisDay"] = False

        arr = arr[1].split("-")
        if len(arr) != 2:
            raise Exception("字符串配置錯誤:分隔符號-")

        begin = arr[0]
        arrBegin = begin.split(":")
        if len(arrBegin) != 3:
            raise Exception("字符串配置錯誤:起始時間分隔符號:")
        
        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("字符串配置錯誤:結束時間分隔符號:")            
        
        param["end"] = {}
        param["end"]["hour"] = float(arrEnd[0])
        param["end"]["min"] = float(arrEnd[1])
        param["end"]["sec"] = float(arrEnd[2])
        arrParams.append(param)

    # 測試
    Log("輸出參數", 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", "今天是否執行過啓動", "今天是否執行過停止"],
            "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("機器人ID:", arrParams[i]["id"], "執行啓動,請登錄平臺檢查是否啓動成功", "擴展API返回值:", 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("機器人ID:", arrParams[i]["id"], "執行停止,請登錄平臺檢查是否停止成功", "擴展API返回值:", ret, strPush)
        
        if nowDay != nowTime.tm_mday:
            nowDay = nowTime.tm_mday

        LogStatus(_D(), nowTime, "\n`" + json.dumps(tbl) + "`")
        Sleep(500)

機器人蔘數設置:

策略運行:

截圖

被這個策略操作的機器人:

策略地址:https://www.fmz.com/strategy/184600

結尾

作爲拋磚引玉,發明者量化交易平臺的擴展API還強大的很,用這些擴展API基於FMZ平臺做一個自己的量化交易平臺都完全沒問題。
這個定時機器人設計的比較簡單,只是無腦到時間開啓,到時間停止,並沒有加入啓動是否成功,檢驗,異常重試,等等機制,有興趣的可以增加功能,擴展。
策略僅供學習參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章