Cycles/test/test_pandas_ema.py

81 lines
2.8 KiB
Python
Raw Normal View History

"""
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()