基本技术指标 Python 实现(1)https://developer.aliyun.com/article/1484220
积累分布线
计算
计算积累分布线(ADL)有三个步骤。首先,计算资金流乘数。其次,将此值乘以成交量以找到资金流量。第三,创建资金流量的累积总和以形成积累分布线(ADL)。
1\. Money Flow Multiplier = [(Close - Low) - (High - Close)] /(High - Low) 2\. Money Flow Volume = Money Flow Multiplier x Volume for the Period 3\. ADL = Previous ADL + Current Period's Money Flow Volume
资金流乘数在+1 和-1 之间波动。因此,它是资金流量和积累分布线的关键。当收盘价位于高低范围的上半部时,乘数为正,当位于下半部时为负。这是完全合理的。当价格收于周期范围的上半部时,买盘压力大于卖盘压力(反之亦然)。当乘数为正时,积累分布线上升,当乘数为负时,积累分布线下降。
乘数调整了最终进入资金流量的量。除非资金流量乘数处于极端值(+1 或-1),否则实际上会减少交易量。当收盘价处于高位时,乘数为+1,当收盘价处于低位时,乘数为-1。当乘数为+1 时,所有交易量为正,当乘数为-1 时,所有交易量为负。在 0.50 时,只有一半的交易量转化为该时期的资金流量。下表显示了 Research-in-Motion(RIMM)的资金流量乘数、资金流量和累积分布线。请注意,当收盘价强劲时,乘数在 0.50 和 1 之间,当收盘价疲弱时,乘数在-0.50 和-1 之间。
点击这里") 查看 Excel 电子表格中累积分布线的计算。
代码
名称:积累分布线(ADL) 描述:计算资金流乘数、资金流量和积累分布线(ADL) import pandas as pd def calculate_ADL(df): money_flow_multiplier = ((df['close'] - df['low']) - (df['high'] - df['close'])) / (df['high'] - df['low']) money_flow_volume = money_flow_multiplier * df['volume'] adl = money_flow_volume.cumsum() return adl # 使用示例 # adl_values = calculate_ADL(df)
Aroon
计算
Aroon 指标以百分比形式显示,并在 0 到 100 之间波动。Aroon-Up 基于价格高点,而 Aroon-Down 基于价格低点。这两个指标并排绘制,便于比较。SharpCharts 中的默认参数设置为 25,下面的示例基于 25 天。
Aroon-Up = ((25 - Days Since 25-day High)/25) x 100 Aroon-Down = ((25 - Days Since 25-day Low)/25) x 100
随着新高点或新低点之间经过的时间增加,Aroon 会下降。50 是分界点。因为 12.5 天标记着确切的中点,在日线图上不可能出现恰好为 50 的读数。在其他时间框架上是可能的。在日线图上,Aroon 要么低于 50(48),要么高于 50(52)。高于 50 的读数意味着在过去的 12 天或更短时间内记录了新高点或新低点。这是最近一半的回顾期。低于 50 的读数意味着在过去的 13 天或更长时间内记录了新高点或新低点((25-13)/25 x 100 = 48)。这是回顾期的后一半。下表显示了 25 天 Aroon-Up 和 25 天 Aroon-Down 的数值范围。
代码
# 计算 Aroon 指标 def calculate_aroon(df): df['high_rolling_max'] = df['high'].rolling(window=25).max() df['low_rolling_min'] = df['low'].rolling(window=25).min() df['days_since_high'] = 25 - df['high'].shift(1).rolling(window=25).apply(lambda x: x.argmax()) df['days_since_low'] = 25 - df['low'].shift(1).rolling(window=25).apply(lambda x: x.argmin()) df['Aroon-Up'] = ((25 - df['days_since_high']) / 25) * 100 df['Aroon-Down'] = ((25 - df['days_since_low']) / 25) * 100 df.drop(['high_rolling_max', 'low_rolling_min', 'days_since_high', 'days_since_low'], axis=1, inplace=True) return df
Aroon 振荡器
计算
Aroon-Up 和 Aroon-Down 衡量价格记录 x 天高点或低点以来的周期数。Aroon Up 基于时间和价格高点。Aroon Down 基于时间和价格低点。例如,25 天 Aroon-Up 衡量自 25 天高点以来的天数,而 25 天 Aroon-Down 衡量自 25 天低点以来的天数。这些指标以百分比形式显示,并在 0 和 100 之间波动。Aroon 振荡器简单地是 Aroon-Up 减去 Aroon-Down。SharpCharts 中的默认参数为 25,下面的示例基于 25 天 Aroon 振荡器。
Aroon Up = 100 x (25 - Days Since 25-day High)/25 Aroon Down = 100 x (25 - Days Since 25-day Low)/25 Aroon Oscillator = Aroon-Up - Aroon-Down
简单地计算数字会揭示一些有趣的配对。要达到或超过某个阈值,需要 Aroon-Up 或 Aroon-Down 达到最低水平。例如,当 Aroon-Up 等于 100 且 Aroon-Down 等于 0 时,振荡器等于+100。类似地,当 Aroon-Up 为 0 且 Aroon-Down 为 100 时,Aroon 振荡器等于-100。要使振荡器达到+100,需要一些强劲的上涨价格运动。同样,要使振荡器达到-100,需要一些强劲的下跌价格运动。
等于+40 的 Aroon 振荡器要求 Aroon-Up 至少为 40,这意味着 Aroon-Down 将为 0。正 40 可能来自一系列 Aroon-Up 和 Aroon-Down 的组合(40-0, 44-4, 48-8, 60-20, 72-32, 80-40 或 100-40)。颠倒这些数字以查看可能产生负 40 的组合。
一般来说,相对较高的正数要求 Aroon-Up 相对较高,而相对较低的负数要求 Aroon-Down 相对较高。下表显示了一系列 Aroon-Up 和 Aroon-Down 配对以形成 Aroon 振荡器。
代码
名称:Aroon Oscillator 描述:计算 Aroon 振荡器 --- 代码: def calculate_aroon_oscillator(df): period = 25 df['Days Since High'] = df['high'].rolling(window=period).apply(lambda x: period - x.idxmax(), raw=True) df['Days Since Low'] = df['low'].rolling(window=period).apply(lambda x: period - x.idxmin(), raw=True) df['Aroon Up'] = 100 * (period - df['Days Since High']) / period df['Aroon Down'] = 100 * (period - df['Days Since Low']) / period df['Aroon Oscillator'] = df['Aroon Up'] - df['Aroon Down'] df.drop(['Days Since High', 'Days Since Low'], axis=1, inplace=True) return df
平均趋向指数(ADX)
计算
方向运动是通过比较两个连续低点之间的差异与它们各自高点之间的差异来计算的。
当前高点减去先前高点大于先前低点减去当前低点时,方向运动是正数(加号)。这种所谓的正向方向运动(+DM)等于当前高点减去先前高点,前提是它是正数。负值将简单地输入为零。
当前低点减去先前低点大于当前高点减去先前高点时,方向运动是负数(减号)。这种所谓的负向方向运动(-DM)等于先前低点减去当前低点,前提是它是正数。负值将简单地输入为零。
上图显示了四个方向运动计算示例。第一对显示了强烈的正向方向运动(+DM)的高点之间的巨大正差异。第二对显示了一个外部日,负向方向运动(-DM)占优势。第三对显示了低点之间的巨大差异,形成强烈的负向方向运动(-DM)。最后一对显示了一个内部日,相当于没有方向运动(零)。正向方向运动(+DM)和负向方向运动(-DM)都是负数并恢复为零,因此它们互相抵消。所有内部日都将有零方向运动。
代码
def directional_movement(df): df['high_shifted'] = df['high'].shift(1) df['low_shifted'] = df['low'].shift(1) df['up_move'] = df['high'] - df['high_shifted'] df['down_move'] = df['low_shifted'] - df['low'] df['plus_dm'] = df['up_move'].apply(lambda x: x if x > 0 else 0) df['minus_dm'] = df['down_move'].apply(lambda x: x if x > 0 else 0) df.drop(['high_shifted', 'low_shifted', 'up_move', 'down_move'], axis=1, inplace=True) return df # 使用示例 df = directional_movement(df)
真实波动幅度(ATR)
计算
通常,平均真实范围(ATR)基于 14 个周期,并可以根据分钟、日、周或月的基础数据进行计算。在这个示例中,ATR 将基于日数据。因为必须有一个起点,第一个 TR 值简单地是最高价减去最低价,而前 14 天的 ATR 是过去 14 天的每日 TR 值的平均值。之后,Wilder 试图通过纳入前一期的 ATR 值来平滑数据。
Current ATR = [(Prior ATR x 13) + Current TR] / 14 - Multiply the previous 14-day ATR by 13. - Add the most recent day's TR value. - Divide the total by 14
点击这里查看一个 Excel 电子表格"),展示了 QQQ ATR 计算的开始。
在电子表格示例中,第一个真实范围值(.91)等于最高价减去最低价(黄色单元格)。第一个 14 天 ATR 值(.56)是通过计算前 14 个真实范围值的平均值(蓝色单元格)得出的。随后的 ATR 值使用上述公式进行平滑处理。电子表格中的数值对应下图中的黄色区域。请注意,随着 QQQ 在五月份暴跌并出现许多长蜡烛图,ATR 值激增。
对于那些在家尝试的人,有一些注意事项。首先,就像指数移动平均线(EMAs)一样,ATR 值取决于你从多远的历史数据开始计算。第一个真实范围值简单地是当前最高价减去当前最低价,而第一个 ATR 是前 14 个真实范围值的平均值。真正的 ATR 公式直到第 15 天才开始生效。即便如此,这两个计算的残留效应会略微影响随后的 ATR 值。对于一小部分数据的电子表格数值可能与价格图表上看到的不完全匹配。小数四舍五入也可能会略微影响 ATR 值。在我们的图表中,我们至少计算了 250 个周期(通常更多),以确保我们的 ATR 值更加准确。
代码
名称:ATR 描述:计算平均真实范围(ATR)指标 import pandas as pd def ATR(df): df['TR'] = df['high'] - df['low'] df['TR_14'] = df['TR'].rolling(window=14).mean() df['ATR'] = (df['ATR_14'].shift(1) * 13 + df['TR']) / 14 df.drop(['TR', 'TR_14'], axis=1, inplace=True) return df
布林带宽度
SharpCharts 计算
( (Upper Band - Lower Band) / Middle Band) * 100
布林带由一个中间带和两个外部带组成。中间带通常设置为 20 个周期的简单移动平均。外部带通常设置为中间带上下 2 个标准差。设置可以根据特定证券或交易风格的特征进行调整。
在计算带宽时,第一步是从上带的值中减去下带的值。这显示了绝对差异。然后将此差异除以中间带,这将使值标准化。然后可以在不同时间段内或与其他证券的带宽值进行比较。
上图显示了纳斯达克 100 ETF(QQQ)的布林带、带宽度和标准差。请注意带宽度如何跟踪标准差(波动性)。两者一起上升和下降。下图显示了一个带有计算示例的电子表格。
代码
# 计算布林带带宽 def calculate_bollinger_band_width(df): df['middle_band'] = df['close'].rolling(window=20).mean() df['upper_band'] = df['middle_band'] + 2 * df['close'].rolling(window=20).std() df['lower_band'] = df['middle_band'] - 2 * df['close'].rolling(window=20).std() df['band_width'] = ((df['upper_band'] - df['lower_band']) / df['middle_band']) * 100 return df
%B 指标
计算
%B = (Price - Lower Band)/(Upper Band - Lower Band)
%B 的默认设置基于布林带(20,2)的默认设置。这些带子设置在 20 日简单移动平均线的上下 2 个标准差处,这也是中轨。证券价格是收盘价或最后交易价。
代码
# 计算%B指标 def calculate_percent_b(df): df['middle_band'] = df['close'].rolling(window=20).mean() df['upper_band'] = df['middle_band'] + 2 * df['close'].rolling(window=20).std() df['lower_band'] = df['middle_band'] - 2 * df['close'].rolling(window=20).std() df['percent_b'] = (df['close'] - df['lower_band']) / (df['upper_band'] - df['lower_band']) return df
查金资金流量
计算
计算查金资金流量(CMF)有四个步骤。下面的示例基于 20 个时期。首先,计算每个时期的资金流量乘数。其次,将此值乘以该时期的交易量,以找到资金流量量。第三,对 20 个时期的资金流量量进行求和,并除以 20 个时期的交易量总和。
1\. Money Flow Multiplier = [(Close - Low) - (High - Close)] /(High - Low) 2\. Money Flow Volume = Money Flow Multiplier x Volume for the Period 3\. 20-period CMF = 20-period Sum of Money Flow Volume / 20 period Sum of Volume
每个时期的资金流量量取决于资金流量乘数。当收盘价位于该时期最高-最低范围的上半部时,该乘数为正;当收盘价位于下半部时,该乘数为负。当收盘价等于最高价时,乘数为 1;当收盘价等于最低价时,乘数为-1。通过这种方式,乘数调整了最终进入资金流量量的量。除非资金流量乘数处于极端值(+1 或-1),否则实际上会减少交易量。
上表显示了使用 Research in Motion(RIMM)的每日数据的一些示例。请注意,当股票在 1 月 5 日收盘时,乘数接近 +1。当股票在 1 月 18 日收盘时,乘数下降到 -0.97。当股票在 12 月 29 日收盘时,乘数接近零(-0.07),股票收于其高低范围的中点附近。点击这里") 查看 Excel 电子表格中 Chaikin Money Flow 的计算示例。
代码
名称:Chaikin Money Flow (CMF) 描述:计算查金资金流量(CMF) def chaikin_money_flow(df): money_flow_multiplier = ((df['close'] - df['low']) - (df['high'] - df['close'])) / (df['high'] - df['low']) money_flow_volume = money_flow_multiplier * df['volume'] df['money_flow_volume'] = money_flow_volume sum_money_flow_volume = df['money_flow_volume'].rolling(window=20).sum() sum_volume = df['volume'].rolling(window=20).sum() df['chaikin_money_flow'] = sum_money_flow_volume / sum_volume return df
Chaikin Oscillator
计算
计算累积分布线(ADL)是计算 Chaikin Oscillator 的第一步。本文将介绍累积分布线的基本要素。查看我们的 ChartSchool 文章获取详细信息。计算累积分布线(ADL)有三个步骤。首先,计算资金流量乘数。其次,将此值乘以成交量以找到资金流量。第三,创建资金流量的累积总和以形成累积分布线(ADL)。第四,取两个移动平均线之间的差异来计算 Chaikin Oscillator。
1\. Money Flow Multiplier = [(Close - Low) - (High - Close)] /(High - Low) 2\. Money Flow Volume = Money Flow Multiplier x Volume for the Period 3\. ADL = Previous ADL + Current Period's Money Flow Volume 4\. Chaikin Oscillator = (3-day EMA of ADL) - (10-day EMA of ADL)
当资金流量乘数为正时,累积分布线上升;当为负时下降。当收盘价位于周期高低范围的上半部时,该乘数为正;当收盘价位于下半部时,该乘数为负。作为 MACD 类型的振荡器,当较快的 3 日 EMA 移动超过较慢的 10 日 EMA 时,Chaikin Oscillator 变为正。相反,当 3 日 EMA 移动低于 10 日 EMA 时,指标变为负。
上图显示了积累分布线(灰色)与 3 日 EMA(蓝色)和 10 日 EMA(红色)。通用电气(GE)的价格不可见,因此我们可以专注于积累分布线和柴金波动指标之间的关系。请注意,当 3 日 EMA 低于 10 日 EMA 时,柴金波动指标进入负值区域。相反,当 3 日 EMA 穿过 10 日 EMA 时,振荡器变为正值。
代码
名称:累积分布线(ADL)和柴金波动指标描述 描述:根据给定的开盘价、收盘价、最高价、最低价和成交量计算累积分布线(ADL)和柴金波动指标 代码: import pandas as pd def calculate_ADL(df): money_flow_multiplier = ((df['close'] - df['low']) - (df['high'] - df['close'])) / (df['high'] - df['low']) money_flow_volume = money_flow_multiplier * df['volume'] adl = money_flow_volume.cumsum() return adl def calculate_Chaikin_Oscillator(df): adl = calculate_ADL(df) ema3 = adl.ewm(span=3, adjust=False).mean() ema10 = adl.ewm(span=10, adjust=False).mean() chaikin_oscillator = ema3 - ema10 return chaikin_oscillator # 使用示例 # df 包含了开盘价、收盘价、最高价、最低价和成交量 # df = pd.DataFrame({'open': [10, 11, 12], 'close': [11, 12, 13], 'high': [13, 14, 15], 'low': [9, 10, 11], 'volume': [1000, 1500, 2000]}) # adl = calculate_ADL(df) # chaikin_oscillator = calculate_Chaikin_Oscillator(df)
# 查德趋势仪表盘(CTM) ## 计算 查德趋势仪表盘的计算基于以下技术指标: + 高、低和收盘价相对于四个不同时间框架(20 天、50 天、75 天和 100 天)的布林带的位置 + 过去 100 天相对于标准偏差的价格变化 + 14 天的 RSI 值 + 任何短期(2 天)价格通道突破的存在 最终得分转换为 0-100 的尺度以便比较。 # 代码 ```python # 计算查德趋势仪表盘得分 def chad_trend(df): # 计算布林带 df['20_day_ma'] = df['close'].rolling(window=20).mean() df['20_day_std'] = df['close'].rolling(window=20).std() df['upper_band_20'] = df['20_day_ma'] + 2 * df['20_day_std'] df['lower_band_20'] = df['20_day_ma'] - 2 * df['20_day_std'] df['50_day_ma'] = df['close'].rolling(window=50).mean() df['50_day_std'] = df['close'].rolling(window=50).std() df['upper_band_50'] = df['50_day_ma'] + 2 * df['50_day_std'] df['lower_band_50'] = df['50_day_ma'] - 2 * df['50_day_std'] df['75_day_ma'] = df['close'].rolling(window=75).mean() df['75_day_std'] = df['close'].rolling(window=75).std() df['upper_band_75'] = df['75_day_ma'] + 2 * df['75_day_std'] df['lower_band_75'] = df['75_day_ma'] - 2 * df['75_day_std'] df['100_day_ma'] = df['close'].rolling(window=100).mean() df['100_day_std'] = df['close'].rolling(window=100).std() df['upper_band_100'] = df['100_day_ma'] + 2 * df['100_day_std'] df['lower_band_100'] = df['100_day_ma'] - 2 * df['100_day_std'] # 计算价格变化相对于标准偏差 df['price_change'] = df['close'].pct_change() df['std_price_change'] = df['price_change'].rolling(window=100).std() # 计算 RSI delta = df['close'].diff() gain = (delta.where(delta > 0, 0)).rolling(window=14).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean() rs = gain / loss df['rsi'] = 100 - (100 / (1 + rs)) # 计算价格通道突破 df['high_breakout'] = df['high'] > df['upper_band_20'] df['low_breakout'] = df['low'] < df['lower_band_20'] # 计算得分 df['score'] = ((df['close'] - df['close'].shift(100)) / df['std_price_change'] + df['rsi'] + df['high_breakout'] + df['low_breakout']) / 4 * 100 return df['score'] # 使用示例 chad_trend_score = chad_trend(df)
商品通道指数(CCI)
计算
下面的示例基于 20 周期商品通道指数(CCI)的计算。CCI 周期数也用于简单移动平均和平均偏差的计算。
CCI = (Typical Price - 20-period SMA of TP) / (.015 x Mean Deviation) Typical Price (TP) = (High + Low + Close)/3 Constant = .015 There are four steps to calculating the Mean Deviation: First, subtract the most recent 20-period average of the typical price from each period's typical price. Second, take the absolute values of these numbers. Third, sum the absolute values. Fourth, divide by the total number of periods (20).
Lambert 将常数设定为 0.015,以确保大约 70%到 80%的 CCI 值落在-100 和+100 之间。这个百分比还取决于回顾期。较短的 CCI(10 个周期)将更加波动,在+100 和-100 之间的值的百分比较小。相反,较长的 CCI(40 个周期)将在+100 和-100 之间的值有更高的百分比。
点击这里查看在 Excel 电子表格中计算 CCI 的链接")。
代码
名称:CCI指标 描述:根据给定的数据计算商品通道指数(CCI) import pandas as pd def calculate_CCI(df): df['TP'] = (df['High'] + df['Low'] + df['Close']) / 3 df['SMA_TP'] = df['TP'].rolling(window=20).mean() df['Mean_Deviation'] = df['TP'] - df['SMA_TP'] df['Mean_Deviation'] = df['Mean_Deviation'].abs().rolling(window=20).sum() / 20 df['CCI'] = (df['TP'] - df['SMA_TP']) / (0.015 * df['Mean_Deviation']) return df['CCI'] # 使用示例 # df['CCI'] = calculate_CCI(df)
# 科波克曲线 ## SharpCharts 计算 ```py Coppock Curve = 10-period WMA of 14-period RoC + 11-perod RoC WMA = Weighted moving average RoC = Rate-of-Change
变动率指标是一个动量振荡器,它在零线上下振荡。科波克使用了 11 和 14 个周期,因为据一个圣公会牧师说,这是悼念所爱之人丧失的平均哀悼期。科波克推测,股市损失的恢复期将类似于这个时间段。
然后,变动率指标通过加权移动平均进行平滑处理。顾名思义,加权移动平均对最新数据赋予更高的权重,对较旧的数据赋予较低的权重。例如,3 期加权移动平均会将第一个数据点乘以 1,第二个数据点乘以 2,第三个数据点乘以 3。然后,这三个数字的总和除以 6,即权重之和(1 + 2 + 3),以创建加权平均值。下表显示了从 Excel 电子表格中的计算。
点击此处下载此电子表格示例。")
代码
# 名称:Coppock Curve # 描述:Calculate Coppock Curve using 10-period WMA of 14-period RoC + 11-period RoC def coppock_curve(df): df['roc_14'] = (df['close'] / df['close'].shift(14) - 1) * 100 df['roc_11'] = (df['close'] / df['close'].shift(11) - 1) * 100 df['wma_10'] = df['roc_14'].rolling(window=10).apply(lambda x: np.sum(np.arange(1, 11) * x) / 55, raw=True) df['coppock_curve'] = df['wma_10'] + df['roc_11'] return df
相关系数
计算
相关系数的计算相当复杂,所以可以跳过这一部分。我们只会简单看一些基本内容,以了解其中的方法。这个指标正是经典统计学的核心。第一步是选择两个证券。在这个例子中,我们将使用英特尔(INTC)和纳斯达克 100ETF(QQQ)。换句话说,我们想要看到英特尔和 QQQ 之间的相关程度。下面的 Excel 表格展示了基础工作。
- INTC 列显示了英特尔在 20 天内的价格,底部显示了平均值。
- QQQ 列显示了 QQQ 的情况。
- 接下来的两列显示了每个期间的价格平方,底部显示了平均值。
- 最后几列显示了每个期间的 INTC 乘以 QQQ,底部显示了平均值。
利用底部行,我们现在可以计算方差、协方差和相关系数。Excel 公式显示在长公式旁边。结果显示,在 6 月 22 日至 7 月 20 日的 20 天期间,英特尔与纳斯达克 100ETF 表现出强烈的正相关性(+.95)。
这里有一个展示相关系数的 Excel 电子表格")。由于四舍五入问题,一些数字可能略有不同。
基本技术指标 Python 实现(3)https://developer.aliyun.com/article/1484233