Overlap:PWMA(帕斯卡加权移动平均线)技术指标详解
一、PWMA的定义
PWMA(Pascal’s Weighted Moving Average,帕斯卡加权移动平均线) 是由Kevin Johnson开发的一种创新移动平均线。它独特之处在于:使用帕斯卡三角形(Pascal’s Triangle) 生成的组合数作为权重分配基础。
核心设计理念
PWMA与对称三角形加权移动平均类似,但权重分布更符合帕斯卡三角形的数学规律——中间高、两端低的对称分布。这种权重结构使得PWMA在平滑价格数据时,更强调窗口中心附近的价格,同时赋予两端(最新数据和最旧数据)相对较低的权重。
PWMA与传统加权移动平均的对比
| 权重来源 | 帕斯卡三角形(组合数) | 线性递增权重 | 等权重 |
| 权重分布 | 中间高、两端低(对称) | 最新数据权重最高 | 全部相等 |
| 曲线平滑度 | 高,类似高斯滤波 | 中等 | 低 |
| 计算复杂度 | 较高(需生成帕斯卡三角) | 低 | 最低 |
重要提醒:部分MetaTrader平台的“PWMA”指标名为“Power Weighted Moving Average”,计算公式为
S
U
M
(
价格
(
i
)
×
i
P
o
w
e
r
)
/
S
U
M
(
i
P
o
w
e
r
)
\\mathrm{SUM}(价格(i) × i^{\\mathrm{Power}}) / \\mathrm{SUM}(i^\\mathrm{Power})
SUM(价格(i)×iPower)/SUM(iPower),与帕斯卡加权均线是完全不同的指标。本文以pandas_ta库的实现为准,介绍基于帕斯卡三角形的PWMA。
二、PWMA的计算方法
1. 帕斯卡三角形简介
帕斯卡三角形是一个由组合数构成的三角形数组,第n行的第k个元素为组合数
(
n
k
)
=
n
!
k
!
(
n
−
k
)
!
\\binom{n}{k} = \\frac{n!}{k!(n-k)!}
(kn)=k!(n−k)!n!。例如,前几行为:
Row 0: 1
Row 1: 1 1
Row 2: 1 2 1
Row 3: 1 3 3 1
Row 4: 1 4 6 4 1
PWMA使用帕斯卡三角形的某一行作为权重序列。
2. 核心计算公式
PWMA的计算公式为加权移动平均的标准形式:
P
W
M
A
t
=
∑
i
=
0
n
−
1
w
i
×
P
t
−
i
∑
i
=
0
n
−
1
w
i
\\mathrm{PWMA}_t = \\frac{\\sum_{i=0}^{n-1} w_i \\times P_{t-i}}{\\sum_{i=0}^{n-1} w_i}
PWMAt=∑i=0n−1wi∑i=0n−1wi×Pt−i
其中:
-
n
n
n:计算周期(length 参数,默认 10) -
P
t
−
i
P_{t-i}
Pt−i:第t
−
i
t-i
t−i 期的价格(P
t
P_t
Pt 为最新价格) -
w
i
w_i
wi:基于帕斯卡三角形生成的权重序列(默认按时间顺序排列,最新数据权重更高)
权重序列生成:
- asc=True(默认):权重按升序排列,最新数据获得最高权重
- asc=False:权重按降序排列,权重分布反转
3. 计算示例(length=4)
取帕斯卡三角形第3行(length-1),权重序列为[1, 3, 3, 1]:
| 最新(t) | 108 | 1 | 108 |
| t-1 | 105 | 3 | 315 |
| t-2 | 102 | 3 | 306 |
| t-3 | 100 | 1 | 100 |
加权和 = 108 + 315 + 306 + 100 = 829 权重和 = 1 + 3 + 3 + 1 = 8 PWMA = 829 / 8 = 103.625
4. 参数说明
| close | pd.Series | 必需 | 收盘价序列 |
| length | int | 10 | 计算周期,控制窗口大小 |
| asc | bool | True | True表示最新数据权重更高;False表示反转权重分布 |
| offset | int | 0 | 结果偏移周期数 |
三、PWMA的使用方法
1. 趋势方向判断
PWMA线的方向是判断市场趋势的最直观依据:
| PWMA向上运行 | 上升趋势,买方力量主导 | 以做多为主 |
| PWMA向下运行 | 下降趋势,卖方力量主导 | 以做空为主 |
| PWMA走平 | 趋势可能减弱或进入盘整 | 观望 |
2. 价格穿越信号
价格与PWMA的穿越关系是最简单的入场/出场信号:
| 买入信号 | 价格从下方上穿PWMA | 考虑建立多头仓位 |
| 卖出信号 | 价格从上方下穿PWMA | 考虑平仓或建立空头 |
3. asc参数选择
asc参数控制权重的分配方向,直接影响PWMA的灵敏度:
| True(默认) | 最新数据权重最高 | 短线交易,强调近期行情 |
| False | 权重分布反转 | 更平滑的历史趋势判断 |
4. 注意事项与局限性
使用PWMA前需了解以下要点:
| 计算结果易受极端值影响 | 权重较高的数据点对结果影响大,价格尖峰可能导致均线异常波动 |
| 计算复杂度较高 | 需生成帕斯卡三角形并滚动计算加权平均,计算量大于SMA |
| 不能单独使用 | 建议与其他技术指标配合使用,构建完整交易系统 |
四、使用pandas_ta计算PWMA(附示例代码)
1. 函数完整参数
pandas_ta.overlap.pwma(close, length=None, asc=None, offset=None, **kwargs)
参数详解:
| close | pd.Series | 必需 | 收盘价序列 |
| length | int | 10 | 计算周期 |
| asc | bool | True | 权重是否按升序分配 |
| offset | int | 0 | 结果偏移周期数 |
返回值:pd.Series——PWMA值序列。
2. 示例代码
import pandas as pd
import pandas_ta as ta
import numpy as np
import matplotlib.pyplot as plt
# ========== 第一步:准备数据 ==========
np.random.seed(42)
dates = pd.date_range(start='2023-01-01', end='2024-12-31', freq='D')
n = len(dates)
# 生成带趋势和周期波动的价格序列
trend = np.linspace(0, 45, n)
cycle = np.sin(np.linspace(0, 6 * np.pi, n)) * 15
noise = np.random.randn(n) * 3
price_series = 100 + trend + cycle + noise
# 添加趋势变化区间
price_series = price_series.astype(float)
for i in range(300, 450):
price_series[i] = price_series[300] + (i–300) * 0.2 # 强势上涨段
for i in range(450, 600):
price_series[i] = price_series[450] – (i–450) * 0.15 # 强势下跌段
df = pd.DataFrame(index=dates[:n])
df['close'] = price_series[:n]
df['high'] = df['close'] + np.abs(np.random.randn(n)) * 2 + 1
df['low'] = df['close'] – np.abs(np.random.randn(n)) * 2 – 1
df['volume'] = np.random.randint(1000000, 25000000, n)
print("=" * 60)
print("数据预览:")
print(df.head())
print("\\n" + "=" * 60 + "\\n")
# ========== 第二步:计算PWMA(基础用法) ==========
# 使用默认参数 length=10, asc=True
df['PWMA'] = ta.pwma(df['close'])
print("PWMA计算结果(最近10行):")
print(df[['close', 'PWMA']].tail(10))
print("\\n" + "=" * 60 + "\\n")
# ========== 第三步:asc参数对比 ==========
# asc=True(默认,最新数据权重更高)
df['PWMA_asc_true'] = ta.pwma(df['close'], length=10, asc=True)
# asc=False(权重反转,更平滑)
df['PWMA_asc_false'] = ta.pwma(df['close'], length=10, asc=False)
print("asc参数对比(最近5行):")
print(df[['close', 'PWMA_asc_true', 'PWMA_asc_false']].tail())
print("\\n" + "=" * 60 + "\\n")
# ========== 第四步:不同周期PWMA对比 ==========
df['PWMA_5'] = ta.pwma(df['close'], length=5)
df['PWMA_10'] = ta.pwma(df['close'], length=10)
df['PWMA_20'] = ta.pwma(df['close'], length=20)
print("不同周期PWMA对比(最近5行):")
print(df[['close', 'PWMA_5', 'PWMA_10', 'PWMA_20']].tail())
print("\\n" + "=" * 60 + "\\n")
# ========== 第五步:计算对比均线 ==========
df['SMA_10'] = ta.sma(df['close'], length=10)
df['WMA_10'] = ta.wma(df['close'], length=10)
print("PWMA vs SMA vs WMA 对比(最近10行):")
print(df[['close', 'PWMA_10', 'SMA_10', 'WMA_10']].tail(10))
print("\\n" + "=" * 60 + "\\n")
# ========== 第六步:生成价格穿越信号 ==========
df['price_above_pwma'] = df['close'] > df['PWMA_10']
df['cross_above'] = (df['price_above_pwma'] == True) & (df['price_above_pwma'].shift(1) == False)
df['cross_below'] = (df['price_above_pwma'] == False) & (df['price_above_pwma'].shift(1) == True)
df['signal'] = ''
df.loc[df['cross_above'], 'signal'] = '买入(价格上穿PWMA)'
df.loc[df['cross_below'], 'signal'] = '卖出(价格下穿PWMA)'
print("价格穿越信号统计:")
print(f"买入信号数量:{df['cross_above'].sum()}")
print(f"卖出信号数量:{df['cross_below'].sum()}")
print("\\n" + "=" * 60 + "\\n")
# ========== 第七步:策略回测 ==========
# 策略:价格 > PWMA 时持仓多头
df['position'] = (df['close'] > df['PWMA_10']).astype(int)
df['returns'] = df['close'].pct_change()
df['strategy_returns'] = df['position'].shift(1) * df['returns']
total_return_buyhold = (1 + df['returns']).prod() – 1
total_return_strategy = (1 + df['strategy_returns']).prod() – 1
print("=" * 60)
print("策略绩效统计(PWMA穿越策略回测):")
print(f"买入持有策略总收益率:{total_return_buyhold:.2%}")
print(f"PWMA穿越策略总收益率:{total_return_strategy:.2%}")
print("\\n注意:此为简化回测,仅供参考")
print("=" * 60 + "\\n")
# ========== 第八步:可视化 ==========
plt.figure(figsize=(14, 12))
# 子图1:价格走势与均线对比
plt.subplot(2, 1, 1)
plt.plot(df.index[–200:], df['close'][–200:], label='Close Price',
linewidth=1.5, color='black')
plt.plot(df.index[–200:], df['PWMA_10'][–200:], label='PWMA (10)',
linewidth=1.5, color='blue')
plt.plot(df.index[–200:], df['SMA_10'][–200:], label='SMA (10)',
linewidth=1, color='orange', alpha=0.7, linestyle='–')
plt.plot(df.index[–200:], df['WMA_10'][–200:], label='WMA (10)',
linewidth=1, color='green', alpha=0.7, linestyle=':')
plt.title('PWMA vs SMA vs WMA 对比 (Last 200 days)', fontsize=14)
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图2:asc参数对比
plt.subplot(2, 1, 2)
plt.plot(df.index[–200:], df['close'][–200:], label='Close Price',
linewidth=1, alpha=0.5, color='black')
plt.plot(df.index[–200:], df['PWMA_asc_true'][–200:], label='PWMA asc=True(灵敏)',
linewidth=1, alpha=0.7)
plt.plot(df.index[–200:], df['PWMA_asc_false'][–200:], label='PWMA asc=False(平滑)',
linewidth=1.5, color='blue')
plt.title('PWMA:asc参数对比', fontsize=14)
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
五、总结
PWMA(帕斯卡加权移动平均线)是一种基于帕斯卡三角形组合数权重的高级移动平均线,其核心价值与定位如下:
| 核心创新 | 使用帕斯卡三角形组合数作为权重,实现对称加权平滑 |
| 核心公式 | PWMA = Σ(w_i × P_{t-i}) / Σ(w_i),权重来源于帕斯卡三角 |
| 核心信号 | 价格穿越、趋势方向判断、asc参数调节灵敏度 |
| 默认参数 | length=10, asc=True |
| 最佳应用场景 | 趋势跟踪、平滑价格波动、多均线组合策略 |
| 主要局限 | 计算复杂度较高、受极端值影响、不能单独使用 |
实战使用建议:

