Python股票量化投资课学习—小市值策略测试

发布于:2023-01-14 ⋅ 阅读:(721) ⋅ 点赞:(0)

第一次发说有广告嫌疑,有编辑一次,尽可能去除广告内容。

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)