
Im vorherigen Artikel wurde eine sehr einfache Python-Strategie implementiert:„Python-Version der Aufhol- und Abverkaufsstrategie“Mit dieser Strategie kann ein Konto so betrieben werden, dass programmierter Handel mit einem bestimmten Handelspaar durchgeführt wird. Das Prinzip ist sehr einfach: den Anstieg verfolgen und den Rückgang verkaufen. Manchmal möchten wir die gleiche Handelslogik für den Betrieb unterschiedlicher Handelspaare verwenden. Sie können mehrere Roboter erstellen und verschiedene Handelspaare festlegen, um mit verschiedenen Währungen zu handeln. Sofern die Strategie nicht allzu kompliziert ist, bietet sie die leistungsstarke Flexibilität der quantitativen Handelsplattform des Erfinders. Es ist sehr einfach, eine Strategie in eine Multiproduktstrategie umzuwandeln, sodass Sie durch die Erstellung nur eines Roboters mehrere Handelspaare ausführen können.
Der transformierte Strategie-Quellcode:
'''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)
Vergleichen Sie den Code und stellen Sie fest, dass er sich stark vom Code im vorherigen Artikel unterscheidet? Tatsächlich ist die Handelslogik genau dieselbe, ohne Änderungen. Wir haben die Strategie nur auf mehrere Varianten umgestellt, sodass wir die bisherige Form „einzelne Variable als Strategieparameter“ nicht mehr verwenden können. Eine vernünftigere Lösung ist Um das Parameter-Array zu erstellen, entspricht der Index jeder Position im Array dem hinzugefügten Handelspaar.

Kapseln Sie dann den Transaktionslogikcode in eine FunktionprocessIn der Hauptschleife der Strategie wird diese Funktion iterativ entsprechend der hinzugefügten Handelspaare aufgerufen, sodass der Code der Handelslogik einmal für jedes Handelspaar ausgeführt wird.
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":[]
}
Durch dieses Design kann jedes Handelspaar seine eigenen Parameter haben, da die Preise der einzelnen Handelspaare stark variieren können und sich auch die Parameter unterscheiden können, sodass manchmal differenzierte Einstellungen erforderlich sind.
Sie können die Änderungen dieser Funktion vergleichen. Diese Funktion ändert nur ein wenig Code. Denken Sie dann über die Absicht dieser Änderung nach.
Diagramme zur Anzeige von Marktdaten und Kontovermögensdaten in der Statusleiste hinzugefügt, sodass die Vermögenswerte und Marktdaten zu jedem Börsenobjekt in Echtzeit angezeigt werden können.
Ist es nicht sehr einfach, eine Python-Strategie in eine Strategie mit mehreren Varianten umzuwandeln, nachdem man die oben genannten Designideen gemeistert hat?



Die Strategie dient nur zu Referenzzwecken, zum Backtesting und zum Testen. Bei Interesse können Sie sie optimieren und aktualisieren. Richtlinienadresse