Python 金融交易实用指南(一)(2)

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

Python 金融交易实用指南(一)(1)https://developer.aliyun.com/article/1523859

概要

在本章中,我们学习了什么时候算法交易比手动交易更具优势,金融资产类别是什么,最常用的订单类型是什么,限价订单簿是什么,以及订单是如何由金融交易所匹配的。

我们还讨论了算法交易系统的关键组成部分 - 核心基础设施和量化基础设施,包括交易策略、执行、限价订单簿、持仓、PnL 管理、回测、交易后分析和风险管理。

在下一章中,我们将讨论 Python 在算法交易中的价值。

第二部分:深入了解用于金融数据集分析的 Python 库

本节将深入介绍核心 Python 库 NumPy 和 pandas,这些库用于分析和操作大型数据框。我们还将涵盖与 pandas 密切相关的可视化库 Matplotlib。最后,我们将介绍 statsmodels 和 scikit-learn 库,这些库允许更高级的金融数据集分析。

本节包括以下章节:

  • 第二章*, Python 中的探索性数据分析*
  • 第三章*, 使用 NumPy 进行高速科学计算*
  • 第四章*, 使用 Pandas 进行数据操作和分析*
  • 第五章*, 使用 Matplotlib 进行数据可视化*
  • 第六章*, 统计估计、推断和预测*

第二章:Python 中的探索性数据分析

本章重点介绍探索性数据分析EDA),这是处理任何数据集的第一步。EDA 的目标是将数据加载到最适合进一步分析的数据结构中,以识别和纠正任何错误/坏数据,并获得对数据的基本见解——字段的类型有哪些;它们是否是分类的;有多少缺失值;字段之间的关系等等。

这些是本章讨论的主要话题:

  • EDA 介绍
  • 用于 EDA 的特殊 Python 库

技术要求

本章中使用的 Python 代码可以在书的代码库中的Chapter02/eda.ipynb笔记本中找到。

EDA 介绍

EDA 是从感兴趣的结构化/非结构化数据中获取、理解和得出有意义的统计见解的过程。这是在对数据进行更复杂的分析之前的第一步,例如从数据中预测未来的期望。在金融数据的情况下,EDA 有助于获得后续用于构建盈利交易信号和策略的见解。

EDA 指导后续决策,包括使用或避免哪些特征/信号,使用或避免哪些预测模型,并验证和引入关于变量性质和它们之间关系的正确假设,同时否定不正确的假设。

EDA 也很重要,可以理解样本(完整数据集的代表性较小数据集)统计数据与总体(完整数据集或终极真相)统计数据之间的差异,并在绘制关于总体的结论时记住这一点,基于样本观察。因此,EDA 有助于减少后续可能的搜索空间;否则,我们将浪费更多的时间后来构建不正确/不重要的模型或策略。

必须以科学的心态来对待 EDA。有时,我们可能会基于轶事证据而不是统计证据得出不充分验证的结论。

基于轶事证据的假设受到以下问题的影响:

  • 不具有统计学意义——观测数量太少。
  • 选择偏见——假设只是因为它首先被观察到而产生的。
  • 确认偏见——我们对假设的内在信念会偏向于我们的结果。
  • 观察中的不准确性。

让我们探索 EDA 涉及的不同步骤和技术,使用真实数据集。

EDA 的步骤

以下是 EDA 涉及的步骤列表(我们将在接下来的子章节中逐个进行讨论):

  1. 加载必要的库并进行设置
  2. 数据收集
  3. 数据整理/整理
  4. 数据清洗
  5. 获得描述性统计
  6. 数据的可视化检查
  7. 数据清洗
  8. 高级可视化技术

加载必要的库并进行设置

我们将使用numpypandasmatplotlib,这些库可以通过以下代码加载:

%matplotlib inline
import numpy as np
import pandas as pd
from scipy import stats
import seaborn as sn
import matplotlib.pyplot as plt
import mpld3
mpld3.enable_notebook()
import warnings
warnings.filterwarnings('ignore')
pd.set_option('display.max_rows', 2)

我们使用mpld3库来启用 Jupyter 的matplotlib图表内的缩放。 前面代码块的最后一行指定了应显示pandas DataFrame 的最大行数为两行。

数据收集

数据收集通常是 EDA 的第一步。 数据可能来自许多不同的来源(逗号分隔值CSV)文件、Excel 文件、网页抓取、二进制文件等),通常需要正确标准化和首先正确格式化在一起。

对于这个练习,我们将使用存储在.csv格式中的 5 年期间的三种不同交易工具的数据。 这些工具的身份故意没有透露,因为这可能泄露它们的预期行为/关系,但我们将在练习结束时透露它们的身份,以直观地评估我们对它们进行的 EDA 的表现如何。

让我们从加载我们可用的数据集开始,将其加载到三个 DataFrame(ABC)中,如下所示:

A = pd.read_csv('A.csv', parse_dates=True, index_col=0);
A

DataFrame A的结构如下所示:


图 2.1 – 从 A.csv 文件构造的 DataFrame

类似地,让我们加载 DataFrame B,如下所示:

B = pd.read_csv('B.csv', parse_dates=True, index_col=0); 
B

DataFrame B的结构如下所示:


图 2.2 – 从 B.csv 文件构造的 DataFrame

最后,让我们将C数据加载到一个 DataFrame 中,如下所示:

C = pd.read_csv('C.csv', parse_dates=True, index_col=0); 
C

我们看到C有以下字段:


图 2.3 – 从 C.csv 文件构造的 DataFrame

如我们所见,所有三个数据源的格式都是2015-05-152020-05-14

数据整理/处理

数据很少是以可直接使用的格式提供的。 数据整理/处理指的是从初始原始来源操纵和转换数据的过程,使其成为结构化的、格式化的和易于使用的数据集。

让我们使用pandas.DataFrame.join(...)来合并这些 DataFrame,并对齐它们以具有相同的DateTimeIndex格式。 使用lsuffix=rsuffix=参数,我们将_A_B_C后缀分配给来自三个 DataFrame 的列,如下所示:

merged_df = A.join(B, how='outer', lsuffix='_A', sort=True).join(C, how='outer', lsuffix='_B', rsuffix='_C', sort=True)
merged_df

我们将检查我们刚刚创建的merged_df DataFrame,并确保它具有我们从所有三个 DataFrame 中预期的所有字段(仅显示前七列)。 DataFrame 可以在这里看到:


图 2.4 – 通过合并 DataFrame A、B 和 C 构造的 DataFrame

请注意,原始三个数据框(ABC)分别有 1,211、1,209 和 1,206 行,但合并后的数据框有 1,259 行。这是因为我们使用了外部连接,它使用了所有三个数据框的日期的并集。当它在特定日期的特定数据框中找不到值时,它会将该数据框的字段的那个位置放置一个 NaN 值。

数据清洗

数据清洗是指处理来自缺失数据、不正确数据值和异常值的数据错误的过程。

在我们的示例中,merged_df 的许多字段都缺失原始数据集和不同日期数据框合并而来的字段。

让我们首先检查是否存在所有值都缺失(NaN)的行,如下所示:

merged_df[merged_df.isnull().all(axis=1)]

结果表明,我们没有任何所有字段都缺失的行,如我们所见:


图 2.5 – DataFrame 表明没有所有字段都缺失的行。

现在,让我们找出有多少行存在至少一个字段缺失/NaN 的,如下所示:

merged_df[['Close_A', 'Close_B', 'Close_C']].isnull().any(axis=1).sum()

因此,结果显示我们的 1,259 行中有 148 行具有一个或多个字段缺失值,如下所示:

148

对于我们的进一步分析,我们需要有效的 Close 价格。因此,我们可以通过运行以下代码删除所有三个工具的任何 Close 价格缺失的行:

valid_close_df = merged_df.dropna(subset=['Close_A', 'Close_B', 'Close_C'], how='any')

删除缺失的 Close 价格后,我们不应该再有缺失的 Close 价格字段,如下代码段所示:

valid_close_df[['Close_A', 'Close_B', 'Close_C']].isnull().any(axis=1).sum()

结果证实,不再存在任何 Close_AClose_BClose_C 字段为 NaN 值的行,如我们所见:

0

让我们检查新的 DataFrame,如下所示:

valid_close_df

这是结果(仅显示前七列):


图 2.6 – 没有任何收盘价缺失/NaN 值的结果 DataFrame

如预期的那样,我们删除了具有任何收盘价缺失/NaN 值的 148 行。

接下来,让我们处理任何其他字段具有 NaN 值的行,首先了解有多少这样的行。我们可以通过运行以下代码来做到这一点:

valid_close_df.isnull().any(axis=1).sum()

这是该查询的输出:

165

因此,存在 165 行至少有一些字段缺失值。

让我们快速检查一下至少有一些字段缺失值的几行,如下所示:

valid_close_df[valid_close_df.isnull().any(axis=1)]

以下显示了一些具有一些缺失值的行(仅显示前七列),如下所示:


图 2.7 – DataFrame 表明仍然有一些行存在一些缺失值

因此,我们可以看到 2015-05-18(在前述截屏中不可见)的 Low_C 字段和 2020-05-01Open_B 字段有 NaN 值(当然还有其他 163 个)。

让我们使用 pandas.DataFrame.fillna(...) 方法与一种称为 backfill 的方法 —— 这使用缺失值后的下一个有效值来填充缺失值。代码如下所示:

valid_close_complete = valid_close_df.fillna(method='backfill')

让我们看看 backfilling 的影响,如下所示:

valid_close_complete.isnull().any(axis=1).sum()

现在,这是查询的输出:

0

正如我们所看到的,在进行 backfill 操作之后,任何行的任何字段都不再有缺失或 NaN 值。

获取描述性统计数据

下一步是生成数据的关键基本统计信息,以便熟悉每个字段,使用 DataFrame.describe(...) 方法。代码如下所示:

pd.set_option('display.max_rows', None)
valid_close_complete.describe()

请注意,我们已经增加了要显示的 pandas DataFrame 的行数。

这是运行 pandas.DataFrame.describe(…) 后的输出,仅显示了前七列:


图 2.8 – 有效关闭完整 DataFrame 的描述统计

前面的输出为我们的 DataFrame 中的每个字段提供了快速摘要统计信息。

图 2.8 的关键观察点可以总结如下:

  • Volume_C 的所有统计值都为 0,这意味着每一行的 Volume_C 值都设置为 0。因此,我们需要移除此列。
  • Open_C 的最小值为 -400,这不太可能是真实的,原因如下:
    a) 其他价格字段 —— High_CLow_CClose_CAdj Close_C —— 的所有最小值都约为 9,因此 Open_C 具有 -400 的最小值是没有意义的。
    b) 考虑到 Open_C 的第 25 个百分位数为 12.4,其最小值不太可能远低于此。
    c) 资产的价格应为非负数。
  • Low_C 的最大值为 330,这同样不太可能,原因如下:
    a) 出于先前所述的相同原因,Open_C 是不正确的。
    b) 此外,考虑到 Low_C 应始终低于 High_C,根据定义,一天中的最低价格必须低于当天的最高价格。

让我们将所有 pandas DataFrame 的输出恢复为只有两行,如下所示:

pd.set_option('display.max_rows', 2)

现在,让我们移除所有三个工具的 Volume 字段,使用以下代码:

prices_only = valid_close_complete.drop(['Volume_A', 'Volume_B', 'Volume_C'], axis=1)
prices_only

prices_only DataFrame 具有以下数据(仅显示前七列):


图 2.9 – 仅价格的 DataFrame

预期之中的是,我们移除了三个工具的交易量列之后,将 DataFrame 维度减少到 1111 × 15 —— 这些以前是 1111 × 18

数据的视觉检查

似乎没有任何明显的错误或不一致之处,所以让我们快速可视化价格,看看这是否符合我们从描述性统计中学到的内容。

首先,我们将从A的价格开始,因为根据描述性统计摘要,我们期望这些是正确的。代码如下所示:

valid_close_complete['Open_A'].plot(figsize=(12,6), linestyle='--', color='black', legend='Open_A')
valid_close_complete['Close_A'].plot(figsize=(12,6), linestyle='-', color='grey', legend='Close_A')
valid_close_complete['Low_A'].plot(figsize=(12,6), linestyle=':', color='black', legend='Low_A')
valid_close_complete['High_A'].plot(figsize=(12,6), linestyle='-.', color='grey', legend='High_A')

输出与我们的期望一致,我们可以根据统计数据和下面截图中显示的图表得出A的价格是有效的结论:


图 2.10 – 展示了交易工具 A 的开盘价、收盘价、最高价和最低价在 5 年内的价格

现在,让我们绘制 C 的价格图,看看图表是否提供了关于我们怀疑某些价格不正确的进一步证据。代码如下所示:

valid_close_complete['Open_C'].plot(figsize=(12,6), linestyle='--', color='black', legend='Open_C')
valid_close_complete['Close_C'].plot(figsize=(12,6), linestyle='-', color='grey', legend='Close_C')
valid_close_complete['Low_C'].plot(figsize=(12,6), linestyle=':', color='black', legend='Low_C')
valid_close_complete['High_C'].plot(figsize=(12,6), linestyle='-.', color='grey', legend='High_C')

输出证实了Open_CLow_C具有一些与其他值极端相距甚远的错误值—这些是异常值。下面的截图显示了说明这一点的图表:


图 2.11 – 展示了 C 价格中正负两个方向的大异常值的图表

我们需要进行一些进一步的数据清理,以消除这些异常值,以便我们不从数据中得出不正确的统计见解。

检测和移除异常值最常用的两种方法是四分位数范围(IQR)和 Z 分数。

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

相关文章
|
数据可视化 数据处理 Python
如何使用Python实现一个基于均线的交易策略
【10月更文挑战第9天】本文介绍了如何使用Python实现一个基于均线的交易策略。主要步骤包括导入所需库(如`pandas`、`numpy`和`matplotlib`),加载股票或期货的历史数据,计算均线和其他指标,实现交易策略逻辑,以及可视化交易结果。示例代码展示了如何根据均线交叉点进行开仓、止损和止盈操作,并提供了注意事项,如数据来源、交易成本和风险管理。
905 7
|
数据采集 数据可视化 数据挖掘
金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析
本文探讨了金融资产波动率建模中的三种主流方法:GARCH、GJR-GARCH和HAR模型,基于SPY的实际交易数据进行实证分析。GARCH模型捕捉波动率聚类特征,GJR-GARCH引入杠杆效应,HAR整合多时间尺度波动率信息。通过Python实现模型估计与性能比较,展示了各模型在风险管理、衍生品定价等领域的应用优势。
1223 66
金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析
|
存储 分布式计算 数据可视化
Python 金融编程第二版(四)(2)
Python 金融编程第二版(四)
231 0
|
存储 SQL 数据可视化
Python 金融编程第二版(四)(1)
Python 金融编程第二版(四)
193 0
|
数据采集 数据可视化 数据处理
如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`)
本文介绍了如何使用Python实现一个交易策略。主要步骤包括:导入所需库(如`pandas`、`numpy`、`matplotlib`),加载历史数据,计算均线和其他技术指标,实现交易逻辑,记录和可视化交易结果。示例代码展示了如何根据均线交叉和价格条件进行开仓、止损和止盈操作。实际应用时需注意数据质量、交易成本和风险管理。
929 5
|
数据采集 人工智能 自然语言处理
AI Agent 金融助理0-1 Tutorial 利用Python实时查询股票API的FinanceAgent框架构建股票(美股/A股/港股) AI Finance Agent
金融领域Finance AI Agents方面的工作,发现很多行业需求和用户输入的 query都是和查询股价/行情/指数/财报汇总/金融理财建议相关。如果需要准确的 金融实时数据就不能只依赖LLM 来生成了。常规的方案包括 RAG (包括调用API )再把对应数据和prompt 一起拼接送给大模型来做文本生成。稳定的一些商业机构的金融数据API基本都是收费的,如果是以科研和demo性质有一些开放爬虫API可以使用。这里主要介绍一下 FinanceAgent,github地址 https://github.com/AI-Hub-Admin/FinanceAgent
|
机器学习/深度学习 存储 TensorFlow
使用Python实现深度学习模型:智能金融风控与信用评估
【7月更文挑战第25天】 使用Python实现深度学习模型:智能金融风控与信用评估
11710 7
|
监控 安全 数据挖掘
Python自动化交易
【8月更文挑战第7天】随着科技发展,自动化交易成为高效智能的投资方式。Python因其实用性和灵活性,在此领域大放异彩。本文介绍使用Python进行自动化交易的流程,包括获取市场数据、制定交易策略、执行交易、风险管理、监控与优化、实时监控及通知、心态管理、安全与隐私保护以及持续学习与优化等方面,并提供了具体的代码示例。通过这些步骤,读者可以构建自己的自动化交易系统,实现稳健的投资回报。
|
机器学习/深度学习 监控 算法
Python数据分析与机器学习在金融风控中的应用
Python数据分析与机器学习在金融风控中的应用
555 12
|
数据可视化 Python
Python 金融编程第二版(三)(4)
Python 金融编程第二版(三)
124 2

推荐镜像

更多