【问题标题】:How to create a column that returns the slope of a moving average?如何创建一个返回移动平均线斜率的列?
【发布时间】:2022-02-24 01:35:34
【问题描述】:

在包含比特币价格的数据框中,我想通过在每行上显示移动平均线(按 20 个周期计算)的斜率角度来衡量趋势的强度。

移动平均线可让您分析时间序列,消除瞬态波动以突出长期趋势。 为了计算用于交易目的的简单 20 周期移动平均线,我们将最后 20 个收盘价相加,然后将结果除以 20。

我开始尝试使用 scipy 的 linregress 函数,但我得到了我无法解决的异常“len() of unsized object”:

from scipy.stats import linregress
x = df.iloc[-1, 8] # -1:last row, 8: sma20
y = df['sma20']
df['slope_deg'] = df.apply(linregress(x, y))

然后我使用了数学模块的 atan 函数,但返回的结果总是 nan,无论行是什么:

import math
df['sma20'] =  df['Close'].rolling(20).mean()
slope=((df['sma20'][0]-df['sma20'][20])/20)
df['slope_deg'] = math.atan(slope) * 180 / math.pi

... 或 45 :

import math
df['sma20'] =  df['Close'].rolling(20).mean()
df['slope_deg'] = math.atan(1) * 180 / math.pi
df

这是一个以日期为索引的代码示例,用于计算移动平均线的价格和移动平均线(示例超过 5 个周期):

df= pd.DataFrame({'date':np.tile( pd.date_range('1/1/2011', 
periods=25, freq='D'), 4 ),
'price':(np.random.randn(100).cumsum() + 10),
'sma5':df['price'].rolling(5).mean() 
})

df.head(10)

谁能帮我创建一个返回移动平均线斜率的列?

【问题讨论】:

  • 可以提供几行df吗?
  • @G.Anderson,不幸的是,代码不起作用。在阅读 cmets 时,我不是唯一一个无法让这段代码工作的人。
  • @richardec,是的,但我不知道如何将它们发送给您。您必须想象数据框只有一列: df['Price'] 此价格随每一行而变化。通过取最后 20 行的平均值,我们得到 20 个周期的移动平均值。然后你必须计算这个移动平均线的斜率角度。第 12 行和第 13 行之间的角度为 x 度,第 13 行和第 14 行之间的角度为 x 度 ...
  • 请参阅 How to make good pandas examplesedit 您的问题以显示输入数据帧的示例

标签: python pandas trading


【解决方案1】:

好的,我做了 20 天的 sma,我不太确定斜坡部分,因为你没有明确说明你需要什么。

我假设斜率值(以度为单位)如下:

arctan( (PriceToday - Price20daysAgo)/ 20 )

这里有代码:

EDIT 1:简化了 'slope' 代码并根据 #Oliver 的建议进行了改编。

import pandas as pd
import yfinance as yf

btc          = yf.download('BTC-USD', period='1Y')
btc['sma20'] = btc.rolling(20).mean()['Adj Close']
btc['slope'] = np.degrees(np.arctan(btc['sma20'].diff()/20))
btc          = btc[['Adj Close','sma20','slope']].dropna()

输出:

btc

               Adj Close           sma20        slope
      Date          
2021-03-15  55907.199219    51764.509570     86.767651
2021-03-16  56804.902344    52119.488086     86.775283
2021-03-17  58870.894531    52708.340234     88.054732
2021-03-18  57858.921875    53284.298242     88.011217
2021-03-19  58346.652344    53892.208203     88.115671
... ... ... ...
2022-02-19  40122.156250    41560.807227     79.715989
2022-02-20  38431.378906    41558.219922     -7.371144
2022-02-21  37075.281250    41474.820312    -76.514600
2022-02-22  38286.027344    41541.472461     73.297321
2022-02-23  38748.464844    41621.165625     75.911862

如您所见,斜率值实际上意义不大。这是因为 20 天垃圾邮件的价格变化远大于 20 个单位,即代表您选择使用的时间窗口的值。

绘制价格和 sma20 与日期的关系。

btc[['Adj Close','sma20']].plot(figsize=(14,7));

【讨论】:

  • 嗨@P.Pinho,你是对的。我意识到我不够具体。您已经了解,目的是显示 20 周期移动平均线的角度。但我想要的不是超过 20 个周期的角度,而是从一个周期到另一个周期的角度,以便查看趋势(由移动平均线突出显示)是加速还是减速。
  • 有一点我不明白,如果斜率是基于最近 20 个周期的平均值,那么 'slope' 列应该用 nan 填充到第 21 行,对吧?
  • 是的。我使用 dropna( ) 从数据集中删除了所有 NaN 值。
  • 关于slope:你能描述一下计算的样子吗?您无需编写代码,只需对其进行描述,也许发布一个示例就足够了。
  • 例如,您已经很好地编码了 sma20。然后关于角度,请查看图表上 2021 年 10 月 1 日左右的 BCT 价格。您可以看到,从 sma20 的那一点开始反转并开始看涨。有趣的是在 10 月 1 日和 2 日之间,然后在 10 月 2 日和 3 日之间,然后在 3 日和 4 日之间有这个 sma20 的角度......在第一天,角度越来越大10 月,然后趋于稳定并在 10 月底开始下降,最后坡度在 11 月 10 日反转。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-19
  • 2017-04-24
  • 1970-01-01
  • 2021-11-21
  • 2017-09-01
  • 2013-12-22
相关资源
最近更新 更多