# System monitorowania - Karta EWMA do wczesnego ostrzegania
print("\n" + "="*80)
print("System wczesnego ostrzegania - karta EWMA")
print("="*80)
# Parametry karty EWMA
lambda_ewma = 0.2 # Waga (0.1-0.3 dla powolnych zmian)
mu_0 = 0 # Średnia docelowa dla błędów (powinniśmy być bliscy prognozie)
sigma = 100 # Odchylenie standardowe (naturalny szum rynku)
L = 3.0 # Współczynnik granic (3.0 standard, 2.5-2.576 bardziej czułe)
# Obliczenie błędów prognozy kombinowanej vs rzeczywistość
# Symulujemy scenariusz: rzeczywisty przebieg = Scenariusz Prawdopodobny + szum
np.random.seed(42)
rzeczywistosc_symul = df_prognozy['NAJBARDZIEJ PRAWDOPODOBNY'].values + np.random.normal(0, 50, len(lata_prognozy))
bledy_prognozy = rzeczywistosc_symul - prognoza_kombinowana
# Obliczenie statystyki EWMA dla błędów
Z_ewma = [bledy_prognozy[0]]
for t in range(1, len(bledy_prognozy)):
Z_t = lambda_ewma * bledy_prognozy[t] + (1 - lambda_ewma) * Z_ewma[-1]
Z_ewma.append(Z_t)
Z_ewma = np.array(Z_ewma)
# Granice kontrolne
UCL = mu_0 + L * sigma * np.sqrt((lambda_ewma / (2 - lambda_ewma)))
LCL = mu_0 - L * sigma * np.sqrt((lambda_ewma / (2 - lambda_ewma)))
# Identyfikacja alarm
alarmy = (Z_ewma > UCL) | (Z_ewma < LCL)
print(f"\nParametry karty EWMA:")
print(f" λ (lambda): {lambda_ewma}")
print(f" μ₀ (średnia docelowa): {mu_0}")
print(f" σ (odchylenie standardowe): {sigma}")
print(f" L (współczynnik granic): {L}")
print(f" UCL (górna granica): {UCL:.0f}")
print(f" LCL (dolna granica): {LCL:.0f}")
print(f"\nAlarmy wykryte: {np.sum(alarmy)} z {len(alarmy)} periodów")
if np.sum(alarmy) > 0:
lata_alarmu = lata_prognozy[alarmy]
print(f"Okresy zagrożenia: {list(lata_alarmu)}")
# Wizualizacja karty EWMA
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10))
# Wykres 1: Rzeczywistość vs prognoza
ax1.plot(lata_prognozy, rzeczywistosc_symul, 'ko-', linewidth=2, markersize=6, label='Rzeczywisty przebieg (symulacja)')
ax1.plot(lata_prognozy, prognoza_kombinowana, 'b--', linewidth=2.5, label='Prognoza kombinowana')
ax1.fill_between(lata_prognozy,
df_prognozy['OPTYMISTYCZNY'],
df_prognozy['PESYMISTYCZNY'],
color='gray',
alpha=0.15,
label='Scenariusze główne')
ax1.set_xlabel('Rok', fontweight='bold')
ax1.set_ylabel('Cena za m² (zł)', fontweight='bold')
ax1.set_title('Monitorowanie Rzeczywistego Przebiegu vs Prognozy', fontweight='bold', fontsize=12)
ax1.grid(True, alpha=0.3)
ax1.legend(fontsize=10)
# Wykres 2: Karta EWMA
ax2.plot(lata_prognozy, Z_ewma, 'o-', color='darkblue', linewidth=2, markersize=6, label='Statystyka EWMA')
ax2.axhline(y=UCL, color='red', linestyle='--', linewidth=2, label=f'UCL = {UCL:.0f}')
ax2.axhline(y=LCL, color='red', linestyle='--', linewidth=2, label=f'LCL = {LCL:.0f}')
ax2.axhline(y=mu_0, color='green', linestyle='-', linewidth=1.5, alpha=0.5, label='Cel (0)')
ax2.fill_between(lata_prognozy, LCL, UCL, color='lightgreen', alpha=0.2, label='Zona kontrolna')
# Zaznacz alarmy
alarmy_idx = np.where(alarmy)[0]
if len(alarmy_idx) > 0:
ax2.scatter(lata_prognozy[alarmy_idx], Z_ewma[alarmy_idx], color='red', s=200, marker='X',
zorder=5, label='ALARM', edgecolors='darkred', linewidths=2)
ax2.set_xlabel('Rok', fontweight='bold')
ax2.set_ylabel('Statystyka Z(EWMA)', fontweight='bold')
ax2.set_title('Karta EWMA - System Wczesnego Ostrzegania o Odchyleniach od Prognozy', fontweight='bold', fontsize=12)
ax2.grid(True, alpha=0.3)
ax2.legend(fontsize=10, loc='upper left')
ax2.set_xticks(np.arange(2025, 2037, 2))
plt.tight_layout()
plt.show()
print("\n[OK] System ostrzegawczy utworzony")