来源:掘金量化社区 myquant.cn ,转载请注明出处,谢谢.
简单的基于ta-lib的均线策略示例
策略简介,主要是基于分时线的close线跟MA之间的关系出信号,同时对信号有个简单的过滤逻辑,同时展示了怎么调用gmsdk来做仓位管理。订单管理并没有在代码中体现, 如果需要对委托订单的状态进行跟踪,还需要增加on_order_status函数,用来跟踪订单的执行状态。
策略逻辑: 用分时bar线的收盘价跟ma线之间的交叉关系发出信号,并根据配置做一个简单的信号过滤。 用一个数列配置下单量,在出信号后,根据已有持仓状态确定是否开仓,或者是继续加仓,或者是回调加仓,还是加仓次数达上限后主动平仓出场。
在代码中添加了一些注释,希望有助于阅读。
注: 代码仅为示例,各参数设置和逻辑都不够严谨,切勿直接用于实盘交易。
#!/usr/bin/env python
# encoding: utf-8
import time
from talib.abstract import SMA
import numpy as np
from collections import deque
from gmsdk import *
# 算法用到的一些常量,阀值,主要用于信号过滤
eps = 1e-6
threshold = 0.235
tick_size = 0.2
half_tick_size = tick_size / 2
significant_diff = tick_size * 2.6
class MA(StrategyBase):
""" strategy example1: MA decision price cross long MA, then place a order, temporary reverse trends place more orders """
def __init__(self, *args, **kwargs):
#import pdb; pdb.set_trace()
super(MA, self).__init__(*args, **kwargs)
# 策略初始化工作在这里写,从外部读取静态数据,读取策略配置参数等工作,只在策略启动初始化时执行一次。
# 从配置文件中读取配置参数
self.exchange = self.config.get("para", "trade_exchange")
self.sec_id = self.config.get("para", "trade_symbol")
self.symbol = ".".join([self.exchange, self.sec_id])
self.last_price = 0.0
self.trade_unit = [1.0, 2.0, 4.0, 8.0, 5.0, 3.0,2.0,1.0,1.0, 0.0] ## [8.0, 4.0, 2.0, 1.0]
self.trade_count = 0
self.trade_limit = len(self.trade_unit)
self.window_size = self.config.getint("para", "window_size") or 60
self.timeperiod = self.config.getint("para", "timeperiod")
self.bar_type = self.config.getint("para", "bar_type")
self.close_buffer = deque(maxlen=self.window_size)
self.significant_diff = self.config.getfloat("para", "significant_diff") or significant_diff
# prepare historical bars for MA calculating
# 从数据服务中准备一段历史数据,使得收到第一个bar后就可以按需要计算ma
last_closes = [bar.close for bar in self.get_last_n_bars(self.symbol, self.bar_type, self.window_size)]
last_closes.reverse() #因为查询出来的时间是倒序排列,需要倒一下顺序
self.close_buffer.extend(last_closes)
# 响应bar数据到达事件
def on_bar(self, bar):
# 确认下bar数据是订阅的分时
if bar.bar_type == self.bar_type:
# 把数据加入缓存
self.close_buffer.append(bar.close)
# 调用策略计算
self.algo_action()
# 响应tick数据到达事件
def on_tick(self, tick):
# 更新市场最新成交价
self.last_price = tick.last_price
def on_execution(self, execution):
#打印订单成交回报信息
print "received execution: %s" % execution.exec_type
#策略的算法函数,策略的交易逻辑实现部分
def algo_action(self):
#数据转换,方便调用ta-lib函数进行技术指标的计算,这里用SMA指标
close = np.asarray(self.close_buffer)
ma = SMA({"close":close}, timeperiod=self.timeperiod)
delta = round(close[-1] - ma[-1],4) # 最新数据点,bar的收盘价跟ma的差
last_ma = round(ma[-1], 4) # 均线ma的最新值
momentum = round(self.last_price - last_ma,4) # 当前最新价格跟ma之间的差,成交价相对ma偏离
#print "close: ", close
print("close ma delta: {0}, last_ma: {1}, momentum: {2}".format(delta, last_ma, momentum))
a_p = self.get_position(self.exchange, self.sec_id, OrderSide_Ask) #查询策略所持有的空仓
b_p = self.get_position(self.exchange, self.sec_id, OrderSide_Bid) #查询策略所持有的多仓
# 打印持仓信息
print ("pos long: {0} vwap: {1}, pos short: {2}, vwap: {3}".format(b_p.volume if b_p else 0.0,
round(b_p.vwap,2) if b_p else 0.0,
a_p.volume if a_p else 0.0,
round(a_p.vwap,2) if a_p else 0.0))
if delta > threshold and momentum >= significant_diff: ## 收盘价上穿均线,且当前价格偏离满足门限过滤条件,多信号
# 没有空仓,且没有超出下单次数限制
if (a_p is None or a_p.volume < eps) and self.trade_count < self.trade_limit:
# 依次获取下单的交易量,下单量是配置的一个整数数列,用于仓位管理,可用配置文件中设置
vol = self.trade_unit[self.trade_count]
# 如果本次下单量大于0, 发出买入委托交易指令
if vol > eps:
self.open_long(self.exchange, self.sec_id, self.last_price, vol)
self.trade_count += 1 #增加计数
else:
# 如果有空仓,且达到本次信号的交易次数上限
if a_p and a_p.volume > eps and self.trade_count == self.trade_limit:
self.close_short(self.exchange, self.sec_id, self.last_price, a_p.volume) # 平掉所有空仓
self.trade_count = 0
else:
# 有空仓时,且上次交易信号后没达到交易次数限制,继续加空
vol = self.trade_unit[self.trade_count] if self.trade_count < self.trade_limit else 0.0
self.trade_count += 1
if vol > eps:
self.open_short(self.exchange, self.sec_id,self.last_price, vol)
elif delta < -threshold and momentum <= - significant_diff: ## bar 收盘价下穿ma均线,且偏离满足信号过滤条件
# 没有多仓时,开空
if (b_p is None or b_p.volume < eps) and self.trade_count < self.trade_limit:
vol = self.trade_unit[self.trade_count]
self.trade_count += 1
if vol > eps:
self.open_short(self.exchange, self.sec_id, self.last_price, vol)
else:
# 已有多仓,且达到了交易次数限制,平掉多仓
if b_p and b_p.volume > eps and self.trade_count == self.trade_limit:
self.close_long(self.exchange, self.sec_id, self.last_price, b_p.volume)
self.trade_count = 0
else:
# 已有多仓,且没有达到交易次数限制,继续加多
vol = self.trade_unit[self.trade_count] if self.trade_count < self.trade_limit else 0.0
self.trade_count += 1
if vol > eps:
self.open_long(self.exchange, self.sec_id, self.last_price, vol)
else: ## 其他情况,忽略不处理
## get positions and close if any
#self.trade_count = 0 ## reset trade count
pass
# 策略启动入口
if __name__ == "__main__":
# 初始化策略
ma = MA(config_file="strategy_ma.ini")
#import pdb; pdb.set_trace() # python调试开关
print "strategy ready, waiting for market data ......"
# 策略进入运行,等待数据事件
ret = ma.run()
# 打印策略退出状态
print "MA :", ma.get_strerror(ret)
以下是它用的配置文件示例
[strategy]
;md_addr=120.24.228.187:8000
td_addr=localhost:8001
[email protected]
password=123456
mode=2
strategy_id=stategy_4
subscribe_symbols=SHFE.ag1512.tick,SHFE.ag1512.bar.60
;start_time=2014-05-26 09:00:00
;end_time=2014-05-26 16:00:00
[para]
trade_exchange=SHFE
trade_symbol=ag1512
window_size=20
bar_type=15
tick_size=1
significant_diff=21
timeperiod=20
##############################################################
# logger settings
##############################################################
[loggers]
keys=root
[logger_root]
level=DEBUG
handlers=console,file
[handlers]
keys=console,file
[handler_file]
class=handlers.RotatingFileHandler
args=("strategy_dual_ma.log","a","maxBytes=10000","backupCount=5")
formatter=simple
[handler_console]
class=StreamHandler
args = (sys.stdout,)
formatter=simple
[formatters]
keys = simple
[formatter_simple]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
------------------------------------------------------------------------------------------------------------------------------------------------
推荐文章阅读:
量化交易入门 | https://www.myquant.cn/community/topic/28/2 |
分享一个python均线策略 | https://www.myquant.cn/community/topic/78/2 |
一个量化交易策略师的自白 | https://www.myquant.cn/community/topic/652/2 |
《利用Python进行数据分析》PDF电子书下载 | https://www.myquant.cn/community/topic/618 |
高频交易:为了0.07毫秒的比拼,竟然花费了1400万美金 | https://www.myquant.cn/community/topic/634/2 |
分享几本量化和python方面的书,可以直接下载 | https://www.myquant.cn/community/topic/89/2 |
2018:数据科学20个最好的Python库 | https://www.myquant.cn/community/topic/664 |
《投资中最简单的事》读书笔记 | https://www.myquant.cn/community/topic/575/2 |
史上最全的量化交易资源合集 | https://www.myquant.cn/community/topic/624/2 |
七种量化选股模型 | https://www.myquant.cn/community/topic/663 |
谈资金管理 | https://www.myquant.cn/community/topic/579/2 |