backtrader.indicators.wma 源代码
#!/usr/bin/env python
"""WMA Indicator Module - Weighted Moving Average.
This module provides the WMA (Weighted Moving Average) indicator
which gives more weight to recent prices.
Classes:
WeightedMovingAverage: WMA indicator (alias: WMA).
Example:
class MyStrategy(bt.Strategy):
def __init__(self):
self.wma = bt.indicators.WMA(self.data.close, period=20)
def next(self):
# Price above WMA indicates uptrend
if self.data.close[0] > self.wma[0]:
self.buy()
# Price below WMA indicates downtrend
elif self.data.close[0] < self.wma[0]:
self.sell()
"""
import math
from ..utils.py3 import range
from . import MovingAverageBase
[文档]
class WeightedMovingAverage(MovingAverageBase):
"""
A Moving Average which gives an arithmetic weighting to values with the
newest having the more weight
Formula:
- weights = range(1, period + 1)
- coef = 2 / (period * (period + 1))
- movav = coef * Sum(weight[i] * data[period - i] for i in range(period))
See also:
- http://en.wikipedia.org/wiki/Moving_average#Weighted_moving_average
"""
alias = (
"WMA",
"MovingAverageWeighted",
)
lines = ("wma",)
def __init__(self):
"""Initialize the WMA indicator.
Calculates weights and coefficient for weighted moving average.
"""
super().__init__()
self.coef = 2.0 / (self.p.period * (self.p.period + 1.0))
self.weights = tuple(float(x) for x in range(1, self.p.period + 1))
[文档]
def next(self):
"""Calculate WMA for the current bar.
Applies arithmetic weighting with newest values having more weight.
"""
period = self.p.period
coef = self.coef
weights = self.weights
weighted_sum = 0.0
for i in range(period):
weighted_sum += weights[period - 1 - i] * self.data[-i]
self.lines.wma[0] = coef * weighted_sum
[文档]
def once(self, start, end):
"""Calculate WMA in runonce mode.
Applies weighted average calculation across all bars.
"""
darray = self.data.array
larray = self.lines.wma.array
period = self.p.period
coef = self.coef
weights = self.weights
while len(larray) < end:
larray.append(0.0)
# Pre-fill warmup with NaN
for i in range(min(period - 1, len(darray))):
if i < len(larray):
larray[i] = float("nan")
for i in range(period - 1, min(end, len(darray))):
weighted_sum = 0.0
for j in range(period):
idx = i - j
if idx >= 0 and idx < len(darray):
val = darray[idx]
if not (isinstance(val, float) and math.isnan(val)):
weighted_sum += weights[period - 1 - j] * val
if i < len(larray):
larray[i] = coef * weighted_sum
WMA = WeightedMovingAverage