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

如何用Pandas高效实现Pine Script布林带宽百分位的循环逻辑?

布林带宽百分位(BBWP)Pandas实现优化

核心问题

你当前代码用硬编码的shift(-1)、shift(-2)等操作统计过去BBW值,但无法动态适配每行对应的回溯长度(最多252期,不足252期则取已有所有前期数据)。我们需要实现动态窗口,统计当前BBW值在过去min(当前索引,252)期内的百分位排名(即有多少前期BBW值小于等于当前值)。

优化后的代码

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

# 获取BTC数据
btc = yf.Ticker("BTC-USD")
df = btc.history(start="2022-06-08", interval="15m", actions=False)

# 重置索引为数字索引(匹配Pine Script的bar_index逻辑)
df.reset_index(drop=True, inplace=True)

# 计算基础指标
df["BASIS"] = ta.sma(df.Close, length=13)
df["STDEV"] = ta.stdev(df.Close, length=13)
df["BBW"] = (df["BASIS"] + df["STDEV"] - (df["BASIS"] - df["STDEV"])) / df["BASIS"]

# 计算每个行对应的回溯长度
df["BBWLEN"] = np.where(df.index < 252, df.index, 252)

# 动态计算BBWSUM:统计过去BBWLEN期内BBW <= 当前BBW的数量
bbw_values = df["BBW"].values
bbw_sum = np.zeros(len(df), dtype=int)

for i in range(len(df)):
    window_len = df["BBWLEN"].iloc[i]
    if window_len == 0:
        continue  # 索引0时无前期数据,sum为0
    # 取前期window_len个BBW值
    window = bbw_values[i - window_len : i]
    # 统计小于等于当前BBW的数量
    bbw_sum[i] = (window <= bbw_values[i]).sum()

df["BBWSUM"] = bbw_sum

# 计算BBWP百分位
df["BBWP"] = np.where(df.index >= 13, (df["BBWSUM"] / df["BBWLEN"]) * 100, None)

# 查看结果
print(df[["BASIS", "STDEV", "BBW", "BBWLEN", "BBWSUM", "BBWP"]].tail())

代码说明

  1. 索引重置:用reset_index(drop=True)替代手动生成索引,更简洁可靠。
  2. 动态窗口计算:通过循环遍历每行,根据BBWLEN取对应长度的前期BBW数据,利用numpy向量化操作统计符合条件的数量,效率远高于硬编码多个shift。
  3. 结果兼容:完全匹配Pine Script逻辑,仅在索引>=13时计算BBWP,其余位置设为None。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:06:28