Python财务分析-Pandas复制Google Trends

本文介绍了一种使用谷歌趋势数据预测金融市场走势的方法,通过分析搜索词如“debt”与道琼斯工业指数的关系,构建了交易策略并计算了其回报。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

复制利用谷歌趋势量化金融市场的交易行为

这是发表于《自然》的一篇论文:
Quantifying Trading Behavior in Financial Markets Using Google Trends.
翻译为:利用谷歌趋势量化金融市场的交易行为。

第一部分介绍了 Pandas 的基础知识以及如何使用它来分析财务数据。

在第二部分,我们将重申这些概念,通过应用它们来重现最近发表的一篇关于使用谷歌趋势搜索量搜索特定术语的论文(例如 ‘debt’(债务))来预测市场走势。有几个单元格是空的,供您填写。

此外,我们将看到如何使用 Pandas 测试实际的交易策略并计算其性能。

先导入所有需要的包

import datetime  # 日期时间库
import numpy as np  # 数组数学库
import pandas as pd  # numpy的数据分析工具,建议0.19版本以上
import pandas_datareader as pdr  # 原pandas.io,一般用作财经工具,建议0.8.1以上
import matplotlib.pyplot as plt  # 绘图库,最常用的可视化工具之一
import tushare as ts  # 财经数据接口包
import matplotlib as mpl  # 绘图库,最常用的可视化工具之一

再调整一下

mpl.rc('figure', figsize=(8, 7))

Tobias Preis 非常好心地向我提供了这份出版物中使用的数据。有许多谷歌趋势搜索词,但在这里我们将只使用 ‘debt’ 。

data = pd.read_csv('data/GoogleTrendsData.csv', index_col='Date', parse_dates=True)
data.head()
                djia      debt
Date                          
2004-01-14  10485.18  0.210000
2004-01-22  10528.66  0.210000
2004-01-28  10702.51  0.210000
2004-02-04  10499.18  0.213333
2004-02-11  10579.03  0.200000

接下来构图:

data.plot(subplots=True)
----------result----------
array([<matplotlib.axes._subplots.AxesSubplot object at 0x000001E772A065F8>,
       <matplotlib.axes._subplots.AxesSubplot object at 0x000001E774D32320>],
      dtype=object)
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yQb4EJEB-1586415134516)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200403153733407.png)]

作者通过形成移动平均线并测试当前值是否与过去3周的移动平均线相交,来检测搜索量在任何给定的周内是否相对增加或减少。

我们先来计算移动平均线。

data['debt_mavg'] = pd.rolling_mean(data.debt, 3)
data.head()
----------result----------
                djia      debt  debt_mavg
Date                                     
2004-01-14  10485.18  0.210000        NaN
2004-01-22  10528.66  0.210000        NaN
2004-01-28  10702.51  0.210000   0.210000
2004-02-04  10499.18  0.213333   0.211111
2004-02-11  10579.03  0.200000   0.207778

因为我们想看看当前值高于均线的前述几个星期,所以我们必须将移动平均时间序列向前移动一下。

data['debt_mavg'] = data.debt_mavg.shift(1)
data.head(10)
----------result----------
                djia      debt  debt_mavg
Date                                     
2004-01-14  10485.18  0.210000        NaN
2004-01-22  10528.66  0.210000        NaN
2004-01-28  10702.51  0.210000        NaN
2004-02-04  10499.18  0.213333   0.210000
2004-02-11  10579.03  0.200000   0.211111
2004-02-19  10714.88  0.203333   0.207778
2004-02-25  10609.62  0.200000   0.205555
2004-03-03  10678.14  0.200000   0.201111
2004-03-10  10529.48  0.196667   0.201111
2004-03-17  10102.89  0.196667   0.198889

生成命令信号

摘要:
“我们使用谷歌趋势来确定n(t - 1)对特定的搜索项进行了多少次搜索,比如第t - 1周的债务,谷歌将周定义为在周日结束,与在此期间谷歌上执行的搜索总数相关。”
并且
“我们实现这个策略通过出售道琼斯工业指数的收盘价p (t)的第一个交易日周t,如果Δn (t−1,Δt) > 0,和购买道琼斯工业指数的价格p (t(1)第一个交易日结束时的下周。[…]。如果Δn (t−1,Δt) < 0,那么我们购买道琼斯工业指数的收盘价p (t)的第一个交易日周t和出售道琼斯工业指数的价格p (t 1)在未来一周的第一个交易日。”

data['order'] = 0
data['order'][data.debt > data.debt_mavg] = -1 # Short if search volume goes up relative to mavg.
data['order'][data.debt < data.debt_mavg] = 1 # Long if search volume goes down relative to mavg.
data.head(10)
----------result----------
                djia      debt  debt_mavg  order
Date                                            
2004-01-14  10485.18  0.210000        NaN      0
2004-01-22  10528.66  0.210000        NaN      0
2004-01-28  10702.51  0.210000        NaN      0
2004-02-04  10499.18  0.213333   0.210000     -1
2004-02-11  10579.03  0.200000   0.211111      1
2004-02-19  10714.88  0.203333   0.207778      1
2004-02-25  10609.62  0.200000   0.205555      1
2004-03-03  10678.14  0.200000   0.201111      1
2004-03-10  10529.48  0.196667   0.201111      1
2004-03-17  10102.89  0.196667   0.198889      1

计算回报

data['ret_djia'] = data.djia.pct_change()
data.head()
----------result----------
                djia      debt  debt_mavg  order  ret_djia
Date                                                      
2004-01-14  10485.18  0.210000        NaN      0       NaN
2004-01-22  10528.66  0.210000        NaN      0  0.004147
2004-01-28  10702.51  0.210000        NaN      0  0.016512
2004-02-04  10499.18  0.213333   0.210000     -1 -0.018998
2004-02-11  10579.03  0.200000   0.211111      1  0.007605

第 t 周的收益与第 t-1 周有关。然而,我们在第 t 周买入,然后在 t+1 周卖出,因此 我们必须通过提高回报率来进行调整。

data['ret_djia'] = data['ret_djia'].shift(-1)
data.head()
----------result----------
                djia      debt  debt_mavg  order  ret_djia
Date                                                      
2004-01-14  10485.18  0.210000        NaN      0  0.004147
2004-01-22  10528.66  0.210000        NaN      0  0.016512
2004-01-28  10702.51  0.210000        NaN      0 -0.018998
2004-02-04  10499.18  0.213333   0.210000     -1  0.007605
2004-02-11  10579.03  0.200000   0.211111      1  0.012841

作者使用的算法是在每周一做出做多或做空道琼斯的决定。过了这个星期,我们退出所有的仓位( 如果我们渴望,就卖;如果我们做空,就买 ),然后做出一个新的交易决定。

ret 列包含每周回报。因此,如果我们在第 t 周买,在第 t+1 周卖,我们就得到了第 t+1 周的回报。相反,如果我们在第 t 周做空,在第 t+1 周买回,我们得到的是 t+1周的负回报。

# 计算我们的策略回报
data['ret_google'] = data.order * data.ret_djia
data.head(10)
----------result----------
                djia      debt  debt_mavg  order  ret_djia  ret_google
Date                                                                  
2004-01-14  10485.18  0.210000        NaN      0  0.004147    0.000000
2004-01-22  10528.66  0.210000        NaN      0  0.016512    0.000000
2004-01-28  10702.51  0.210000        NaN      0 -0.018998   -0.000000
2004-02-04  10499.18  0.213333   0.210000     -1  0.007605   -0.007605
2004-02-11  10579.03  0.200000   0.211111      1  0.012841    0.012841
2004-02-19  10714.88  0.203333   0.207778      1 -0.009824   -0.009824
2004-02-25  10609.62  0.200000   0.205555      1  0.006458    0.006458
2004-03-03  10678.14  0.200000   0.201111      1 -0.013922   -0.013922
2004-03-10  10529.48  0.196667   0.201111      1 -0.040514   -0.040514
2004-03-17  10102.89  0.196667   0.198889      1 -0.003775   -0.003775

现在我们只需要计算复利。当我们把赚来的钱进行再投资时,回报实际上不是把它们加起来计算的,而是用它们的累计乘积计算的:

i t = ( i t − 1 + i t − 1 ⋅ r t ) = ( 1 + r t ) ⋅ i t − 1 , i 0 = 1 i_t = (i_{t-1} + i_{t-1} \cdot r_t) = (1 + r_t) \cdot i_{t-1}, \quad i_0 = 1 it=(it1+it1rt)=(1+rt)it1,i0=1

plt.figure(figsize=(10, 3))
(1 + data.ret_google).cumprod().plot()
plt.ylabel('Portfolio value')
----------result----------
Text(0, 0.5, 'Portfolio value')
plt.show()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SqfGC5Z5-1586415134517)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200403175525081.png)]

限制

我们已经看到, Pandas 可以非常灵活而强大地处理时间序列财务数据。

使用一些基本的金融数学,我们甚至可以实现一个简单的回测。

然而,如果我们真的想在现实世界中运行这个我们在这里忽略了的策略,就会涉及到很多复杂性:

  • 容易产生误差
  • 没有考虑交易成本
  • 我们自己的订单对价格的影响。
  • 预测偏差: 我们可以获得整个历史,这使得我们很容易使用我们无法获得的信息。

因此,为了真正正确地反测试一个策略,我们需要模拟所有这些东西。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值