8
Follow
1364
Followers
手把手教你把Python单品种策略改造成多品种策略
Created 2020-01-20 17:33:36 Updated 2023-10-17 21:18:46
14
4782
一、手把手教你把Python单品种策略改造成多品种策略
上期文章,实现了一个非常简单的Python策略:「Python版追涨杀跌策略」,该策略可以操作一个账户在某个交易对上进行程序化交易,原理很简单,就是追涨杀跌。有时候我们想用同样的交易逻辑去操作不同的交易对。可以创建多个机器人,设置不同交易对,来进行各个币种的交易。如果策略并不是很复杂,鉴于发明者量化交易平台强大的灵活性。很容易的可以把一个策略改造成多品种策略,这样只用创建一个机器人就可以跑多个交易对了。
改造后的策略源码:
'''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)
二、找不同
对比看下代码,是不是发现和上篇文章中的代码区别很大呢 ?
其实交易逻辑是完全一样的,没有任何改动,只是我们把策略修改成多品种的,就不能用之前的“单个变量作为策略参数”这样的形式了,比较合理的解决方案是,把参数做成数组,数组每个位置的索引对应添加的交易对。
然后把交易逻辑这部分代码封装到一个函数process中,在策略主循环上,根据添加的交易对迭代调用这个函数,让每个交易对都执行一次交易逻辑代码。
-
迭代(遍历)调用:
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":[] }这样设计,可以让每个交易对都有自己的参数,因为每个交易对可能价格差别很大,参数上也可能又差异,有时候需要差异化设置。
-
CancelAll 函数
可以对比下,这个函数的变化。该函数只是修改了一点点代码,然后思考下,这样修改的意图。
-
状态栏图表数据
增加了在状态栏显示行情数据和账户资产数据的图表,把每个交易所对象对应的资产和行情都能实时显示出来。
掌握了上面这些设计思路,把一个Python策略修改成多品种的策略是不是就很简单了呢?
三、回测测试
策略仅供参考学习,回测测试,有兴趣可以优化升级。
策略地址
Related Recommendations
Research on Binance Futures Multi-currency Hedging Strategy Part 3Research on Binance Futures Multi-currency Hedging Strategy Part 2Research on Binance Futures Multi-currency Hedging Strategy Part 1Crocodile line trading system Python versionJavaScript version SuperTrend strategyIntroducing FMZ Quant data science research environmentParabolic Steering SAR and Price High and Low Point StrategyTeach you how to let an old strategy docking the websocket quotes interfaceSimilarities and differences between commodity futures and cryptocurrency exchanges APIMulti-level percentage take profit strategy
Comment
All comments (14)
孟总,请问为什么,你这个策略下单不用设置exchange.SetDirection("buy")方向,还有个e. 不是exchange.吗,我最近在学习策略
4 years ago
- 1








