如何实施兴登堡预兆指标?

How to implement the Hindenburg omen indicator?

根据定义here,兴登堡预兆指标是:

The daily number of new 52-week highs and 52-week lows in a stock market index are greater than a threshold amount (typically 2.2%).

对我来说,这意味着,我们每天滚动并回顾 52 周或 252 business/trading 天,然后计算高点(或低点)的数量,最后计算出 return 或 pct_change,这是他们想要监控的新高(或低点)的比率,例如高于 2.2%

import pandas as pd
import numpy as np
import yfinance as yf

# download the S&P500 
df = yf.download('^GSPC')
# compute the "highs" and "lows"
df['Highs'] = df['Close'].rolling(252).apply(lambda x: x.cummax().diff().
    apply(lambda x: np.where(x > 0, 1, 0)).sum()).pct_change()
df['Lows'] = df['Close'].rolling(252).apply(lambda x: x.cummin().diff().
    apply(lambda x: np.where(x < 0, 1, 0)).sum()).pct_change()

我们的理解是一样的吗?有更好的方法吗?

有趣的问题!我可以推荐以下代码吗 - 它 运行s 比 apply 解决方案快得多,因为它是矢量化的,并且还更清楚地列出了步骤,以便您可以检查临时结果。

我得到的结果与您的代码不同 - 您也可以通过在底部的时间序列上绘制结果来进行比较。

import pandas as pd
import numpy as np
import yfinance as yf

# download the S&P500 
df = yf.download('^GSPC')

# Constants
n_trading_day_window = 252

# Simplify the input dataframe to only the relevant column
df_hin_omen = df[['Close']]
# Calculate rolling highs and lows
df_hin_omen.insert(1, 'rolling_high', df_hin_omen['Close'].rolling(n_trading_day_window).max())
df_hin_omen.insert(2, 'rolling_low', df_hin_omen['Close'].rolling(n_trading_day_window).min())
# High and low are simply when the given row matches the 252 day high or low
df_hin_omen.insert(3, 'is_high', df_hin_omen.Close == df_hin_omen.rolling_high)
df_hin_omen.insert(4, 'is_low', df_hin_omen.Close == df_hin_omen.rolling_low)
# Calculate rolling percentages
df_hin_omen.insert(5, 'percent_highs', df_hin_omen.is_high.rolling(n_trading_day_window).sum() / n_trading_day_window)
df_hin_omen.insert(6, 'percent_lows', df_hin_omen.is_low.rolling(n_trading_day_window).sum() / n_trading_day_window)

有了 运行 之后,您可以按如下方式检查结果:

import matplotlib, matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(16, 6))
df_hin_omen.resample('w').mean().percent_highs.plot(ax=ax)
df_hin_omen.resample('w').mean().percent_lows.plot(ax=ax)

Hindenburg Omen Definition,“兴登堡预兆寻找与前提的统计偏差,即在正常情况下,一些股票要么创下 52 周新高,要么创下 52 周新低。这将是如果两者同时发生则不正常。"

因此,从我们的图表来看,我的解释是股市目前收于许多 52 周高点,但并未显示出许多 52 周低点。另请注意引用的文章指出“据报道,它仅在 25% 的时间内正确预测了股市的大幅下跌。”所以我不确定我们是否可以对此读得太多...

编辑

我看过你的代码,我认为 pct_change 函数的使用不正确 - 它会计算滚动微分的变化,所以从例如 0.10 开始移动% 到 0.11% 实际上等同于 10% 的变化。相反,根据我上面的代码,你需要过去一年的滚动总和除以一年中的天数。