You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python(Pandas)MST指标与TradingView PineScript结果不一致的修复方法

解决TradingView MST指标与Python实现数值不一致的问题

我在TradingView上使用自定义MST指标,但基于Pandas的Python实现结果和TradingView上的数值不匹配,需要修改代码让两者数值完全一致。

原TradingView PineScript代码

//Calculate MST
RSI = ta.rsi(close, 14)
rsidelta    = ta.mom(RSI, 9)
rsisma      = ta.sma(ta.rsi(close, 3), 3)
mst         = rsidelta+rsisma
plot(mst, title="MST", color=#BB2BFA, linewidth = 2)

原Python代码问题分析

原Python实现存在几个关键差异导致数值不一致:

  • rsidelta计算范围错误:原代码只计算了最后一个RSI值与倒数第9个值的差,但PineScript是对每一根K线计算当前RSI与9周期前RSI的差值。
  • 序列对齐问题:原代码中rsi_delta是单个值,与rsi_sma(序列)相加会导致广播错误,无法得到逐K线的MST值。
  • 潜在RSI逻辑差异:TradingView的RSI使用Wilder简单移动平滑,需确保Python实现与之对齐。

修改后的Python代码

1. 修正RSI函数(匹配TradingView逻辑)

import pandas as pd
import numpy as np
import talib as ta

def rsi(df: pd.DataFrame, period: int = 14, source: str = 'close') -> pd.Series:
    # 使用talib的RSI,默认采用Wilder平滑,与TradingView完全一致
    return ta.RSI(df[source], timeperiod=period)

若无法使用talib,可手动实现Wilder平滑的RSI:

def rsi_wilder(df: pd.DataFrame, period: int =14, source: str='close') -> pd.Series:
    delta = df[source].diff(1)
    gain = delta.where(delta > 0, 0)
    loss = -delta.where(delta < 0, 0)

    # 初始周期用简单平均
    avg_gain = gain.rolling(window=period, min_periods=period).mean()
    avg_loss = loss.rolling(window=period, min_periods=period).mean()

    # Wilder递推平滑
    for i in range(period, len(df)):
        avg_gain.iloc[i] = (avg_gain.iloc[i-1] * (period - 1) + gain.iloc[i]) / period
        avg_loss.iloc[i] = (avg_loss.iloc[i-1] * (period - 1) + loss.iloc[i]) / period

    rs = avg_gain / avg_loss
    return 100 - (100 / (1 + rs))

2. 修正scanner.py中的MST计算逻辑

# Scan 7
if '7' in self.scans:
    scan = self.scans['7']
    # 获取14周期RSI序列(返回Series方便后续计算)
    rsi_14 = indicators.rsi(df=df, period=scan['rsi_period'], source=scan['rsi_source'])
    # 逐K线计算rsidelta:当前RSI - 9周期前RSI
    rsi_delta = rsi_14 - rsi_14.shift(scan['rsi_delta_period'])
    
    # 计算rsisma:先取3周期RSI,再做3周期SMA
    rsi_3 = indicators.rsi(df=df, period=scan['rsi_sma_period'], source=scan['rsi_source'])
    rsi_sma = rsi_3.rolling(window=scan['rsi_sma_period']).mean()
    
    # 逐行匹配计算MST
    mst = rsi_delta + rsi_sma

关键修改点说明

  • rsidelta对齐:用shift(9)实现PineScript中ta.mom(RSI,9)的逐K线动量计算逻辑。
  • 序列一致性:所有计算基于pd.Series进行,确保每根K线的数值对应相加,避免广播错误。
  • RSI平滑匹配:强制使用Wilder平滑方式,与TradingView的ta.rsi逻辑完全一致。

内容的提问来源于stack exchange,提问作者mgoblue33

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 16:01:28