The resource loading... loading...

Hands-on teaches you how to convert a Python single-variety policy into a multi-variety policy.

Author: Inventors quantify - small dreams, Created: 2020-01-20 17:33:36, Updated: 2023-10-17 21:18:46

img

One, handshake teaches you how to convert a Python single-variety policy into a multi-variety policy.

In the last article, we implemented a very simple Python strategy:"Python version of chase and kill strategy"This strategy can be used to manipulate an account to make programmatic trades on a certain trading pair, the principle is simple, it is a chase-and-drop. Sometimes we want to use the same trading logic to operate different trading pairs. Multiple robots can be created, set up different trading pairs, to trade in different currencies. If the strategy is not very complex, given the great flexibility of the inventor's quantitative trading platform.

The following is the source code of the modified strategy:

'''backtest
start: 2019-02-20 00:00:00
end: 2020-01-10 00:00:00
period: 1m
exchanges: [{"eid":"OKEX","currency":"BTC_USDT"},{"eid":"OKEX","currency":"ETH_USDT","stocks":30},{"eid":"OKEX","currency":"LTC_USDT","stocks":100}]
'''

import time
import json

params = {
    "arrBasePrice": [-1, -1, -1],     # -1
    "arrRatio": [0.05, 0.05, 0.05],         # 0.05
    "arrAcc": [],           # _C(exchange.GetAccount)
    "arrLastCancelAll": [0, 0, 0], # 0
    "arrMinStocks": [0.01, 0.01, 0.01],     # 0.01
    "arrPricePrecision": [2, 2, 2], # 2
    "arrAmountPrecision": [3, 2, 2], # 2
    "arrTick":[]
}

def CancelAll(e):
    while True : 
        orders = _C(e.GetOrders)
        for i in range(len(orders)) :
            e.CancelOrder(orders[i]["Id"], orders[i])
        if len(orders) == 0 :
            break
        Sleep(1000)

def process(e, index):
    global params
    ticker = _C(e.GetTicker)
    params["arrTick"][index] = ticker
    if params["arrBasePrice"][index] == -1 :
        params["arrBasePrice"][index] = ticker.Last
    if ticker.Last - params["arrBasePrice"][index] > 0 and (ticker.Last - params["arrBasePrice"][index]) / params["arrBasePrice"][index] > params["arrRatio"][index]:
        params["arrAcc"][index] = _C(e.GetAccount)
        if params["arrAcc"][index].Balance * params["arrRatio"][index] / ticker.Last > params["arrMinStocks"][index]:
            e.Buy(ticker.Last, params["arrAcc"][index].Balance * params["arrRatio"][index] / ticker.Last)
            params["arrBasePrice"][index] = ticker.Last
    if ticker.Last - params["arrBasePrice"][index] < 0 and (params["arrBasePrice"][index] - ticker.Last) / params["arrBasePrice"][index] > params["arrRatio"][index]: 
        params["arrAcc"][index] = _C(e.GetAccount)
        if params["arrAcc"][index].Stocks * params["arrRatio"][index] > params["arrMinStocks"][index]:
            e.Sell(ticker.Last, params["arrAcc"][index].Stocks * params["arrRatio"][index])
            params["arrBasePrice"][index] = ticker.Last
    ts = time.time()
    if ts - params["arrLastCancelAll"][index] > 60 * 5 :
        CancelAll(e)
        params["arrLastCancelAll"][index] = ts 

def main():
    global params
    
    for i in range(len(exchanges)) :    
        params["arrAcc"].append(_C(exchanges[i].GetAccount))
        params["arrTick"].append(_C(exchanges[i].GetTicker))
        exchanges[i].SetPrecision(params["arrPricePrecision"][i], params["arrAmountPrecision"][i])

    for key in params :
        if len(params[key]) < len(exchanges):
            raise "params error!"

    while True:
        tblAcc = {
            "type" : "table",
            "title": "account",
            "cols": ["账户信息"], 
            "rows": []
        }        

        tblTick = {
            "type" : "table",
            "title": "ticker",
            "cols": ["行情信息"], 
            "rows": []
        }
        for i in range(len(exchanges)): 
            process(exchanges[i], i)

        for i in range(len(exchanges)):
            tblAcc["rows"].append([json.dumps(params["arrAcc"][i])])
            tblTick["rows"].append([json.dumps(params["arrTick"][i])])

        LogStatus(_D(), "\n`" + json.dumps([tblAcc, tblTick]) + "`")
        Sleep(500)

Second, find the difference.

If you look at the code, is there a big difference between what you found and what you found in the previous article? In fact, the transaction logic is exactly the same, without any changes, only we modify the strategy into multiple varieties, so we can not use the previous hash single variable as a form of strategy parameter hash, a more reasonable solution is to make the parameter into an array, the index of each position of the array corresponds to the added transaction pair.

img

And then you wrap this part of the transactional logic code into a function.processIn the strategy main loop, the function is called iteratively based on the added transaction pairs, so that each transaction pair executes one transaction logic code.

  • I'm not sure what you're talking about.

    for i in range(len(exchanges)): 
        process(exchanges[i], i)
    
  • The policy parameters:

    params = {
        "arrBasePrice": [-1, -1, -1],           # -1
        "arrRatio": [0.05, 0.05, 0.05],         # 0.05
        "arrAcc": [],                           # _C(exchange.GetAccount)
        "arrLastCancelAll": [0, 0, 0],          # 0
        "arrMinStocks": [0.01, 0.01, 0.01],     # 0.01
        "arrPricePrecision": [2, 2, 2],         # 2
        "arrAmountPrecision": [3, 2, 2],        # 2
        "arrTick":[]
    }
    

    This design allows each pair to have its own parameters, as each transaction has a large difference in possible prices, which can also vary in parameters, sometimes requiring differentiation settings.

  • CancelAll function

    This can be contrasted with a change in the function. The function simply modifies a bit of code and then thinks about the intention of the modification.

  • State bar chart data

    The addition of a chart showing market data and account asset data in the status bar, which shows the corresponding assets and markets for each exchange object in real time.

With all of these design ideas, is it really that simple to change a Python strategy into a multi-variety strategy?

Three, repeat the test.

img

img

img

The strategy is for reference learning only, retesting tests, and interest in optimizing upgrades.Policy address


Related

More

bbbwwed2009Mr. Meng, why don't you just set up the exchange.SetDirection (("buy") direction, and there's an e. Not exchange.

The Big Black Horse of the CircleHow much is the minimum capital for this strategy?

The Big Black Horse of the CircleI've been waiting for half a day for a response.

The Big Black Horse of the CircleOK, OK, I got it, I got it in the coin, no wonder.

The Big Black Horse of the Circle/upload/asset/164f3fe6e84331d800583.png Now it's okay, but I have money in my account, how much is the minimum amount you have to invest in this strategy, is there not enough money in my account?

The Big Black Horse of the Circle/upload/asset/16495fcb1185338f8af27.png is the added host IP.

The Big Black Horse of the CircleGetAccount: 400: {"error_message":"Invalid IP","code":30011,"error_code":"30011","message":"Invalid IP"} This is a list of all the different ways GetAccount can be used. I added the IP to the API, but it's wrong.

The Big Black Horse of the Circle/upload/asset/164330beccf32fc55e7b6.png How to solve this

The Big Black Horse of the CircleHow many K-line cycles is the robot set to?

Inventors quantify - small dreamsThis strategy is a teaching strategy, learning-oriented, and can be modified, extended, and optimized on your own.

Inventors quantify - small dreamsThe strategy is open source, and the logic is simple: chase down and down. Note that this is a digital currency spot strategy, it cannot run futures, it can be modified into futures.

Inventors quantify - small dreamsWhen you request an API KEY, the IP address you set is the whitelisted address to which access is allowed. Once you set it, only this IP address can be used to access the API interface using your API KEY.

Inventors quantify - small dreamsInstall python on the host server.

Inventors quantify - small dreamsThis policy does not apply to the K-line, and is set to 1 minute because of the effect of the tick particle size.