量化投资研究服务平台股票逐bar回测说明,我们通过一些具体应用来进行说明。

编写策略

编写一个完整的策略, 我们需要实现三个策略方法:

  • initialize
    初始化,配置策略参数
  • build_universe
    编写股票/品种筛选逻辑
  • handle_data 策略择时算法,一般情况,此处编写逐bar逻辑

以下,经典实用的 双均线策略 为例,看一下策略的基本编写方法。

交易单只股票

[1]:
"""
10日均线上穿50日均线,买入持有;
10日均线跌破50日均线,卖出清仓。
"""
import numpy as np


def initialize(context):
    """
    初始化
    """

    # 设置初始金额
    context.initial_capital = 100000.

    # 订阅行情, 分别指定 bar周期 与 股票列表
    context.freq = "1D"
    context.set_scope(["000001.SZ"])

    # 设定参照基准
    context.benchmark = "000016.SH"
    # 设定回测起始时间
    context.start_date = "20170104"
    context.end_date = "20171231"


def build_universe(context):
    """
    设定自选股票池
    """
    context.universe.add(["000001.SZ"])


def handle_data(context, data):
    """
    策略逻辑
    """

    account = context.account

    close_10 = data["000001.SZ"].close(1, 10)  # 取前10日收盘价
    close_50 = data["000001.SZ"].close(1, 50)  # 取前50日收盘价
    ma_10 = close_10.mean()
    ma_50 = close_50.mean()

    # 10日均线上穿50日均线买入
    if account["000001.SZ"].position == 0 and ma_10 > ma_50:
        # 全仓买入
        context.order_target_percent("000001.SZ", 1.)
        context.log("买入, 当前持仓{}手".format(account["000001.SZ"].position))

    # 10日均线跌破50日均线卖出
    if account["000001.SZ"].position > 0 and ma_10 < ma_50:
        # 清仓
        context.order_target_value("000001.SZ", 0)
        context.log("卖出, 当前持仓{}手".format(account["000001.SZ"].position))
[2]:
%matplotlib inline
# 运行策略
from dwtrader.core.engine import Engine
engine = Engine()
engine.run()
engine.plot()
add_data in 0.754407 secs
2017-01-23 09:30:00 000001.SZ 可用资金不足, 期望下单112手, 调整至111手
2017-01-23 09:30:00 买入, 当前持仓111手
2017-03-27 09:30:00 卖出, 当前持仓0手
2017-06-07 09:30:00 买入, 当前持仓113手
run in 0.789520 secs
_images/股票逐bar回测说明_4_1.png

交易多只股票

我们也可以对一篮子股票进行组合回测。

[3]:
"""
10日均线上穿50日均线,买入持有;
10日均线跌破50日均线,卖出清仓。
"""
import numpy as np


def initialize(context):
    """
    初始化
    """

    # 设置初始金额
    context.initial_capital = 100000.

    # 订阅行情, 分别指定 bar周期 与 股票列表
    context.freq = "1D"
    context.set_scope(["000001.SZ", "601933.SH", "002230.SZ"])

    # 设定参照基准
    context.benchmark = "000016.SH"
    # 设定回测起始时间
    context.start_date = "20170104"
    context.end_date = "20171231"


def build_universe(context):
    """
    设定自选股票池
    """
    context.universe.set(["000001.SZ", "601933.SH", "002230.SZ"])


def handle_data(context, data):
    """
    策略逻辑
    """

    account = context.account

    for s in context.universe:
        close_10 = data[s].close(1, 10)  # 取前10日收盘价
        close_50 = data[s].close(1, 50)  # 取前50日收盘价
        ma_10 = close_10.mean()
        ma_50 = close_50.mean()

        # 10日均线上穿50日均线买入
        if account[s].position == 0 and ma_10 > ma_50:
            # 全仓买入
            context.order_target_percent(s, 0.33)
            context.log("买入{}, 当前持仓{}手".format(s, account[s].position))

        # 10日均线跌破50日均线卖出
        if account[s].position > 0 and ma_10 < ma_50:
            # 清仓
            context.order_target_value(s, 0)
            context.log("卖出{}, 当前持仓{}手".format(s, account[s].position))

在 handle_data 方法中,由于universe现在包含了多只股票,我们添加了一个循环,来逐个检查当前的股票是否满足我们的买卖逻辑。

多周期回测

回测中,我们可以订阅多个时间频率的数据,比如:context.freq = '60min', '1D' , 即会同时加载60分钟和日线数据。订阅多周期数据源后,将以最小周期的bar的时间频率来触发 handle_data 逻辑。

详细示例可以参见示例策略文件夹中的 双均线策略-多周期.ipynb

动态选股

很多时候,我们希望能够动态的调整我们的自选股票池。
这部分逻辑,我们通过 build_unvierse 方法来实现。

假设我们现在想要在中证500中,每月选取 PE 排名前10名的股票,就可以如下改写上例中的 build_universe 方法:

[4]:
"""
选择ep因子排名最后的50只股票,每月初调整股票池

10日均线上穿50日均线,买入持有;
10日均线跌破50日均线,卖出清仓。
"""

import numpy as np


def initialize(context):
    """
    初始化
    """

    # 设置初始金额
    context.initial_capital = 10000000.

    # 订阅行情, 分别指定 bar周期 与 股票列表
    context.freq = "1D"
    # 订阅所有中证500成分股行情数据
    context.set_scope("000905.SH")

    # 设定参照基准
    context.benchmark = "000905.SH"
    # 设定回测起始时间
    context.start_date = "20170104"
    context.end_date = "20171231"

    # 设定股票池刷新频率
    context.universe_freq = "monthly"


def build_universe(context):
    """
    择股逻辑
    """
    # 先读取当前的中证500成分股
    zz500 = context.get_components("000905.SH")

    # 获取ep因子
    ep = context.factors["EP_TTM"]

    # 从因子中选出排名前50的股票
    my_basket = ep.top(50, codes=zz500)
    context.universe.set(my_basket)


def handle_data(context, data):
    """
    策略逻辑
    """

    account = context.account
    # 统计现在需要观察的所有股票
    codes = list(set(context.universe + context.holdings))

    for s in codes:
        close_10 = data[s].close(1, 10)  # 取前10日收盘价
        close_50 = data[s].close(1, 50)  # 取前50日收盘价
        ma_10 = close_10.mean()
        ma_50 = close_50.mean()

        # 10日均线上穿50日均线买入
        if account[s].position == 0 and ma_10 > ma_50:
            # 全仓买入
            context.order_target_percent(s, 0.02)
            context.log("买入{}, 当前持仓{}手".format(s, account[s].position))

        # 10日均线跌破50日均线卖出
        if account[s].position > 0 and ma_10 < ma_50:
            # 清仓
            context.order_target_value(s, 0)
            context.log("卖出{}, 当前持仓{}手".format(s, account[s].position))

        # 卖出在持仓中但不在股票池中的股票
        if s in context.holdings:
            if s not in context.universe:
                context.order_target_value(s, 0)

可以看到,我们首先要在 initialize 中指定股票池刷新频率,同时在 build_universe 方法中实现相应的选股逻辑。

还需要注意的是,由于现在股票池是动态变化的,我们账户中目前持有的股票,有可能并不在最新的股票池中,所以我们需要同时跟踪股票池和持仓列表中的所有股票。在上面的策略中,一旦有持仓中的股票跌出股票池,我们就会清掉该仓位,但实际上我们也可以选择继续持有,直到它们达到了我们预先设定的卖出条件。

导入本地数据文件

除了使用平台上提供的数据以外,也可以导入本地的数据文件,进行回测分析。

# 数据文件路径
path = 'ag1806_5min.csv'

# 传入数据属性,导入数据
context.load_local_data(
    path_or_df=path,
    freq='5min', # 数据周期
    code='ag1806', # 交易代码
    min_diff=1, # 最小变动价位
    contract_unit=15, # 合约乘数
    attributes={
        'name': '白银1806',
    }
)

1. 支持导入的数据格式

csv文件 或 pandas.DataFrame 数据对象

2. 导入bar数据(切片数据)

必须传入的字段

datetime: 时间索引,若传入DataFrame,须为 datetime 类型
open: 开盘价序列
close: 收盘价序列

3. 导入tick数据(原始行情数据)

必须传入的字段

datetime: 时间索引,若传入DataFrame,须为 datetime 类型
last_price: 最新价序列

4. 传入合约属性

合约属性作为参数传入(必填属性)

code:合约交易代码
freq: 数据周期。bar数据如:‘5min’, ‘30min’, ‘1D’, tick数据:‘tick’
min_diff: 最小变动价位。如A股股票最小变动价位为0.01
contract_unit: 交易单位/合约乘数。如A股为100,50eft期权为10000

其它属性可以通过 attributes 参数(dict类型)传入,策略内引用:data['ag1806'].get_attribute('name'),返回 ‘白银1806’

5. 关于bar时间戳

如果导入的是bar数据,由于是切片,所以每条数据实际上会对应一个bar起始时间,和一个bar截止时间。
为了和bar推送时的时间保持一致,这里我们需要使用切片起始时间作为bar的时间戳。
比如对于A股,在5分钟数据的每日第一根bar的时间戳应为 ‘2018-01-01 09:30:00’。
而对于日线及以上级别的数据,也应使用开盘时间(不考虑集合竞价)作为该日bar数据的时间戳。
实际上,如果回测中只使用了同一频率的数据,bar时间戳的标记风格,并不会影响最终的测试结果。
但如果策略中使用了多个时间频率,比如同时载入了日线及分钟级别的数据,则必须将时间戳按上述规则进行转换,否则将无法保证bar数据的正确推送顺序,从而影响回测结果。

使用因子

通过 context.factors 可以获取到当前平台上的所有因子数据。
传入正确的因子名称,将返回一个因子对象,类型为 Factor , 如果传入多个因子名,将会返回一个复合因子(等权合成)。
# 获取单因子对象
context.factors['EP_TTM']

# 获取复合因子对象
context.factors['MonthlyReturn','RoeGrowth1', 'MonthlyTradeAmount']

# 获取多个因子的DataFrame,每列对应一个单独的因子序列
# 一级索引为时间,二级索引为股票代码
context.factors.get_multiple('MonthlyReturn','RoeGrowth1', 'MonthlyTradeAmount')

因子对象常用方法

# 获取ep因子
ep = context.factors['EP_TTM']

# 选择ep因子中排名最前的50支股票,默认从全A股票中选择
ep.top(size=50)

# 传入股票列表,在给定范围中排序
sz50 = context.get_components('0000016.SH')
# 在上证50中,选出ep因子排名前10的股票
ep.top(size=10, codes=sz50)

# 获取原始因子值,类型为 pd.Series
ep_value = ep.value

关于原始因子的详细信息,请参考平台上的 因子说明文档 。

理解bar推送机制

bar,即K线数据,行情数据的切片。

目前支持的切片频率:

  • 1分钟(‘1min’), 3分钟(‘3min’), 5分钟(‘5min’), N分钟(N必须能整除30,或为30的倍数,如10、15、30、60、120等)。
  • 日线(‘1D’)及其倍数周期

数据推送时,按订阅的最小周期的bar的频率进行。如订阅的最小周期为 ‘5min’,则会每5分钟触发一次 handle_data 方法。

如在日线频率上(context.freq='1D'), 假设当前的理论交易日为 20180314 ,则在开盘的同一时刻(9:30),即会生成当日的bar数据,时间戳为datetime.datetime(2018, 3, 14, 9, 30),同时系统理论时间也随之更新,指向 datetime.datetime(2018, 3, 14, 9, 30)。在实时行情中,该bar属于正在形成的bar,只有开盘价为有效历史数据,对应到回测中,当前bar总是指向未完成的bar,除开盘价以外,均属于未来数据。比如取最近的10周期的收盘价序列,应为 close(1, 10), 1表示向前回溯1个周期,若取 close(0, 10), 则该序列中会引用到当前bar的收盘价,即引入了未来数据。

close(1) 表示最近一个已完成的bar的收盘价数据,close(n) 表示最近第n个完成bar的收盘价数据,close(0) 指向当前正在更新的bar的收盘价。

分钟周期上同理,每个分钟的当前bar数据,也属于未完成的bar,在引用历史价格时,除开盘价外,均需向前回溯。

常用对象

context – 策略上下文

StrategyContext 的实例,用来在用户的策略方法中传递,方便存取策略数据。

一些常用属性

context.now # 当前理论时间
context.current_date # 当前交易日
context.pre_date # 上一交易日
context.pre_dt # 上一个时间戳

context.data # 数据源仓库(可以类似字典一样,根据标的代码与频率行索引)
context.universe # 自选池
context.holdings # 当前持仓列表
context.accout # 理论账户
context.initial_capital # 理论账户初始权益,等价于 context.account.initial_capital
context.current_capital # 理论账户当前权益,等价于 context.account.current_capital
context.factors # 因子库

data – 数据源仓库

数据源仓库,handle_data 方法中,默认会接收到该对象,也可以通过 context.data 获取。

datasource – 数据源

数据源对象。通过股票代码索引数据源仓库,即会返回对应股票的数据源对象。
如 stock  = data['000001.SZ'] , 即为获取到的平安银行的数据源对象。

“datasource“ 的常用属性

stock.open # 开盘价序列
stock.high # 最高价序列
stock.low # 最低价序列
stock.close # 收盘价序列
stock.volume # 成交量序列
stock.time # 时间序列(如为bar数据,则对应bar的起始时间)

stock.barpos # 当前股票的bar位置索引,第一根bar返回1,后续依次递增

序列数据的索引方法(开盘价序列为例)

stock.open(0) # 返回最新bar开盘价
stock.open(1) # 返回第一根历史bar开盘价

# 例如获取平安银行昨日的开盘价
stock = context.data['000001.SZ']
last_open = stock.open(1)

序列数据的切片方法

stock.open(ago=0, size)
  • ago: 切片起点据当前的位置,0表示当前位置,1表示上一根bar的位置,以此类推
  • size: 切片的长度
# 例如取平安银行历史5天的收盘价序列
stock = context.data['000001.SZ']
close5 = stock.close(1, 5)

获取相应股票交易状态

stock.is_st # 属性方法,是否为 ST
stock.is_suspended # 属性方法,是否停牌
stock.is_delisted # 属性方法,是否已退市
stock.ipo_date # 属性方法,上市日期

context.universe – 股票自选池

选股逻辑(build_universe) 中的最终结果,应存入 context.universe 中,方便在择时逻辑(handle_data)中引用。

stocks = context.get_components('0000016.SH')
context.universe.add(stocks) # 在现有自选池中加入新选股票
context.universe.set(stocks) # 重置自选池,加入新选股票
context.universe.drop_st() # 去除ST股票
context.universe.drop_suspended() # 去除停牌股票
context.universe.drop_delisted() # 去除退市股票

universe(自选池)的更新机制

可以在 build_universe 方法中定义选股逻辑,定期更新自选池。更新周期通过 context.universe_freq 设置,常用的如 'daily', 'weekly', 'monthly' 等,详见 API简介 – context.universe_freq 部分。

自选池更新的最小频率为 'daily'。在更新日当天,build_universe 函数会在开盘前触发,此时当前理论时间(context.now)已经更新, 但因为尚未开盘,可以通过 data['000001.SZ'].time(0) 看到,数据时间戳依然指向上一个交易日。同理,data['000001.SZ'].close(0) 等也均返回上一个交易日的价格数据。

context.account – 账户

可以查询理论账户的当前权益、可用余额等

context.account.initial_capital # 理论账户初始权益
context.account.current_capital # 理论账户当前权益
context.account.cash # 理论账户可用现金

我们可以从账户中查询特定股票的持仓情况

context.account['000001.SZ'].position # 当前持仓手数,0表示空仓,负数表示持有空头仓位
context.account['000001.SZ'].entry_price # 获取最近一次的开仓价格
context.account['000001.SZ'].exit_price # 获取最近一次的平仓价格
context.account['000001.SZ'].entry_time # 获取最近一次的开仓时间
context.account['000001.SZ'].exit_time # 获取最近一次的平仓时间
context.account['000001.SZ'].first_entry_price # 若有加仓,返回当前持仓中的首次开仓价格
context.account['000001.SZ'].first_exit_price # 若有减仓,返回当前持仓中的首次平仓价格
context.account['000001.SZ'].first_entry_time # 若有加仓,返回当前持仓中的首次开仓时间
context.account['000001.SZ'].first_exit_time  # 若有减仓,返回当前持仓中的首次平仓时间

常见问题

个别股票停牌时,返回的价格序列会与其它股票数据保持对齐吗?

不会对齐。例如,取 close_10 = data['000001.SZ', '1D'].close(1, 10),如果该股票过去10个交易日中发生过停牌,则 close_10 中会跳过该停牌日期继续往前取值,尽可能返回一个长度为10的numpy数组(如果历史数据足够,历史数据不足则最终的数组长度会小于10)。如果其它股票并未发生过停牌,则二者的 close_10 实际指向了不同的交易时间段。

如何对齐不同股票的价格序列?

时间戳本身也是一个序列,time_10 = data['000001.SZ', '1D'].time(1, 10),利用pandas可以很简单的生成时间序列 series_10 = pd.Series(close_10, index=time_10) , 从而可以进行各种时间序列相关的处理。

API简介

以下方法默认通过策略方法中传递的 context 调用


set_cost – 设置交易费用

set_cost(ratio=0., slippage=0)

暂用

参数

  • ratio: 每次交易的开平仓交易费率,买入卖出采用相同费率
  • slippage:每次交易的滑点个数

示例

# 每次交易收取万二手续费,设置2个滑点
context.set_cost(ratio=0.0002, slippage=2)

benchmark – 设置参照基准

context.benchmark = '000016.SH'


set_scope – 设置股票数据订阅范围

context.set_scope(index)

参数

  • index: 股票指数,类型 str;或传入股票列表,类型 list

说明

  • 如果传入指数代码,则会加载回测区间内该指数的所有历史成分股

示例

# 订阅上证50成分股行情数据
context.set_scope('000016.SH')

# 订阅列表中的所有股票数据
context.set_scope(['000001.SZ', '002230.SZ', '600000.SH'])

freq – 设置策略运行周期

context.freq = ‘1D’

默认为日线级别 '1D'

可用周期:

  • 1分钟(‘1min’), 3分钟(‘3min’), 5分钟(‘5min’), N分钟(N必须能整除30,或为30的倍数,如10、15、30、60、120等)。
  • 日线(‘1D’)及其倍数周期

可以同时设置多个运行周期:

# 将同时订阅 10分钟 和 日线 bar数据
context.freq = '10min', '1D'

universe_freq – 设置股票池刷新频率

context.universe_freq = 'monthly'

可选项

  • daily: 每日开盘前选股
  • weekly: 每周选股
  • week_start: 每周第一个交易日选股,与weekly等价
  • week_end: 每周最后一个交易日选股
  • monthly: 每月选股
  • month_start: 每月第一个交易日选股,与monthly等价
  • month_end: 每月最后一个交易日选股

get_components – 获取成分股

get_components(category, date=None, weights=False)

参数

  • category: 分类代码,比如沪深300的 category 为 ‘000300.SH’
  • date: 日期, 类型为 datetime.datetime,默认取当前交易日(回测理论时间)
  • weights: 是否返回权重

返回值

  • 默认返回成分股 list , 若 weights=True , 返回 pandas.DataFrame 对象

示例

# 获取当前沪深300成分股
context.get_components('000300.SH')

factors – 获取因子

factors 为因子仓库

设置参数

# 如需设置参数,可以在 initialize 接口方法中统一设置:
context.factors.set_params({
    'MonthlyReturn': {
        'factor_direction': 1
    },
    'RoeGrowth1': {
        'factor_direction': -1
    },
    'MonthlyTradeAmount': {
        'factor_direction': 1
    }
})

获取因子

  • 可以直接通过因子名来对因子仓库进行索引:context.factors[‘RoeGrowth1’]
  • 传入多个因子名,则会返回复合因子

示例

# 获取因子 EP_TTM
pe = context.factors['EP_TTM']

# 获取复合因子
trinity = context.factors[
    'MonthlyReturn',
    'RoeGrowth1',
    'MonthlyTradeAmount'
]

load_local_data – 加载本地行情数据文件

load_local_data(path_or_df, code, min_diff, contract_unit, attributes=None)

参数

  • path_or_df: str 类型,csv文件地址;或 pd.DataFrame 数据对象
  • code: 合约交易代码,str 类型
  • freq: 数据周期/频率,str 类型
  • min_diff: 最小变动价位,float 类型
  • contract_unit: 交易乘数/合约单位 float/int 类型
  • attributes: 自定义属性,dict 类型,可选参数

示例

context.load_local_data(
    path_or_df='path/to/data/ag1806.csv',
    freq='5min',
    code='ag1806',
    min_diff=1,
    contract_unit=15,
    attributes={
        'name': '白银1806',
        'end_date': datetime.datetime(2018, 6, 15)
    }
)

order_target_value – 按目标金额调仓

order_target_value(stock, target, price=None)

参数

  • stock: 股票代码或数据源对象,类型 str / DataSource
  • target: 目标金额(单位:元)
  • price: 报单价格,默认为None,即使用当前开盘价(加滑点)报单

返回值

  • 暂时返回None,后续更新会返回报单结构

示例

# 已当前开盘价买入价值10000元的平安银行股票
context.order_target_value('000001.SZ', 10000.)

order_target_percent – 按目标比例调仓

order_target_percent(stock, target, price=None)

参数

  • stock: 股票代码或数据源对象,类型 str / DataSource
  • target: 目标持仓比例,为当前股票价值占账户总权益之比
  • price: 报单价格,默认为None,即使用当前开盘价(加滑点)报单

返回值

  • 暂时返回None,后续更新会返回报单结构

示例

# 已当前开盘价买入价值为1%账户总额的的平安银行股票
context.order_target_value('000001.SZ', 0.1)

order_tartget_size – 按目标手数调仓

order_target_percent(stock, target, price=None)

参数

  • stock: 股票代码或数据源对象,类型 str / DataSource
  • target: 目标持仓比例,为当前股票价值占账户总权益之比
  • price: 报单价格,默认为None,即使用当前开盘价(加滑点)报单

返回值

  • 暂时返回None,后续更新会返回报单结构

示例

# 已当前开盘价买入价值为1%账户总额的的平安银行股票
context.order_target_value('000001.SZ', 0.1)

context.data

属性方法,指向数据源仓库

示例

# 获取平安银行数据源对象,默认使用策略的timeframe
stock = context.data['000001.SZ']
# 获取平安银行1小时数据的数据源对象
stock_1H = context.data['000001.SZ', '1H']

获取当前(理论)时间

context.now
当前理论时间,即当前Bar数据的时间戳,数据类型 datetime.datetime
context.current_date
当前日期,数据类型 datetime.datetime
context.pre_date
上一个交易日,数据类型 datetime.datetime

factors.get_multiple – 获取多个因子数据

factors.get_multiple(*factor_names)

参数

  • factor_names: 多个因子名称,逗号隔开即可,类型为 str

返回值

  • pd.DataFrame, 索引为MultiIndex, 一级索引为时间,二级索引为股票代码, 每列对应一个因子序列

示例

# 获取一个包含指定的三个因子的dataframe
factors.get_multiple(
    'MonthlyReturn',
    'RoeGrowth1',
    'MonthlyTradeAmount'
)

facotr.value – 返回原始因子序列

factor.value

返回值

  • 原始因子序列,类型 pd.Series,索引为MultiIndex, 一级索引为时间,二级索引为股票代码

factor.top – 选取因子排名最前的N只股票

factor.top(size, date=None, codes=None, as_list=True)

参数

  • size: 需要选出的股票数量,类型 int
  • date: 日期,类型 datetime.datetime,默认为上一个交易日
  • codes: 接收一个股票列表作为排序范围, 类型 list, 默认从全A股票中选择
  • as_list: 结果是否作为列表返回,默认为True,为False将返回一个 pd.Series, 索引为股票代码,值为因子取值

返回值

  • list / pd.Series

示例

# 从全A中选择 ep因子 排名最前的50只股票
ep = context.factors['EP_TTM']
top50 = ep.top(50)

factor.bottom – 选取因子排名最后的N只股票

factor.bottom(size, date=None, codes=None, as_list=True)

同 factor.top


factor.get_value – 获取因子数据

factor.get_value(date=None)

参数

  • date: 日期,类型 datetime.datetime,默认为上一个交易日

返回值

  • 返回某日(末日返回上个交易日)因子数据,index为股票代码,类型 pd.Series

示例

# 获取上一交易日因子数据
ep = context.factors['EP_TTM']
ss = ep.get_value()

factor.get_stock_weights – 生成股票权重

factor.get_weighted_stocks(size, date=None, codes=None, weighting=None)

根据因子数据,生成理论持仓权重

参数

  • size: 需要选出的股票数量,类型 int
  • date: 日期,类型 datetime.datetime,默认为上一个交易日
  • codes: 接收一个股票列表作为排序范围, 类型 list, 默认从全A股票中选择
  • weighting: 股票权重分配方法,默认使用分层加权
    • ‘LayeredWeighting’: 分层加权
    • ‘EqualWeighting’: 同等权重
    • ‘TotalMktValueWeighting’: 总市值加权
    • ‘TotalMktValueWeighting’: 流通市值加权

返回值

  • 返回股票权重列表,类型 pd.Series

示例

# 在中证500中,根据ep因子,得出当日股票持仓权重
zz500 = context.get_components('000905.SH')
ep = context.factors['EP_TTM']
weights = ep.get_stock_weights(100, codes=zz500)