Overlap:SINWMA(正弦加权移动平均线)技术指标详解

Overlap:SINWMA(正弦加权移动平均线)技术指标详解

一、SINWMA的定义

SINWMA(Sine Weighted Moving Average,正弦加权移动平均线) 是一种利用正弦波周期特性来分配权重的移动平均线。它的核心理念是:市场价格波动类似于某种未知的波动或周期,正弦波可以有效地模拟这种特性,从而使均线对价格的周期变化更为敏感。

这种加权方式使得SINWMA在平滑价格数据的同时,能够减少滞后并提升对趋势拐点的敏感度,特别适合捕捉有明显周期性的资产行情。

SINWMA与PWMA的对比

SINWMA与PWMA(帕斯卡加权移动平均)都属于非线性的高级移动平均线,但权重逻辑不同:

对比维度 SINWMA(正弦加权) PWMA(帕斯卡加权)
权重来源 正弦波函数(sin 帕斯卡三角形(组合数)
权重分布 中间高、两端低(正弦波半周期) 中间高、两端低(对称)
曲线平滑度 高,带周期规律感知 高,类似高斯滤波
计算复杂度 中等(需计算正弦值) 较高(需生成帕斯卡三角)
理论基础 价格波动遵循周期波 组合数学

二、SINWMA的计算方法

1. 核心权重公式

SINWMA的权重基于正弦波函数生成,其核心思想是周期中心点权重最大,两端权重递减 。标准权重公式为:

wi=sin⁡⁡(π(i+1)N+1) w_i = \sin⁡\left(\frac{\pi(i+1)}{N+1}\right) wi=sin⁡(N+1π(i+1))

其中:

  • iii 是数据点的索引(从0开始,0表示最旧数据)
  • NNN 是移动平均的周期(length参数)
  • π\piπ 是圆周率

权重分布特征:周期中心点权重最大,边缘点权重较低,模拟市场价格的中期影响力。

2. 完整计算公式

SINWMA的计算公式为加权移动平均的标准形式:

SINWMAt=∑i=0N−1wi×Pt−i∑i=0N−1wi \mathrm{SINWMA}t = \frac{\sum{i=0}^{N-1} w_i \times P_{t-i}}{\sum_{i=0}^{N-1} w_i} SINWMAt=∑i=0N−1wi∑i=0N−1wi×Pt−i

等价于:

SINWMA=(价格i×权重i)的加总权重之和 \mathrm{SINWMA} = \frac{(\text{价格}_i \times \text{权重}_i) \text{的加总}}{\text{权重之和}} SINWMA=权重之和(价格i×权重i)的加总

展开形式 (以5周期为例):

Sum=Pt⋅sin⁡(1π6)+Pt−1⋅sin⁡(2π6)+⋯+Pt−4⋅sin⁡(5π6) \mathrm{Sum} = P_t \cdot \sin\left(\frac{1\pi}{6}\right) + P_{t-1} \cdot \sin\left(\frac{2\pi}{6}\right) + \cdots + P_{t-4} \cdot \sin\left(\frac{5\pi}{6}\right) Sum=Pt⋅sin(61π)+Pt−1⋅sin(62π)+⋯+Pt−4⋅sin(65π)

Den=sin⁡(1π6)+sin⁡(2π6)+⋯+sin⁡(5π6) \mathrm{Den} = \sin\left(\frac{1\pi}{6}\right) + \sin\left(\frac{2\pi}{6}\right) + \cdots + \sin\left(\frac{5\pi}{6}\right) Den=sin(61π)+sin(62π)+⋯+sin(65π)

SINWMA=SumDen \mathrm{SINWMA} = \frac{\mathrm{Sum}}{\mathrm{Den}} SINWMA=DenSum

3. 不同周期权重分配

周期N 权重序列(正弦值) 最大权重位置
5 0.5, 0.866, 1.0, 0.866, 0.5 中心(第3位)
10 正弦波前半段10等分点 中心区域
20 正弦波前半段20等分点 中心区域

4. 参数说明

参数 类型 默认值 说明
close pd.Series 必需 收盘价序列
length int 10 计算周期,控制窗口大小
offset int 0 结果偏移周期数

三、SINWMA的使用方法

1. 趋势方向判断

SINWMA线的方向是判断市场趋势的最直观依据:

SINWMA状态 趋势含义 操作倾向
SINWMA向上运行 上升趋势,买方力量主导 以做多为主
SINWMA向下运行 下降趋势,卖方力量主导 以做空为主
SINWMA走平 趋势可能减弱或进入盘整 观望

2. 价格穿越信号

价格与SINWMA的穿越是最简单的入场/出场信号:

信号类型 触发条件 操作建议
买入信号 价格从下方上穿SINWMA 考虑建立多头仓位
卖出信号 价格从上方下穿SINWMA 考虑平仓或建立空头

3. 多指标配合

正弦加权移动平均线结合如MACD、RSI等动量指标使用时,可以作为趋势过滤器,减少交易信号的误判。

4. 注意事项与局限性

使用SINWMA前需了解以下要点

局限性 说明
参数选择影响较大 周期长度需要根据资产特性及历史周期调整
计算复杂度稍高 相较于SMA,需要计算正弦权重
对极端行情适应性有限 在极端跳空行情时,指标可能出现延迟
不能单独使用 建议与其他技术指标配合使用

四、使用pandas_ta计算SINWMA

1. 函数完整参数

python 复制代码
pandas_ta.overlap.sinwma(close, length=None, offset=None, **kwargs)

参数详解

参数 类型 默认值 说明
close pd.Series 必需 收盘价序列
length int 10 计算周期,决定窗口大小
offset int 0 结果偏移周期数

返回值pd.Series------SINWMA值序列。

2. 示例代码

python 复制代码
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")

# ========== 第二步:计算SINWMA ==========
# 使用默认参数 length=10
df['SINWMA'] = ta.sinwma(df['close'])

print("SINWMA计算结果(最近10行):")
print(df[['close', 'SINWMA']].tail(10))
print("\n" + "=" * 60 + "\n")

# ========== 第三步:不同周期SINWMA对比 ==========
df['SINWMA_5'] = ta.sinwma(df['close'], length=5)
df['SINWMA_10'] = ta.sinwma(df['close'], length=10)
df['SINWMA_20'] = ta.sinwma(df['close'], length=20)

print("不同周期SINWMA对比(最近5行):")
print(df[['close', 'SINWMA_5', 'SINWMA_10', 'SINWMA_20']].tail())
print("\n" + "=" * 60 + "\n")

# ========== 第四步:计算对比均线 ==========
df['SMA_10'] = ta.sma(df['close'], length=10)
df['EMA_10'] = ta.ema(df['close'], length=10)
df['WMA_10'] = ta.wma(df['close'], length=10)

print("SINWMA vs SMA vs EMA vs WMA 对比(最近10行):")
print(df[['close', 'SINWMA_10', 'SMA_10', 'EMA_10', 'WMA_10']].tail(10))
print("\n" + "=" * 60 + "\n")

# ========== 第五步:生成价格穿越信号 ==========
df['price_above_sinwma'] = df['close'] > df['SINWMA_10']
df['cross_above'] = (df['price_above_sinwma'] == True) & (df['price_above_sinwma'].shift(1) == False)
df['cross_below'] = (df['price_above_sinwma'] == False) & (df['price_above_sinwma'].shift(1) == True)

df['signal'] = ''
df.loc[df['cross_above'], 'signal'] = '买入(价格上穿SINWMA)'
df.loc[df['cross_below'], 'signal'] = '卖出(价格下穿SINWMA)'

print("价格穿越信号统计:")
print(f"买入信号数量:{df['cross_above'].sum()}")
print(f"卖出信号数量:{df['cross_below'].sum()}")

print("\n最近15个穿越信号:")
signals = df[df['signal'] != ''].tail(15)
if not signals.empty:
    print(signals[['close', 'SINWMA_10', 'signal']])
print("\n" + "=" * 60 + "\n")

# ========== 第六步:策略回测 ==========
# 策略:价格 > SINWMA 时持仓多头
df['position'] = (df['close'] > df['SINWMA_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("策略绩效统计(SINWMA穿越策略回测):")
print(f"买入持有策略总收益率:{total_return_buyhold:.2%}")
print(f"SINWMA穿越策略总收益率:{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['SINWMA_10'][-200:], label='SINWMA (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['EMA_10'][-200:], label='EMA (10)', 
         linewidth=1, color='green', alpha=0.7, linestyle=':')
plt.plot(df.index[-200:], df['WMA_10'][-200:], label='WMA (10)', 
         linewidth=1, color='purple', alpha=0.7, linestyle='-.')

plt.title('SINWMA vs SMA vs EMA vs WMA 对比 (Last 200 days)', fontsize=14)
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)

# 子图2:不同周期SINWMA对比
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['SINWMA_5'][-200:], label='SINWMA (5) - 短线', 
         linewidth=1, alpha=0.7)
plt.plot(df.index[-200:], df['SINWMA_10'][-200:], label='SINWMA (10) - 标准', 
         linewidth=1.5, color='blue')
plt.plot(df.index[-200:], df['SINWMA_20'][-200:], label='SINWMA (20) - 长线', 
         linewidth=1.5, color='green')

# 标记穿越信号
buy_signals = df[df['cross_above']]
sell_signals = df[df['cross_below']]
plt.scatter(buy_signals.index[-25:], buy_signals['close'][-25:], 
            color='green', marker='^', s=60, label='买入信号(价格上穿)', alpha=0.8)
plt.scatter(sell_signals.index[-25:], sell_signals['close'][-25:], 
            color='red', marker='v', s=60, label='卖出信号(价格下穿)', alpha=0.8)

plt.title('SINWMA:不同周期对比与穿越信号', fontsize=14)
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

五、总结

SINWMA(正弦加权移动平均线)是一种利用正弦波周期特性分配权重的移动平均线,其核心价值与定位如下:

维度 特点
核心创新 正弦波权重分布,周期中心权重最大
核心公式 SINWMA = Σ(w_i × P_{t-i}) / Σ(w_i),其中w_i = sin(π(i+1)/(N+1))
默认参数 length=10
核心优势 周期感知能力强,适合捕捉有明显周期性的资产行情
最佳应用场景 趋势跟踪、多均线组合策略
主要局限 参数敏感、计算复杂度稍高、对极端行情适应性有限

实战使用建议

  1. 多周期配合:短周期SINWMA(5-10)捕捉短期方向,长周期SINWMA(20-50)确认主趋势
  2. 与振荡指标配合:结合MACD、RSI等动量指标,SINWMA可作为趋势过滤器,减少信号误判
  3. 适合波动性较强的品种:由于权重设计,SINWMA在高波动市场依旧保持较好的平滑和响应效果