第一次发说有广告嫌疑,有编辑一次,尽可能去除广告内容。
Python股票量化投资课学习—小市值策略测试
测试平台—
小市值策略测试 测试结果如下:
小市值策略测试 思路如下:
选股策略:市值因子
具体内容:在没个月的最后一个交易日,将所有股票按照市值从小到大排序,买入市值最小的10只股票。持有接下来的一个月,到下个月底的时候,按照同样的规则,买入另外10只股票,如此往复。
小市值策略测试 测试源文件如下:
源文件下载地址:https://download.csdn.net/download/jinzhai/86402507
小市值策略测试 源码如下:
# coding=utf-8
from __future__ import print_function, absolute_import, unicode_literals
from gm.api import *
import datetime
"""
示例策略仅供参考,不建议直接实盘使用。
小市值策略,等权买入全A市场中市值最小的前N只股票,月初调仓换股
"""
def init(context):
# 定时任务,月频(仿真和实盘时不支持该频率)
schedule(schedule_func=algo, date_rule='1m', time_rule='09:31:00')
# 定义股票池数量
context.num = 10
def algo(context):
# 当前时间
now = context.now
# 上一交易日
last_date = get_previous_trading_date(exchange='SZSE', date=now)
# 获取A股代码(剔除停牌股、ST股、次新股(365天))
all_stock,all_stock_str = get_normal_stocks(now)
# 获取所有股票市值,并按升序排序
fundamental = get_fundamentals_n('trading_derivative_indicator', all_stock_str, last_date, fields='TOTMKTCAP', count=1, df=True).sort_values(by='TOTMKTCAP')
# 获取前N只股票
to_buy = list(fundamental.iloc[:context.num,:]['symbol'])
print('本次股票池有股票数目: ', len(to_buy))
positions = context.account().positions()
# 平不在标的池的股票
for position in positions:
symbol = position['symbol']
if symbol not in to_buy:
order_target_percent(symbol=symbol, percent=0, order_type=OrderType_Market,position_side=PositionSide_Long)
# 获取股票的权重
percent = 1 / len(to_buy)
# 买在标的池中的股票
for symbol in to_buy:
order_target_percent(symbol=symbol, percent=percent, order_type=OrderType_Market,position_side=PositionSide_Long)
def on_order_status(context, order):
# 标的代码
symbol = order['symbol']
# 委托价格
price = order['price']
# 委托数量
volume = order['volume']
# 目标仓位
target_percent = order['target_percent']
# 查看下单后的委托状态,等于3代表委托全部成交
status = order['status']
# 买卖方向,1为买入,2为卖出
side = order['side']
# 开平仓类型,1为开仓,2为平仓
effect = order['position_effect']
# 委托类型,1为限价委托,2为市价委托
order_type = order['order_type']
if status == 3:
if effect == 1:
if side == 1:
side_effect = '开多仓'
elif side == 2:
side_effect = '开空仓'
else:
if side == 1:
side_effect = '平空仓'
elif side == 2:
side_effect = '平多仓'
order_type_word = '限价' if order_type==1 else '市价'
print('{}:标的:{},操作:以{}{},委托价格:{},委托数量:{}'.format(context.now,symbol,order_type_word,side_effect,price,volume))
def get_normal_stocks(date,new_days=365):
"""
获取目标日期date的A股代码(剔除停牌股、ST股、次新股(365天))
:param date:目标日期
:param new_days:新股上市天数,默认为365天
"""
if isinstance(date,str) and len(date)==10:
date = datetime.datetime.strptime(date,"%Y-%m-%d")
elif isinstance(date,str) and len(date)>10:
date = datetime.datetime.strptime(date,"%Y-%m-%d %H:%M:%S")
# 先剔除退市股、次新股和B股
df_code = get_instrumentinfos(sec_types=SEC_TYPE_STOCK, fields='symbol, listed_date, delisted_date', df=True)
all_stocks = [code for code in df_code[(df_code['listed_date']<=date-datetime.timedelta(days=new_days))&(df_code['delisted_date']>date)].symbol.to_list() if code[:6]!='SHSE.9' and code[:6]!='SZSE.2']
# 再剔除当前的停牌股和ST股
history_ins = get_history_instruments(symbols=all_stocks, start_date=date, end_date=date, fields='symbol,sec_level, is_suspended', df=True)
all_stocks = list(history_ins[(history_ins['sec_level']==1) & (history_ins['is_suspended']==0)]['symbol'])
all_stocks_str = ','.join(all_stocks)
return all_stocks,all_stocks_str
def on_backtest_finished(context, indicator):
print('*'*50)
print('回测已完成,请通过右上角“回测历史”功能查询详情。')
if __name__ == '__main__':
'''
strategy_id策略ID,由系统生成
filename文件名,请与本文件名保持一致
mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
token绑定计算机的ID,可在系统设置-密钥管理中生成
backtest_start_time回测开始时间
backtest_end_time回测结束时间
backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
backtest_initial_cash回测初始资金
backtest_commission_ratio回测佣金比例
backtest_slippage_ratio回测滑点比例
'''
run(strategy_id='strategy_id',
filename='main.py',
mode=MODE_BACKTEST,
token='{{token}}',
backtest_start_time='2021-01-01 08:00:00',
backtest_end_time='2021-12-31 16:00:00',
backtest_adjust=ADJUST_PREV,
backtest_initial_cash=1000000,
backtest_commission_ratio=0.0001,
backtest_slippage_ratio=0.0001)