其实我从用聚宽也差不多一个月了,之前一直是抄的一个小市值策略,回测效果很好,但模拟盘就一般,实盘更别提了,现在还是亏损状态,还好只亏了不到1%。

这次我自己瞎写了一个策略,其实我根本不会炒股,但是写这个还蛮好玩的,策略十分朴素(简陋),回测效果实在是不忍直视,唯独今年的效果很好,可以说是奇怪的过拟合了。

思路是:

  1. 选取前一日成交额最大的行业(申万一级行业,因为聚宽好像只有这个数据呃);
  2. 选取这个行业内前一日换手率5%~10%的股票,并按市值降序;
  3. 筛选出前一日涨幅0%~9%的股票;
  4. 每周四上午十点半调仓;
  5. 如果没有筛选出符合条件的股票就空仓。

回测结果:

代码:

from jqdata import finance

## 初始化函数,设定要操作的股票、基准等等
def initialize(context):
    # 设定指数
    g.stockindex = '000300.XSHG' 
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # True为开启动态复权模式,使用真实价格交易
    set_option('use_real_price', True) 
    # 设定成交量比例
    set_option('order_volume_ratio', 1)
    # 股票类交易手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
    set_order_cost(OrderCost(open_tax=0, close_tax=0.001, \
                             open_commission=0.0003, close_commission=0.0003,\
                             close_today_commission=0, min_commission=5), type='stock')
    # 最大持仓数量
    g.stocknum = 5

    # 每周四运行
    run_weekly(trade, weekday=4, time='10:30', reference_security='000300.XSHG',force=True)

## 交易函数
def trade(context):

        ## 获得Buylist
        Buylist = check_stocks(context)
        
        ## 卖出
        if len(context.portfolio.positions) > 0:
            for stock in context.portfolio.positions.keys():
                if stock not in Buylist:
                    order_target(stock, 0)

        if len(Buylist)==0:return []

        ## 分配资金
        Num = 5
        if len(context.portfolio.positions) < g.stocknum :
            Num = g.stocknum  - len(context.portfolio.positions)
            Cash = context.portfolio.cash/Num
        else: 
            Cash = 0

        ## 买入
        if len(Buylist) > 0:
            for stock in Buylist[:Num]:
               if stock not in context.portfolio.positions.keys():
                   order_value(stock,Cash)
        return 

# 获取成交额最大的申万一级行业
def get_active_industry(date):
    obj = finance.SW1_DAILY_PRICE
    q = query(obj).filter(obj.date==date)
    data = finance.run_query(q)
    return data.sort_values(by='money', ascending=False).iloc[0,2]

# 获取行业内换手率5%~10%的股票代码,返回一个List
def get_industry_stock_list(industryIndex):
    stockList = get_industry_stocks(industryIndex)
    q = query(valuation).filter((valuation.turnover_ratio>5)&(valuation.turnover_ratio<10)&(valuation.pe_ratio>0)&(valuation.code.in_(stockList)))
    return get_fundamentals(q)['code'].tolist()

# 筛选出涨幅0%~9%股票代码,返回一个List
def filter_stock_pct_change(date, stockList):
    if len(stockList)==0: return []
    data = get_price(stockList, end_date=date, frequency='daily', fields=['close','pre_close'], skip_paused=False, fq='pre', count=1, panel=False, fill_paused=True)
    data['pct_change'] = data['close']/data['pre_close']-1
    data = data[data['pct_change'].between(0,0.09)]
    return data['code'].tolist()

# 给定一个日期,根据选股条件返回股票列表
def init_stock_list(date):
    industryIndex = get_active_industry(date)
    stockList = get_industry_stock_list(industryIndex)
    if len(stockList)==0: return []
    return filter_stock_pct_change(date, stockList)

## 选股函数,判断日期为持仓前一天
def check_stocks(context):
    date = context.previous_date
    return init_stock_list(date)