En el último artículo, se implementó una estrategia de Python muy simple:
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)
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
Luego encapsular el código de la lógica de negociación en una funciónprocess
En 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.
for i in range(len(exchanges)):
process(exchanges[i], i)
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?
La estrategia es sólo para aprendizaje y pruebas de retroceso, y puede optimizarla y actualizarla si está interesado.Dirección de la estrategia