import json
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

DATA_FILE = "/home/jerome/Perso/freqtradeDocker/user_data/data/binance/BTC_USDC-4h.feather"


def compute_crash_risk_index(df):
    # VOLATILITÉ
    df['H-L'] = df['high'] - df['low']
    df['ATR'] = df['H-L'].rolling(14).mean()
    df['atr_norm'] = df['ATR'] / df['close']

    # DRAWDOWN (critique)
    df['rolling_max'] = df['close'].rolling(48).max()
    df['drawdown'] = (df['close'] - df['rolling_max']) / df['rolling_max']
    df['dd_score'] = np.clip(-df['drawdown'] / 0.10, 0, 1)

    # TENDANCE (slope)
    df['MA7'] = df['close'].rolling(7).mean()
    df['MA14'] = df['close'].rolling(14).mean()
    df['slope'] = df['MA7'] - df['MA14']
    df['slope_score'] = np.clip(1 - (df['slope'] / df['close']), 0, 1)

    # NÉGATIVE STREAK
    df['neg_streak'] = df['close'].pct_change().apply(lambda x: min(x, 0)).rolling(24).sum()
    df['neg_score'] = np.clip(-df['neg_streak'] / 0.05, 0, 1)

    # COMPOSANTS COURT TERME
    df['pct_change_3'] = df['close'].pct_change(3)
    df['pct_change_3_smooth'] = df['pct_change_3'].rolling(6).mean()
    df['crash_score'] = np.clip(1 + (df['pct_change_3_smooth'] / 0.05), 0, 1)

    df['speed'] = df['close'].diff().rolling(6).mean()
    df['accel'] = df['speed'].diff().rolling(6).mean()
    df['STD20'] = df['close'].rolling(20).std()
    df['accel_score'] = np.clip(1 + (df['accel'] / (df['STD20'] + 1e-9)), 0, 1)

    # INDEX FINAL
    df['crash_raw'] = (
            0.35 * df['dd_score'] +  # le plus important pour crash lent
            0.25 * df['neg_score'] +
            0.20 * df['slope_score'] +
            0.10 * df['crash_score'] +
            0.10 * df['accel_score']
    )

    # LISSAGE SIMPLE
    df['crash_risk_index'] = df['crash_raw'].ewm(span=24).mean()

    return df


#
# def compute_crash_risk_index(df):
#     # -- volatilité
#     df['H-L'] = df['high'] - df['low']
#     df['ATR'] = df['H-L'].rolling(14).mean()
#     df['atr_norm'] = df['ATR'] / df['close']
#
#     # -- variations lissées pour éviter les spikes
#     df['pct_change_3'] = df['close'].pct_change(3)
#     df['pct_change_3_smooth'] = df['pct_change_3'].rolling(6).mean()
#
#     # -- speed/accel : on SMOOTH sinon c'est incontrôlable
#     df['speed'] = df['close'].diff().rolling(6).mean()
#     df['accel'] = df['speed'].diff().rolling(6).mean()
#
#     # -- Bollinger
#     df['MA20'] = df['close'].rolling(20).mean()
#     df['STD20'] = df['close'].rolling(20).std()
#     df['BB_lower'] = df['MA20'] - 2 * df['STD20']
#
#     # -------- Scores normalisés & STABLES --------
#     df['crash_score'] = np.clip(1 + (df['pct_change_3_smooth'] / 0.05), 0, 1)
#
#     df['accel_score'] = np.clip(
#         1 + (df['accel'] / (df['STD20'] + 1e-9)),
#         0, 1
#     )
#
#     df['boll_score'] = np.clip(
#         (df['close'] - df['BB_lower']) / (3 * df['STD20']),  # + 3σ au lieu de 2σ
#         0, 1
#     )
#
#     df['atr_score']  = np.clip(
#         1 - (df['atr_norm'] / 0.06),  # tolérance plus large
#         0, 1
#     )
#
#     # -------- COMBINAISON + DOUBLE SMOOTHING --------
#     df['crash_raw'] = (
#         0.30 * df['crash_score'] +
#         0.25 * df['accel_score'] +
#         0.20 * df['boll_score'] +
#         0.15 * df['atr_score']
#     )
#
#     # Lissage ultra important pour éviter le 0.3 → 0.9
#     df['crash_risk_index'] = (
#         df['crash_raw'].ewm(span=48).mean()   # 2 jours en 1h
#     ).rolling(24).mean()                      # filtre final
#
#     return df

# def compute_crash_risk_index(df):
#     df['H-L'] = df['high'] - df['low']
#     df['ATR'] = df['H-L'].rolling(14).mean()
#     df['atr_norm'] = df['ATR'] / df['close']
#
#     df['pct_change_3'] = df['close'].pct_change(3)
#
#     df['speed'] = df['close'].diff()
#     df['accel'] = df['speed'].diff()
#
#     df['MA20'] = df['close'].rolling(20).mean()
#     df['STD20'] = df['close'].rolling(20).std()
#     df['BB_lower'] = df['MA20'] - 2 * df['STD20']
#
#     df['crash_score'] = np.clip(1 + (df['pct_change_3'] / 0.05), 0, 1)
#     df['accel_score'] = np.clip(1 + (df['accel'] / df['STD20']), 0, 1)
#     df['boll_score'] = np.clip((df['close'] - df['BB_lower']) / (2 * df['STD20']), 0, 1)
#     df['atr_score']  = np.clip(1 - (df['atr_norm'] / 0.04), 0, 1)
#
#     df['crash_raw'] = (
#         0.30 * df['crash_score'] +
#         0.25 * df['accel_score'] +
#         0.20 * df['boll_score'] +
#         0.15 * df['atr_score']
#     )
#
#     # Lissage ultra important pour éviter le 0.3 → 0.9
#     df['crash_risk_index'] = (
#         df['crash_raw'].ewm(span=4).mean()   # 2 jours en 1h
#     ).rolling(2).mean()                      # filtre final
#
#     return df

# Load Freqtrade OHLCV JSON
# with open(DATA_FILE, "r") as f:
#     raw = json.load(f)

df = pd.read_feather(DATA_FILE)
print(df.head())


# df = pd.DataFrame(raw)
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date')

# compute risk
df = compute_crash_risk_index(df)

# Only keep Nov. 2025
df = df["2025-10-01":"2025-12-10"]

plt.figure(figsize=(12, 6))
plt.plot(df.index, df['crash_risk_index'])
plt.title("Crash Risk Index – Novembre 2025")
plt.grid(True)
plt.show()
