股票:SHSE.600009;
时间:2016/1/1--2017/1/1分频数据;
10周期均线与20日均线的双均线策略;
无持仓时直接按照股票池等权买入;
有持仓时,不在股票池中的股票卖出。
2. 代码解读:
- #!/usr/bin/env python
- # encoding: utf-8
- import numpy as np
- from gmsdk import *
- from talib import SMA
- import time
- class MA(StrategyBase):
- def __init__(self, *args, **kwargs):
- super(MA, self).__init__(*args, **kwargs)
- self.close_list = []
- bars = self.get_last_n_bars('SHSE.600009', 60, 20, '2016-01-01 00:00:00')
- last_closes = [bar.close for bar in bars] # 提取每分钟收盘价
- last_closes.reverse() # 查询出的结果为倒序,需反转
- self.close_list.extend(last_closes)
- def on_bar(self, bar):
- if bar.bar_type == 60:
- position = self.get_positions() # 获取持仓量
- if len(position) == 0: ##如果没有持仓,设self.holding = 0
- self.holding = 0
- if len(position) > 0:
- if position[0].available_yesterday > 0: # 如果有昨仓,设self.holding = 1
- self.volume = position[0].available_yesterday
- self.holding = 1
- if position[0].available_today > 0: # 如果有今仓,设self.holding = 2
- self.holding = 2
- self.close_list.append(bar.close)
- if len(self.close_list) < 20:
- self.MA10 = self.close_list[:]
- self.MA20 = self.close_list[:]
- if len(self.close_list) >= 20:
- close = np.asarray(self.close_list)
- self.MA10 = SMA(close, timeperiod=10) # 10周期均线
- self.MA20 = SMA(close, timeperiod=20) # 20周期均线
- if self.holding == 0:
- if self.MA10[-1] > self.MA20[-1]: # 10周期均线>20周期均线开仓
- self.open_long('SHSE', '600009', 0, 10000)
- if self.holding == 1:
- if self.MA10[-1] < self.MA20[-1]: # 10周期均线<20周期均线平仓
- self.close_long('SHSE', '600009', 0, self.volume)
- if self.holding == 2:
- pass
- if __name__ == '__main__':
- ma = MA(
- username='username', # 输入用户名
- password='password', # 输入密码
- strategy_id='strategy_2', # 输入策略ID
- subscribe_symbols='SHSE.600009.bar.60', # 输入订阅代码
- mode=4, # 选择模式
- td_addr='localhost:8001'
- )
- ma.backtest_config(
- start_time='2016-01-01 09:00:00', # 起始时间
- end_time='2017-01-01 09:00:00', # 结束时间
- initial_cash=1000000, # 初始金额
- transaction_ratio=1, # 成交比率
- commission_ratio=0.0000, # 手续费
- slippage_ratio=0.000, # 滑点
- price_type=1)
- start = time.time()
- ret = ma.run()
- end = time.time()
- print(end - start)
3. Python相关函数
3.1 Python标准函数:
功能 | 函数原型 | 参数 | 返回值 | ||
参数名 | 含义 | ||||
reverse | 用于反向列表中元素 | list.reverse() | 该方法没有返回值,但是会对列表的元素进行反向排序。 | ||
extend | 该方法没有返回值,但是会对列表的元素进行反向排序。 | list.extend(seq) | seq | 元素列表。 | 该方法没有返回值,但会在已存在的列表中添加新的列表内容。 |
len | 返回对象(字符、列表、元组等)长度或项目个数。 | len(s) | s | 对象 | 返回对象长度。 |
append | 用于在列表末尾添加新的对象。 | list.append(obj) | obj | 添加到列表末尾的对象。 | 该方法无返回值,但是会修改原来的列表。 |
功能 | 函数原型 | 参数 | 返回值 | |||
参数名 | 类型 | 说明 | ||||
get_last_n_bars | 提取单个代码的最新n条Bar数据,策略类和行情服务类都提供该接口。 | get_last_n_bars(symbol, bar_type, n, end_time='') | symbol | string | 证券代码, 带交易所代码以确保唯一,如SHSE.600000 | Bar列表 |
bar_type | int | bar周期,以秒为单位,比如60即1分钟bar | ||||
n | int | 提取的数据条数 | ||||
end_time | string | 指定截止时间, 如2015-10-30 15:00:00 | ||||
get_positions | 查询当前策略指定symbol(由交易所代码和证券ID组成)和买卖方向的持仓信息。策略类和交易服务类都提供该接口。 | get_position(exchange, sec_id, side); | exchange | string | 交易所代码 | Position对象,持仓信息 |
sec_id | string | 证券代码 | ||||
side | int | 买卖方向 | ||||
open_long | 异步开多仓,以参数指定的symbol、价和量下单。如果价格为0,为市价单,否则为限价单。策略类和交易服务类都提供该接口 | open_long(exchange, sec_id, price, volume) | exchange | string | 交易所代码, 如上交所SHSE | 委托下单生成的Order对象 |
sec_id | string | 证券代码,如浦发银行600000 | ||||
price | float | 委托价,如果price=0,为市价单,否则为限价单 | ||||
volume | float | 委托量 | ||||
close_long | 异步平多仓接口,以参数指定的exchange, 证券代码sec_id, 价和量下单。如果价格为0,为市价单,否则为限价单。策略类和交易服务类都提供该接口。 | close_long(exchange, sec_id, price, volume) | exchange | string | 交易所代码, 如上交所SHSE | 委托下单生成的Order对象 |
sec_id | string | 证券代码,如浦发银行600000 | ||||
price | float | 委托价,如果price=0,为市价单,否则为限价单 | ||||
volume | float | 平仓量 |
4. 金融术语:
双均线策略:指的是运用两条不同周期的移动平均线,即短周期移动平均线和长周期移动平均线的相对大小,研判买进与卖出时机的策略。当短周期的均线从长期均线的下方,向上穿越至长周期的均线,所形成的交点,称为金叉。当短周期的均线从长期均线的上方,向下穿越至长周期的均线,所形成的交点,称为死叉。当出现金叉点时,市场属于多头市场;当出现死叉点时,市场属于空头市场。