量化交易 实战第十三课 打分法选股

量化交易 实战第十三课 打分法选股

经过筛选的因子

在这里插入图片描述

因子方向因子说明
因子升序因子值越小越好, 市值, 市盈率, 市净率
因子降序因子值越大越好, ROIC, inc_revenue 营业总收入和 inc_profit_before_tax 利润增长率

打分法选股流程

分析

回测区间:
2016-01-01 ~ 2021-01-01

选股:

  • 选股因子: 6 个已知方向的因子
  • 选股权重:
    • 因子升序从小到大分 10 组, 第几组为所在组得分
    • 因子降序从大到小分 10 组, 第几组为所在组得分
  • 数据处理: 处理缺失值

调仓周期:

  • 调仓: 每月进行一次调仓
  • 交易规则: 卖出已持有的股票
  • 买入新的股票池当中的股票

代码

# 可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。
import pandas as pd

# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
def init(context):
    # 选股数
    context.stocknum = 20
    
    # 升序因子
    context.up = ["market_cap", "pe_ratio", "pb_ratio"]

    # 运行按月定时函数
    scheduler.run_monthly(score_select, tradingday=1)

def score_select(context, bat_dict):
    """打分法选股逻辑"""

    # 选出银子数据, 进行缺失值处理
    q = query(
        fundamentals.eod_derivative_indicator.market_cap,
        fundamentals.eod_derivative_indicator.pe_ratio,
        fundamentals.eod_derivative_indicator.pb_ratio,
        fundamentals.financial_indicator.return_on_invested_capital,
        fundamentals.financial_indicator.inc_revenue,
        fundamentals.financial_indicator.inc_profit_before_tax
    )    

    fund = get_fundamentals(q)
    factors_data = fund.T  # 转置
    factors_data = factors_data.dropna()

    # 调试输出
    print(factors_data.head())

    # 定义打分函数, 确定股票池
    select_stocklist(context, factors_data)

    # 定义调仓函数
    reblance(context)


    # 定义打分函数, 确定股票池
def select_stocklist(context, factors_data):
    """打分的具体步骤, 返回股票池"""

    # 循环每个因子去处理
    for name in factors_data.columns:

        # 因子升序的, 进行升序排序
        if name in context.up:
            factor = factors_data.sort_values(by=name)[name]
        else:
            factor = factors_data.sort_values(by=name, ascending=False)[name]

        # 对单个因子进行打分处理
        # 新建一个因子分数列
        factor = pd.DataFrame(factor)

        factor[name + "score"] = 0

        # 进行打分
        # 先求出每组数量, 然后根据数量一次给出分数
        stock_groupnum = len(factors_data) // 10

        for i in range(10):
            # 最后一组单独处理
            if i == 9:
                factor[name + "score"][(i + 1) * stock_groupnum:] = i + 1

            factor[name + "score"][i * stock_groupnum: (i + 1) * stock_groupnum] = i + 1
        
        # 拼接每个因子的分数到原始的 factors_data 数据中
        factors_data = pd.concat([factors_data, factor[name + "score"]], axis=1)
    
    # 调试输出
    print(factors_data.head())

    # 求出总分
    sum_score = factors_data[
        ["market_capscore", "pe_ratioscore", "pb_ratioscore","return_on_invested_capitalscore", "inc_revenuescore",
         "inc_profit_before_taxscore"]].sum(1).sort_values()

    # 调试输出
    print(sum_score.head())

    # 定义股票池
    context.stock_list = sum_score.index[:context.stocknum]

    # 调试输出
    print(context.stock_list)


def reblance(context):
    # ----------------卖出----------------
	# 遍历股票池
    for stock in context.portfolio.positions.keys():
        # 判断是否还在股票池
        if stock not in context.stock_list:
            # 如果不在, 卖出
            order_target_percent(stock, 0)

    # ----------------买入-----------------
	# 买入的百分比
    weight = 1.0 / len(context.stock_list)
    # 遍历股票池
    for stock in context.stock_list:
        # 等比例买入
        order_target_percent(stock, weight)



# before_trading此函数会在每天策略交易开始前被调用,当天只会被调用一次
def before_trading(context):
    pass


# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context, bar_dict):
    # 开始编写你的主要的算法逻辑
    pass


# after_trading函数会在每天交易结束后被调用,当天只会被调用一次
def after_trading(context):
    pass

效果

在这里插入图片描述
在这里插入图片描述

评论 52
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值