File size: 2,781 Bytes
61b4af1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# scripts/analytics_build_summary.py

from pathlib import Path
import numpy as np
import pandas as pd

FORECAST_PATH = Path("outputs/mandi_commodity_all_forecasts_moirai.csv")
OUT_SUMMARY_PATH = Path("outputs/analytics_mandi_commodity_summary.csv")


def compute_group_stats(group: pd.DataFrame) -> pd.Series:
    """
    Compute summary stats for one (Mandi, Commodity) group
    over the Moirai forecast horizon.
    """
    prices = group["pred_modal_price"].values.astype(float)

    mean_price = float(np.mean(prices))
    min_price = float(np.min(prices))
    max_price = float(np.max(prices))
    std_price = float(np.std(prices))

    # volatility as % of mean (avoid divide by zero)
    vol_pct = float(std_price / mean_price) if mean_price != 0 else np.nan

    # simple linear trend: price ~ a * t + b
    t = np.arange(len(prices))
    if len(prices) >= 2:
        slope, intercept = np.polyfit(t, prices, 1)
    else:
        slope, intercept = np.nan, np.nan

    # day-to-day percentage changes
    if len(prices) >= 2:
        pct_changes = np.diff(prices) / prices[:-1]
        max_up = float(np.max(pct_changes))
        max_down = float(np.min(pct_changes))
        max_abs_move = float(np.max(np.abs(pct_changes)))
    else:
        max_up = max_down = max_abs_move = np.nan

    # spike / crash flags (thresholds can be tuned)
    spike_flag = bool(max_up > 0.10)      # > +10% jump in one day
    crash_flag = bool(max_down < -0.10)   # < -10% drop in one day

    return pd.Series(
        {
            "forecast_mean_price": mean_price,
            "forecast_min_price": min_price,
            "forecast_max_price": max_price,
            "forecast_std_price": std_price,
            "forecast_volatility_pct": vol_pct,
            "trend_slope_per_day": float(slope),
            "max_daily_pct_up": max_up,
            "max_daily_pct_down": max_down,
            "max_abs_daily_pct_move": max_abs_move,
            "has_spike": spike_flag,
            "has_crash": crash_flag,
        }
    )


def main():
    print(f"Loading Moirai forecasts from {FORECAST_PATH} ...")
    df = pd.read_csv(FORECAST_PATH)

    # ensure date is datetime for potential future use
    df["date"] = pd.to_datetime(df["date"])

    group_cols = [c for c in ["Mandi", "Commodity", "State", "district_name"] if c in df.columns]

    print(f"Grouping by: {group_cols}")
    grouped = df.groupby(group_cols, dropna=False)

    summary_rows = grouped.apply(compute_group_stats).reset_index()

    OUT_SUMMARY_PATH.parent.mkdir(parents=True, exist_ok=True)
    summary_rows.to_csv(OUT_SUMMARY_PATH, index=False)

    print(f"Saved mandi+commodity summary analytics to: {OUT_SUMMARY_PATH}")
    print(f"Summary shape: {summary_rows.shape}")


if __name__ == "__main__":
    main()