En la carga de los recursos... Cargando...

Enseñar a transformar una estrategia de Python de una sola especie en una estrategia de múltiples especies

El autor:FMZ~Lydia, Creado: 2022-12-20 17:26:27, Actualizado: 2023-09-20 09:45:28

img

Enseñarle a transformar una estrategia de moneda única Python en una estrategia de varias monedas

I. Enseñarle a transformar una estrategia de moneda única de Python en una estrategia de varias monedas

En el último artículo, se implementó una estrategia de Python muy simple:Estrategia para comprar a los ganadores de la versión de Python, esta estrategia puede operar una cuenta para llevar a cabo el programa de negociación en un determinado par de operaciones. El principio es muy simple, es decir, perseguir después de aumentar y matar después de disminuir. A veces queremos usar la misma lógica de negociación para operar diferentes pares de operaciones. Puede crear múltiples robots y establecer diferentes pares de operaciones para realizar transacciones en varias monedas. Si la estrategia no es muy compleja, debido a la fuerte flexibilidad de la plataforma de negociación FMZ Quant, es fácil transformar una estrategia en una estrategia de múltiples especies, para que pueda ejecutar múltiples pares de operaciones creando solo un robot.

Código fuente de la estrategia después de la transformación:

'''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. Encontrar una diferencia

Al comparar el código, ¿se da cuenta de que es muy diferente del código del artículo anterior? De hecho, la lógica de negociación es exactamente la misma, sin ningún cambio. Solo modificamos la estrategia a una de múltiples especies, no podemos usar la forma anterior de variable única como parámetro de estrategia. Una solución más razonable es hacer el parámetro en una matriz, y el índice de cada posición en la matriz corresponde al par de operaciones agregado.

img

Luego encapsular el código de la lógica de negociación en una funciónprocessEn el bucle de estrategia principal, llame a esta función iterativamente de acuerdo con los pares de operaciones añadidos, y deje que cada par de operaciones ejecute el código de lógica de operaciones una vez.

  • Llamada repetitiva (transversal):
for i in range(len(exchanges)): 
    process(exchanges[i], i)
  • Parámetros de la estrategia:
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":[]
}

Este diseño permite que cada par de operaciones tenga sus propios parámetros, porque cada par de operaciones puede tener una gran diferencia de precio, y los parámetros también pueden ser diferentes, a veces requiriendo ajustes diferenciales.

  • Cancelar todas las funciones Esta función sólo modifica un poco de código, y luego pensar en la intención de dicha modificación.

  • Datos del gráfico de la barra de estado Se añade un gráfico para mostrar los datos de mercado y los datos de activos de la cuenta en la barra de estado, de modo que los activos y el mercado correspondientes de cada objeto de intercambio puedan mostrarse en tiempo real. ¿Es fácil cambiar una estrategia de Python en una estrategia de múltiples especies después de dominar las ideas de diseño anteriores?

III. Prueba de retroceso

img img img

La estrategia es sólo para aprendizaje y pruebas de retroceso, y puede optimizarla y actualizarla si está interesado.Dirección de la estrategia


Relacionados

Más.