Python 金融交易实用指南(三)(4)

简介: Python 金融交易实用指南(三)

Python 金融交易实用指南(三)(3)https://developer.aliyun.com/article/1523774

探索 MarketStack 数据源

MarketStack 提供跨主要全球股票交易所的实时、盘内和历史市场数据的广泛数据库。它为每月高达 1,000 次的 API 请求提供免费访问。

虽然没有官方的 MarketStack Python 库,但 REST JSON API 在 Python 中提供了对其所有数据的舒适访问。

让我们下载苹果公司的调整后收盘数据:

import requests
params = {
  'access_key': 'XXXXX'
}
api_result = \
requests.get('http://api.marketstack.com/v1/tickers/aapl/eod', params)
api_response = api_result.json()
print(f"Symbol = {api_response['data']['symbol']}")
for eod in api_response['data']['eod']:
    print(f"{eod['date']}: {eod['adj_close']}")
Symbol = AAPL
2020-12-28T00:00:00+0000: 136.69
2020-12-24T00:00:00+0000: 131.97
2020-12-23T00:00:00+0000: 130.96
2020-12-22T00:00:00+0000: 131.88
2020-12-21T00:00:00+0000: 128.23
2020-12-18T00:00:00+0000: 126.655
2020-12-17T00:00:00+0000: 128.7
2020-12-16T00:00:00+0000: 127.81
2020-12-15T00:00:00+0000: 127.88
2020-12-14T00:00:00+0000: 121.78
2020-12-11T00:00:00+0000: 122.41
2020-12-10T00:00:00+0000: 123.24
2020-12-09T00:00:00+0000: 121.78
2020-12-08T00:00:00+0000: 124.38
2020-12-07T00:00:00+0000: 123.75
2020-12-04T00:00:00+0000: 122.25

现在让我们下载纳斯达克证券交易所的所有股票代码:

api_result = \
requests.get('http://api.marketstack.com/v1/exchanges/XNAS/tickers', params)
api_response = api_result.json()
print(f"Exchange Name = {api_response['data']['name']}")
for ticker in api_response['data']['tickers']:
    print(f"{ticker['name']}: {ticker['symbol']}")
Exchange Name = NASDAQ Stock Exchange
Microsoft Corp: MSFT
Apple Inc: AAPL
Amazoncom Inc: AMZN
Alphabet Inc Class C: GOOG
Alphabet Inc Class A: GOOGL
Facebook Inc: FB
Vodafone Group Public Limited Company: VOD
Intel Corp: INTC
Comcast Corp: CMCSA
PepsiCo Inc: PEP
Adobe Systems Inc: ADBE
Cisco Systems Inc: CSCO
NVIDIA Corp: NVDA
Netflix Inc: NFLX

MarketStack 的票务宇宙检索功能是最有价值的功能之一。所有回测的第一步之一是确定股票交易的宇宙(即完整列表)。然后,您可以通过仅交易具有某些趋势或某些交易量的股票等方式将自己限制在该列表的子集中。

概要

在本章中,我们概述了在 Python 中获取金融和经济数据的不同方法。在实践中,您通常同时使用多个数据源。我们探索了yahoofinancials Python 库,并看到了单个和多个股票检索。然后,我们探索了pandas_datareader Python 库,以访问 Yahoo Finance、EconDB 和 Fed 的 Fred 数据,并缓存查询。然后我们探索了 Quandl、IEX Cloud 和 MarketStack 数据源。

在下一章中,我们将介绍回测库 Zipline,以及交易组合绩效和风险分析库 PyFolio。

第八章:Zipline 和 PyFolio 简介

在本章中,您将了解到被称为 Zipline 和 PyFolio 的 Python 库,它们抽象出了算法交易策略的回测和性能/风险分析方面的复杂性。它们允许您完全专注于交易逻辑。

为此,我们将涵盖以下主要内容:

  • 简介 Zipline 和 PyFolio
  • 安装 Zipline 和 PyFolio
  • 将市场数据导入 Zipline/PyFolio 回测系统
  • 构建 Zipline/PyFolio 回测模块
  • 查看关键 Zipline API 参考
  • 从命令行运行 Zipline 回测
  • 简介 PyFolio 提供的关键风险管理指标

技术要求

本章中使用的 Python 代码可在书籍代码库的 Chapter08/risk_management.ipynb 笔记本中找到。

简介 Zipline 和 PyFolio

回测是一种计算方法,用于评估如果将交易策略应用于历史数据,该策略将表现如何。理想情况下,这些历史数据应来自于一个具有类似市场条件的时期,例如具有类似于当前和未来的波动性。

回测应包括所有相关因素,如滑点和交易成本。

Zipline 是最先进的开源 Python 库之一,用于算法交易回测引擎。其源代码可在 github.com/quantopian/zipline 找到。Zipline 是一个适用于日常交易的回测库(也可以回测每周、每月等)。它不太适合回测高频交易策略。

PyFolio 是一个开源的 Python 性能和风险分析库,由金融投资组合组成,与 Zipline 紧密集成。您可以在 github.com/quantopian/pyfolio 找到其文档。

使用这两个库来回测您的交易策略可以节省大量时间。

本章的目标是描述这些库的关键功能并建立您的直觉。鼓励您在 PyCharm 或任何其他 Python IDE 中调试代码,并研究每个结果变量的内容以充分利用提供的信息。一旦您熟悉了每个结果对象的内容,简要地研究这些库的源代码以查看其全部功能。

安装 Zipline 和 PyFolio

我们建议按照 附录 A 中描述的方式设置开发环境。尽管如此,详细的说明在以下各节中给出。

安装 Zipline

出于性能原因,Zipline 严重依赖于特定版本的 Python 及其相关库。因此,最好的安装方式是在 conda 虚拟环境中创建并在那里安装 Zipline。我们建议使用 Anaconda Python 进行此操作。

让我们创建一个名为 zipline_env 的虚拟环境,使用 Python 3.6,并安装 zipline 包:

conda create -n zipline_env python=3.6
conda activate zipline_env
conda install -c conda-forge zipline

现在我们将安装 PyFolio。

安装 PyFolio

您可以通过 pip 安装 pyfolio 包:

pip install pyfolio

正如我们所见,安装 PyFolio 也是一项简单的任务。

将市场数据导入到 Zipline/PyFolio 回测系统中

回测依赖于我们拥有广泛的市场数据数据库。

Zipline 引入了两个与市场数据相关的术语 - bundle 和 ingest:

  • Bundle 是从自定义源逐步将市场数据导入到 Zipline 的专有数据库的接口。
  • Ingest 是将自定义源市场数据逐步导入到 Zipline 的专有数据库的实际过程;数据摄取不会自动更新。每次需要新鲜数据时,您都必须重新进行数据摄取。

默认情况下,Zipline 支持以下 bundle:

  • 历史 Quandl bundle(2018 年之前的美国股票每日免费数据)
  • .csv 文件 bundle

现在我们将更详细地学习如何导入这两个 bundle。

从历史 Quandl bundle 导入数据

首先,在激活的 zipline_env 环境中,将 QUANDL_API_KEY 环境变量设置为您的免费(或付费)Quandl API 密钥。然后,进行 quandl 数据摄取。

对于 Windows,请使用以下代码:

SET QUANDL_API_KEY=XXXXXXXX
zipline ingest -b quandl

对于 Mac/Linux,请使用以下代码:

export QUANDL_API_KEY=XXXXXXXX
zipline ingest -b quandl

注意

Quandl 在 2018 年停止更新免费 bundle,但对于最初的几个算法交易步骤仍然非常有用。

最好在 Windows 的系统属性中设置 QUANDL_API_KEY(按下 Windows 图标并键入 Environment Variables):


图 8.1 – 在 Windows 上定位“编辑系统环境变量”对话框

然后,选择 编辑系统环境变量


图 8.2 – 在 Windows 的系统属性中定位“环境变量…”对话框

然后,在**环境变量…**对话框中指定变量。

对于 Mac/Linux,将以下命令添加到 ~/.bash_profile 以进行基于用户的操作,或添加到 ~/.bashrc 以进行非登录交互式 shell:

export QUANDL_API_KEY=xxxx

现在,让我们学习如何从 CSV 文件 bundle 导入数据。

从 CSV 文件 bundle 导入数据

默认的 CSV bundle 要求 CSV 文件采用 开盘价、最高价、最低价、收盘价、成交量OHLCV)格式,并带有日期、红利和拆分:

date,open,high,low,close,volume,dividend,split

本书的 GitHub 存储库包含一个示例输入 CSV 文件。其前几行如下所示:

date,open,high,low,close,volume,dividend,split
2015-05-15,18251.9707,18272.7207,18215.07031,18272.56055,108220000,0,0
2015-05-18,18267.25,18325.53906,18244.25977,18298.88086,79080000,0,0
2015-05-19,18300.48047,18351.35938,18261.34961,18312.39063,87200000,0,0
2015-05-20,18315.06055,18350.13086,18272.56055,18285.40039,80190000,0,0
2015-05-21,18285.86914,18314.89063,18249.90039,18285.74023,84270000,0,0
2015-05-22,18286.86914,18286.86914,18217.14063,18232.01953,78890000,0,0
2015-05-26,18229.75,18229.75,17990.01953,18041.53906,109440000,0,0

要使用自定义 CSV 文件 bundle,请按照以下步骤操作:

  1. 为 CSV 文件创建一个目录,例如C:\MarketData,其中包含一个名为Daily的子目录。
  2. 将 CSV 文件复制到创建的目录中(例如C:\MarketData\Daily)。
  3. 在 Windows 的C:\Users\\.zipline\extension.py目录或 Mac/Linux 的~/.zipline/extension.py中编辑.py文件扩展名,如下所示:
import pandas as pd
from zipline.data.bundles import register
from zipline.data.bundles.csvdir import csvdir_equities
register(
    'packt-csvdir-bundle',
    csvdir_equities(
        ['daily'],
        'c:/MarketData/',
    ),
    calendar_name='NYSE', 
    start_session=pd.Timestamp('2015-5-15', tz='utc'),
    end_session=pd.Timestamp('2020-05-14', tz='utc')
)
  1. 请注意,我们将市场数据与交易日历相关联。在这种情况下,我们使用的是NYSE,对应美国股票。
  2. 摄入捆绑包,如下所示:
zipline ingest -b packt-csvdir-bundle
  1. 输出如下:


图 8.3 – zipline 摄入 packt-csvdir-bundle 的输出

这已经创建了一个具有A票据的资产。

从自定义捆绑包导入数据

历史 Quandl 捆绑包最适合学习如何设计和回测算法策略。CSV 文件捆绑包最适合导入没有公开价格的资产的价格。但是,对于其他用途,您应该购买市场数据订阅。

从 Quandl 的 EOD 美国股票价格数据导入数据

Quandl 提供每月 49 美元的 End of Day 美国股票价格数据库订阅服务(www.quandl.com/data/EOD-End-of-Day-US-Stock-Prices),季度或年度付款可享受折扣。

与其他服务相比,该服务的优点如下:

  • Quandl 已深度集成到 Zipline 中,您可以使用一个命令下载所有股票的历史记录。
  • 与其他提供商不同,每月您可以进行的 API 调用数量没有硬限制。

安装自定义捆绑包很简单:

  1. 使用以下命令找到bundles目录的位置:
python -c "import zipline.data.bundles as bdl; print(bdl.__path__)"
  1. 在我的计算机上,这导致以下输出:
['d:\\Anaconda3\\envs\\zipline_env\\lib\\site-packages\\zipline\\data\\bundles']
  1. quandl_eod.py文件从本书的 GitHub 存储库复制到该目录中。该文件是对 Zipline 的 GitHub 上代码的轻微修改。
  2. 在相同的目录中,修改__init__.py文件(在那里添加这行):
from . import quandl_eod  # noqa

完整的__init__.py文件示例如下:

# These imports are necessary to force module-scope register calls to happen.
from . import quandl  # noqa
from . import csvdir  # noqa
from . import quandl_eod  # noqa
from .core import (
    UnknownBundle,
    bundles,
    clean,
    from_bundle_ingest_dirname,
    ingest,
    ingestions_for_bundle,
    load,
    register,
    to_bundle_ingest_dirname,
    unregister,
)
__all__ = [
    'UnknownBundle',
    'bundles',
    'clean',
    'from_bundle_ingest_dirname',
    'ingest',
    'ingestions_for_bundle',
    'load',
    'register',
    'to_bundle_ingest_dirname',
    'unregister',
] 

安装完成后,请确保您已将QUANDL_API_KEY环境变量设置为您的 API 密钥,并运行ingest命令:

zipline ingest -b quandl_eod

输出如下:


图 8.4 – 摄入 quandl_eod 捆绑包的输出

quandl_eod.py的实际源代码是不言自明的。带有@bundles.register("quandl_eod")注解的quandl_eod_bundle函数定义了下载过程:

@bundles.register("quandl_eod")
def quandl_eod_bundle(environ,
                  asset_db_writer,
                  minute_bar_writer,
                  daily_bar_writer,
                  adjustment_writer,
                  calendar,
                  start_session,
                  end_session,
                  cache,
                  show_progress,
                  output_dir):
    """
    quandl_bundle builds a daily dataset using Quandl's WIKI Prices dataset.
    For more information on Quandl's API and how to obtain an API key,
    please visit https://docs.quandl.com/docs#section-authentication
    """
    api_key = environ.get("QUANDL_API_KEY")
    if api_key is None:
        raise ValueError(
            "Please set your QUANDL_API_KEY environment variable and retry."
        )
    raw_data = fetch_data_table(
        api_key, show_progress, 
        environ.get("QUANDL_DOWNLOAD_ATTEMPTS", 5)
    )
    asset_metadata = \
    gen_asset_metadata(raw_data[["symbol", "date"]], 
                       show_progress)
    asset_db_writer.write(asset_metadata)
    symbol_map = asset_metadata.symbol
    sessions = calendar.sessions_in_range(start_session, 
                                          end_session)
    raw_data.set_index(["date", "symbol"], inplace=True)
    daily_bar_writer.write(
        parse_pricing_and_vol(raw_data, sessions,
                              symbol_map),
        show_progress=show_progress,
    )
    raw_data.reset_index(inplace=True)
    raw_data["symbol"] = \
    raw_data["symbol"].astype("category")
    raw_data["sid"] = raw_data.symbol.cat.codes
    adjustment_writer.write(
        splits=parse_splits(
            raw_data[["sid", "date", "split_ratio"]].loc[raw_data.split_ratio != 1],
            show_progress=show_progress,
        ),
        dividends=parse_dividends(
            raw_data[["sid", "date", "ex_dividend"]].loc[raw_data.ex_dividend != 0],
            show_progress=show_progress,
        ),
    )

参与此过程的步骤如下:

  1. 下载所有 EOD 数据。
  2. 生成元数据。
  3. 应用交易日历。
  4. 应用企业事件。

虽然 Quandl 的商业数据源已深度集成到 Zipline 中,但存在替代数据源。

从雅虎财经和 IEX 付费数据导入数据

该项目在 github.com/hhatefi/zipline_bundles 提供了一个用于 Yahoo Finance 和 IEX 的 Zipline bundle。该软件包支持从 Yahoo Finance 的 .csv 文件、直接从 Yahoo Finance 和从 IEX 导入 Zipline。本书仅专注于从 Yahoo Finance 和 IEX 直接导入。

虽然该软件包允许自动安装,但我不建议这样做,因为它要求在 Windows 的 C:\Users\\.zipline\extension.py 目录或 Mac/Linux 的 ~/.zipline/extension.py 目录中有一个空的 extension.py 文件。

安装步骤如下:

  1. github.com/hhatefi/zipline_bundles 下载该仓库。
  2. 将仓库的 \zipline_bundles-master\lib\extension.py 文件与 Windows 的 C:\Users\\.zipline\extension.py 或 Mac/Linux 的 ~/.zipline/extension.py 合并。如果后者文件不存在,只需复制并粘贴该文件。
  3. 在以下代码中编辑起始日期和结束日期:
register('yahoo_direct', # bundle's name
         direct_ingester('YAHOO',
                         every_min_bar=False,
                         symbol_list_env='YAHOO_SYM_LST', 
# the environment variable holding the comma separated list of assert names
                         downloader=yahoo.get_downloader(start_date='2010-01-01',
                                                         end_date='2020-01-01'
                         ),
         ),
         calendar_name='NYSE',
)
  1. 在以下代码中执行相同操作:
register('iex', # bundle's name
         direct_ingester('IEX Cloud',
                         every_min_bar=False,
                         symbol_list_env='IEX_SYM_LST', 
# the environemnt variable holding the comma separated list of assert names
                         downloader=iex.get_downloader(start_date='2020-01-01',
                                                       end_date='2020-01-05'
                         ),
                         filter_cb=lambda df: df[[cal.is_session(dt) for dt in df.index]]
         ),
         calendar_name='NYSE',
)
  1. 完整文件应如下所示:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pathlib import Path
from zipline.data.bundles import register
from zipline.data.bundles.ingester import csv_ingester 
# ingester.py need to be placed in zipline.data.bundles
_DEFAULT_PATH = str(Path.home()/'.zipline/csv/yahoo')
register(
    'yahoo_csv',
    csv_ingester('YAHOO',
                 every_min_bar=False, 
                 # the price is daily
                 csvdir_env='YAHOO_CSVDIR',
                 csvdir=_DEFAULT_PATH,
                 index_column='Date',
                 column_mapper={'Open': 'open',
                                'High': 'high',
                                'Low': 'low',
                                'Close': 'close',
                                'Volume': 'volume',
                                'Adj Close': 'price',
                 },
    ),
    calendar_name='NYSE',
)
from zipline.data.bundles.ingester import direct_ingester
from zipline.data.bundles import yahoo
register('yahoo_direct', # bundle's name
         direct_ingester('YAHOO',
                         every_min_bar=False,
                         symbol_list_env='YAHOO_SYM_LST', # the environemnt variable holding the comma separated list of assert names
                         downloader=yahoo.get_downloader(start_date='2010-01-01',
                                                         end_date='2020-01-01'
                         ),
         ),
         calendar_name='NYSE',
)
from zipline.data.bundles import iex
import trading_calendars as tc
cal=tc.get_calendar('NYSE')
register('iex', # bundle's name
         direct_ingester('IEX Cloud',
                         every_min_bar=False,
                         symbol_list_env='IEX_SYM_LST', # the environemnt variable holding the comma separated list of assert names
                         downloader=iex.get_downloader(start_date='2020-01-01',
                                                       end_date='2020-01-05'
                         ),
                         filter_cb=lambda df: df[[cal.is_session(dt) for dt in df.index]]
         ),
         calendar_name='NYSE',
)
  1. 使用以下命令查找 bundles 目录的位置:
python -c "import zipline.data.bundles as bdl; print(bdl.__path__)"
  1. 这将在我的计算机上产生以下输出:
['d:\\Anaconda3\\envs\\zipline_env\\lib\\site-packages\\zipline\\data\\bundles']
  1. Copy \zipline_bundles-master\lib\iex.py\zipline_bundles-master\lib\ingester.py\zipline_bundles-master\lib\yahoo.py 仓库文件复制到您的 Zipline bundles 目录;例如,d:\\Anaconda3\\envs\\zipline_env\\lib\\site-packages\\zipline\\data\\bundles\
  2. 将感兴趣的股票代码设置为环境变量。例如,在 Windows 上,使用以下代码:
set YAHOO_SYM_LST=GOOG,AAPL,GE,MSFT
    set IEX_SYM_LST=GOOG,AAPL,GE,MSFT
  1. 在 Mac/Linux 上,请使用以下代码:
export YAHOO_SYM_LST=GOOG,AAPL,GE,MSFT
    export IEX_SYM_LST=GOOG,AAPL,GE,MSFT
  1. 如果有可用的 IEX 令牌(以 sk_ 开头),请在 Windows 上像这样设置:
set IEX_TOKEN=xxx
  1. 对于 Mac/Linux,请执行以下操作:
export IEX_TOKEN=xxx
  1. 导入数据:
zipline ingest -b yahoo_direct
zipline ingest -b iex
  1. 这将导致关于 yahoo_direct bundle 的以下输出:


图 8.5 – 导入 yahoo_direct bundle 的输出

这也会导致以下输出,这是关于 iex bundle 的:


图 8.6 – 导入 iex bundle 的输出

与其他数据源集成,例如本地 MySQL 数据库,类似于 github.com/hhatefi/zipline_bundles 中的代码。某些这样的 bundle 可在 github.com 上获得。

Python 金融交易实用指南(三)(5)https://developer.aliyun.com/article/1523776

相关文章
|
24天前
|
存储 算法 数据挖掘
Python 金融交易实用指南(一)(5)
Python 金融交易实用指南(一)
26 4
|
24天前
|
数据可视化 算法 Linux
Python 金融交易实用指南(一)(3)
Python 金融交易实用指南(一)
22 3
|
24天前
|
存储 算法 Linux
Python 金融交易实用指南(四)(5)
Python 金融交易实用指南(四)
17 3
|
24天前
|
Python
Python 金融交易实用指南(四)(2)
Python 金融交易实用指南(四)
16 3
|
24天前
|
索引 Python
Python 金融交易实用指南(一)(4)
Python 金融交易实用指南(一)
14 2
|
24天前
|
数据采集 数据可视化 算法
Python 金融交易实用指南(一)(2)
Python 金融交易实用指南(一)
20 2
|
24天前
|
存储 算法 数据可视化
Python 金融交易实用指南(一)(1)
Python 金融交易实用指南(一)
17 2
|
24天前
|
算法 Python
Python 金融交易实用指南(四)(4)
Python 金融交易实用指南(四)
12 1
|
24天前
|
算法 Python
Python 金融交易实用指南(四)(3)
Python 金融交易实用指南(四)
13 1
|
24天前
|
存储 算法 Python
Python 金融交易实用指南(四)(1)
Python 金融交易实用指南(四)
10 0