- Introduced `BBRSIncrementalState` for real-time processing of the Bollinger Bands + RSI strategy, allowing minute-level data input and internal timeframe aggregation. - Added `TimeframeAggregator` class to handle real-time data aggregation to higher timeframes (15min, 1h, etc.). - Updated `README_BBRS.md` to document the new incremental strategy, including key features and usage examples. - Created comprehensive tests to validate the incremental strategy against the original implementation, ensuring signal accuracy and performance consistency. - Enhanced error handling and logging for better monitoring during real-time processing. - Updated `TODO.md` to reflect the completion of the incremental BBRS strategy implementation.
81 lines
2.8 KiB
Python
81 lines
2.8 KiB
Python
"""
|
|
Test pandas EMA behavior to understand Wilder's smoothing initialization
|
|
"""
|
|
|
|
import pandas as pd
|
|
import numpy as np
|
|
|
|
def test_pandas_ema():
|
|
"""Test how pandas EMA works with Wilder's smoothing."""
|
|
|
|
# Sample data from our debug
|
|
prices = [16568.00, 16569.00, 16569.00, 16568.00, 16565.00, 16565.00,
|
|
16565.00, 16565.00, 16565.00, 16565.00, 16566.00, 16566.00,
|
|
16563.00, 16566.00, 16566.00, 16566.00, 16566.00, 16566.00]
|
|
|
|
# Calculate deltas
|
|
deltas = np.diff(prices)
|
|
gains = np.where(deltas > 0, deltas, 0)
|
|
losses = np.where(deltas < 0, -deltas, 0)
|
|
|
|
print("Price changes:")
|
|
for i, (delta, gain, loss) in enumerate(zip(deltas, gains, losses)):
|
|
print(f"Step {i+1}: delta={delta:5.2f}, gain={gain:4.2f}, loss={loss:4.2f}")
|
|
|
|
# Create series
|
|
gain_series = pd.Series(gains)
|
|
loss_series = pd.Series(losses)
|
|
|
|
period = 14
|
|
alpha = 1.0 / period
|
|
|
|
print(f"\nUsing period={period}, alpha={alpha:.6f}")
|
|
|
|
# Test different EMA parameters
|
|
print("\n1. Standard EMA with min_periods=period:")
|
|
avg_gain_1 = gain_series.ewm(alpha=alpha, adjust=False, min_periods=period).mean()
|
|
avg_loss_1 = loss_series.ewm(alpha=alpha, adjust=False, min_periods=period).mean()
|
|
|
|
print("Index | Gain | Loss | AvgGain | AvgLoss | RS | RSI")
|
|
print("-" * 60)
|
|
for i in range(min(len(avg_gain_1), 18)):
|
|
gain = gains[i] if i < len(gains) else 0
|
|
loss = losses[i] if i < len(losses) else 0
|
|
avg_g = avg_gain_1.iloc[i]
|
|
avg_l = avg_loss_1.iloc[i]
|
|
|
|
if not (pd.isna(avg_g) or pd.isna(avg_l)) and avg_l != 0:
|
|
rs = avg_g / avg_l
|
|
rsi = 100 - (100 / (1 + rs))
|
|
else:
|
|
rs = np.nan
|
|
rsi = np.nan
|
|
|
|
print(f"{i:5d} | {gain:4.2f} | {loss:4.2f} | {avg_g:7.4f} | {avg_l:7.4f} | {rs:4.2f} | {rsi:6.2f}")
|
|
|
|
print("\n2. EMA with min_periods=1:")
|
|
avg_gain_2 = gain_series.ewm(alpha=alpha, adjust=False, min_periods=1).mean()
|
|
avg_loss_2 = loss_series.ewm(alpha=alpha, adjust=False, min_periods=1).mean()
|
|
|
|
print("Index | Gain | Loss | AvgGain | AvgLoss | RS | RSI")
|
|
print("-" * 60)
|
|
for i in range(min(len(avg_gain_2), 18)):
|
|
gain = gains[i] if i < len(gains) else 0
|
|
loss = losses[i] if i < len(losses) else 0
|
|
avg_g = avg_gain_2.iloc[i]
|
|
avg_l = avg_loss_2.iloc[i]
|
|
|
|
if not (pd.isna(avg_g) or pd.isna(avg_l)) and avg_l != 0:
|
|
rs = avg_g / avg_l
|
|
rsi = 100 - (100 / (1 + rs))
|
|
elif avg_l == 0 and avg_g > 0:
|
|
rs = np.inf
|
|
rsi = 100.0
|
|
else:
|
|
rs = np.nan
|
|
rsi = np.nan
|
|
|
|
print(f"{i:5d} | {gain:4.2f} | {loss:4.2f} | {avg_g:7.4f} | {avg_l:7.4f} | {rs:4.2f} | {rsi:6.2f}")
|
|
|
|
if __name__ == "__main__":
|
|
test_pandas_ema() |