原 分享一个python均线策略
来源:掘金量化社区 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
-
-
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=
------------------------------------------------------------------------------------------------------------------------------------------------
推荐文章阅读:
1 | 网格交易策略(附策略源码与收益图) | https://www.myquant.cn/community/topic/548/2 |
2 | 指数增强策略 | https://www.myquant.cn/community/topic/527 |
3 | 日内回转交易策略 | https://www.myquant.cn/community/topic/526 |
4 | 跨期套利策略 | https://www.myquant.cn/community/topic/525 |
5 | 跨品种价差套利策略 | https://www.myquant.cn/community/topic/524 |
6 | 集合竞价选股 | https://www.myquant.cn/community/topic/523 |
7 | 基于EV/EBITDA倍数估值法的Alpha对冲策略 | https://www.myquant.cn/community/topic/522 |
8 | 行业轮动策略 | https://www.myquant.cn/community/topic/521 |
9 | 海龟交易法则 | https://www.myquant.cn/community/topic/520 |
《算法导论 第三版英文版》_高清中文版
《深度学习入门:基于Python的理论与实现》_高清中文版
《深入浅出数据分析》_高清中文版
《Python编程:从入门到实践》_高清中文版
《Python科学计算》_高清中文版
《深度学习入门:基于Python的理论与实现》_高清中文版
《深入浅出数据分析》_高清中文版
《Python编程:从入门到实践》_高清中文版