zipline中benchmarks.py源码分析

1 benchmark 基准数据

zipline默认使用的回测基准数据是美国的标普500,可以通过两种方式来设置:
A、在初始化TradingEnvironment的时候使用bm_symbol参数来设置,基准数据的数据源通过csv获取;
B、在策略代码里通过 set_benchmark函数设置,基准数据直接使用本地的数据。
国内的基准数据要使用国内市场的指数,如上交所要使用上证综指。
注意,zipline在运行时对数据的要求比较严格,特别是基准数据,不能缺失,否则可能会导致异常。

我们打开data/benchmarks.py文件,跳过头部的授权信息和依赖项。

2 get_benchmark_returns_from_file 从文件中获取基准数据

get_benchmark_returns_from_file 从文件中获取基准数据,文件是包含基准数据的csv文件,格式为【时间】【基准数据】。
csv文件内容示例如下:
date,return
2020-01-02 00:00:00+00:00,0.01
2020-01-03 00:00:00+00:00,-0.02

def get_benchmark_returns_from_file(filelike):
    """
    Get a Series of benchmark returns from a file

    Parameters
    ----------
    filelike : str or file-like object
        Path to the benchmark file.
        expected csv file format:	
        date,return
        2020-01-02 00:00:00+00:00,0.01
        2020-01-03 00:00:00+00:00,-0.02

    """
    log.info("Reading benchmark returns from {}", filelike)

    df = pd.read_csv(				# 读取csv文件
        filelike,					# csv文件
        index_col=['date'],			# 索引列
        parse_dates=['date'],		# 指定date列为时间类型
    ).tz_localize('utc')

    if 'return' not in df.columns:	# 检查return列数据
        raise ValueError("The column 'return' not found in the "
                         "benchmark file \n"
                         "Expected benchmark file format :\n"
                         "date, return\n"
                         "2020-01-02 00:00:00+00:00,0.01\n"
                         "2020-01-03 00:00:00+00:00,-0.02\n")

    return df['return'].sort_index()	# 按时间列排序,返回基准数据的时序回报数据

3 BenchmarkSpec 基准数据操作类

我们在utils/run_algo.py的class BenchmarkSpec(object):中找到了对get_benchmark_returns_from_file的调用。BenchmarkSpec 类提供了对基准数据的操作

class BenchmarkSpec(object):

3.1 init 初始化

    """
    Helper for different ways we can get benchmark data for the Zipline CLI and
    zipline.utils.run_algo.run_algorithm.

    Parameters
    ----------
    benchmark_returns : pd.Series, optional
        Series of returns to use as the benchmark.
    benchmark_file : str or file
        File containing a csv with `date` and `return` columns, to be read as
        the benchmark.
    benchmark_sid : int, optional
        Sid of the asset to use as a benchmark.
    benchmark_symbol : str, optional
        Symbol of the asset to use as a benchmark. Symbol will be looked up as
        of the end date of the backtest.
    no_benchmark : bool
        Flag indicating that no benchmark is configured. Benchmark-dependent
        metrics will be calculated using a dummy benchmark of all-zero returns.
    """

    def __init__(self,
                 benchmark_returns,
                 benchmark_file,
                 benchmark_sid,
                 benchmark_symbol,
                 no_benchmark):

初始化,代码中的参数有详细说明,我们来理解下:

参数类型可选必选说明
benchmark_returnspd.Series可选时序基准回报数据
benchmark_file文件必选包含 datereturn字段的csv基准文件
benchmark_sid整型可选
benchmark_symbol 字符型可选股票代码
no_benchmark布尔型必选未配置基准数据的标志。依赖基准数据的指标将采用0回报基准来进行计算
        self.benchmark_returns = benchmark_returns
        self.benchmark_file = benchmark_file
        self.benchmark_sid = benchmark_sid
        self.benchmark_symbol = benchmark_symbol
        self.no_benchmark = no_benchmark

3.2 from_cli_params 从Cli参数获取cls

从Cli参数获取cls,不设置基准回报数据:

    @classmethod
    def from_cli_params(cls,
                        benchmark_sid,
                        benchmark_symbol,
                        benchmark_file,
                        no_benchmark):

        return cls(
            benchmark_returns=None,
            benchmark_sid=benchmark_sid,
            benchmark_symbol=benchmark_symbol,
            benchmark_file=benchmark_file,
            no_benchmark=no_benchmark,
        )

3.3 from_returns 从置基准回报数据获取cls

从置基准回报数据获取cls,只设置基准回报数据和未配置基准数据的标志:

    @classmethod
    def from_returns(cls, benchmark_returns):
        return cls(
            benchmark_returns=benchmark_returns,
            benchmark_file=None,
            benchmark_sid=None,
            benchmark_symbol=None,
            no_benchmark=benchmark_returns is not None,
        )

3.4 resolve 获取回报数据

resolve,根据TradingAlgorithm传递过来的股票信息、时序起始时间,返回基准数据对应的股票ID和回报数据。

    def resolve(self, asset_finder, start_date, end_date):
        """
        Resolve inputs into values to be passed to TradingAlgorithm.

        Returns a pair of ``(benchmark_sid, benchmark_returns)`` with at most
        one non-None value. Both values may be None if no benchmark source has
        been configured.

        Parameters
        ----------
        asset_finder : zipline.assets.AssetFinder
            Asset finder for the algorithm to be run.
        start_date : pd.Timestamp
            Start date of the algorithm to be run.
        end_date : pd.Timestamp
            End date of the algorithm to be run.

        Returns
        -------
        benchmark_sid : int
            Sid to use as benchmark.
        benchmark_returns : pd.Series
            Series of returns to use as benchmark.
        """
        if self.benchmark_returns is not None:	# 有基准回报数据
            benchmark_sid = None
            benchmark_returns = self.benchmark_returns
        elif self.benchmark_file is not None:	 # 没有基准回报数据,有基准数据文件
            benchmark_sid = None
            # 从基准数据文件中读取基准回报数据
            benchmark_returns = get_benchmark_returns_from_file(
                self.benchmark_file,
            )
        elif self.benchmark_sid is not None:	# 有基准数据股票ID
            benchmark_sid = self.benchmark_sid
            benchmark_returns = None
        elif self.benchmark_symbol is not None:	# 有基准数据股票代码
            try:
            	# 从股票信息中根据股票代码查找对应的股票ID
                asset = asset_finder.lookup_symbol(
                    self.benchmark_symbol,
                    as_of_date=end_date,
                )
                benchmark_sid = asset.sid
                benchmark_returns = None
            except SymbolNotFound:
                raise _RunAlgoError(
                    "Symbol %s as a benchmark not found in this bundle."
                )
        elif self.no_benchmark:		# 没有基准数据
            benchmark_sid = None
            benchmark_returns = self._zero_benchmark_returns(
                start_date=start_date,
                end_date=end_date,
            )
        else:
        	# 警告日志:未配置基准数据,可以通过algorithm调用set_benchmark函数设置
            log.warn(
                "No benchmark configured. "
                "Assuming algorithm calls set_benchmark."
            )
            # 警告日志:基准数据回报需要设置基准数据对应的股票ID、股票代码、数据文件
            log.warn(
                "Pass --benchmark-sid, --benchmark-symbol, or"
                " --benchmark-file to set a source of benchmark returns."
            )
            # 警告日志:基准数据零回报需要设置no-benchmark
            log.warn(
                "Pass --no-benchmark to use a dummy benchmark "
                "of zero returns.",
            )
            benchmark_sid = None
            benchmark_returns = None

        return benchmark_sid, benchmark_returns

上面代码中的参数有详细说明,我们来理解下:

参数类型说明
asset_finderzipline.assets.AssetFinderalgorithm 运行时需要使用的股票信息
start_datedatealgorithm 运行时的时序开始时间
end_datedatealgorithm 运行时的时序结束时间

上面代码中的返回信息有详细说明,我们来理解下:

返回信息说明
benchmark_sid基准数据对应的股票ID
benchmark_returns基准数据对应的股票的回报数据

3.5 _zero_benchmark_returns 获取零基准数据回报

    @staticmethod
    def _zero_benchmark_returns(start_date, end_date):
        return pd.Series(
            index=pd.date_range(start_date, end_date, tz='utc'),
            data=0.0,
        )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值