Apprendre à transformer une stratégie Python à une seule espèce en une stratégie multi-espèces

Auteur:Je ne sais pas., Créé: 2022-12-20 17:26:27, Mis à jour: 2023-09-20 09:45:28

img

Apprendre à transformer une stratégie Python monétaire en une stratégie multi-monnaie

I. Apprendre à transformer une stratégie monétaire Python en une stratégie multi-monnaies

Dans le dernier article, une stratégie Python très simple a été mise en œuvre:Stratégie pour acheter les gagnants de la version Python, cette stratégie peut faire fonctionner un compte pour effectuer le programme de trading sur une certaine paire de trading. Le principe est très simple, c'est-à-dire pourchasser après augmentation et tuer après diminution. Parfois, nous voulons utiliser la même logique de trading pour faire fonctionner différentes paires de trading. Vous pouvez créer plusieurs robots et définir différentes paires de trading pour effectuer des transactions dans différentes devises. Si la stratégie n'est pas très complexe, compte tenu de la forte flexibilité de la plateforme de trading FMZ Quant, il est facile de transformer une stratégie en une stratégie multi-espèces, de sorte que vous pouvez exécuter plusieurs paires de trading en créant un seul robot.

Code source de la stratégie après transformation:

'''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": ["Account information"], 
            "rows": []
        }        

        tblTick = {
            "type" : "table",
            "title": "ticker",
            "cols": ["Market information"], 
            "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)

II. Trouver une différence

En comparant le code, constatez- vous qu'il est très différent du code de l'article précédent? En fait, la logique de négociation est exactement la même, sans aucun changement. Nous ne modifions que la stratégie à une espèce multiple, nous ne pouvons pas utiliser la forme précédente de variable unique comme paramètre de stratégie. Une solution plus raisonnable est de faire le paramètre dans un tableau, et l'indice de chaque position dans le tableau correspond à la paire de négociation ajoutée.

img

Puis encapsuler le code de la logique de trading dans une fonctionprocess. Sur la boucle de stratégie principale, appeler cette fonction de manière itérative en fonction des paires de trading ajoutées, et laisser chaque paire de trading exécuter le code logique de trading une fois.

  • Appel itératif (transversal):
for i in range(len(exchanges)): 
    process(exchanges[i], i)
  • Paramètres de stratégie:
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":[]
}

Cette conception permet à chaque paire de négociation d'avoir ses propres paramètres, car chaque paire de négociation peut avoir une grande différence de prix, et les paramètres peuvent également être différents, nécessitant parfois des réglages différentiels.

  • Annuler toute la fonction Vous pouvez comparer le changement de cette fonction. cette fonction ne modifie qu'un peu de code, et puis penser à l'intention de cette modification.

  • Données du graphique de barre d'état Un graphique est ajouté pour afficher les données de marché et les données d'actifs du compte dans la barre d'état, de sorte que les actifs et le marché correspondants de chaque objet de change peuvent être affichés en temps réel. Est-il facile de changer une stratégie Python en une stratégie multi-espèces après avoir maîtrisé les idées de conception ci-dessus?

III. Test de retour

img img img

La stratégie est uniquement à des fins d'apprentissage et de backtesting, et vous pouvez l'optimiser et la mettre à niveau si vous êtes intéressé.Adresse stratégique


Relationnée

Plus de