Lullooo commited on
Commit
281e26b
·
verified ·
1 Parent(s): 637c846

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -218
app.py DELETED
@@ -1,218 +0,0 @@
1
- ################### PACKAGES
2
- import pandas as pd
3
- import numpy as np
4
- from datetime import datetime, timedelta
5
- import time
6
- import requests
7
- from pytrends.request import TrendReq
8
- import joblib
9
- import gradio as gr
10
- from sklearn.preprocessing import StandardScaler
11
-
12
-
13
- ################### MODEL LOADING
14
- # Load XGBoost and NGBoost
15
- xgb_artifact = joblib.load("xgb_volatility_model.joblib")
16
- xgb_model = xgb_artifact["model"]
17
- xgb_features = xgb_artifact["feature_names"]
18
-
19
- ngb_artifact = joblib.load("ngb_volatility_model.joblib")
20
- ngb_model = ngb_artifact["model"]
21
- ngb_features = ngb_artifact["feature_names"]
22
-
23
- forecast_ngb_artifact = joblib.load("Forecast_ngb_volatility_model.joblib")
24
- forecast_ngb_model = forecast_ngb_artifact["model"]
25
- forecast_ngb_features = forecast_ngb_artifact["feature_names"]
26
-
27
- # Load KMeans + scaler
28
- kmeans_artifact = joblib.load("kmeans_model.joblib")
29
- kmeans_model = kmeans_artifact["model"]
30
- cluster_scaler = kmeans_artifact["scaler"]
31
- # Only use the features that were actually used during training
32
- cluster_features_names = ["close", "volume", "trend", "fg_index"]
33
-
34
-
35
- ################### FEATURE GATHERING
36
- def fetch_ohlcv_last_n_days(date="2026-01-18", n_days=90):
37
- end = pd.to_datetime(date)
38
- start = end - timedelta(days=n_days)
39
-
40
- url = "https://api.coingecko.com/api/v3/coins/bitcoin/market_chart/range"
41
- params = {
42
- "vs_currency": "usd",
43
- "from": int(start.timestamp()),
44
- "to": int(end.timestamp())
45
- }
46
-
47
- r = requests.get(url, params=params, timeout=20)
48
- r.raise_for_status()
49
- data = r.json()
50
-
51
- prices = pd.DataFrame(data["prices"], columns=["timestamp", "close"])
52
- volumes = pd.DataFrame(data["total_volumes"], columns=["timestamp", "volume"])
53
-
54
- df = prices.merge(volumes, on="timestamp")
55
- df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms")
56
- df.set_index("timestamp", inplace=True)
57
-
58
- df = df.resample("1D").agg(
59
- open=("close", "first"),
60
- high=("close", "max"),
61
- low=("close", "min"),
62
- close=("close", "last"),
63
- volume=("volume", "sum")
64
- ).dropna()
65
-
66
- return df
67
-
68
- def fetch_fg_last_6_days(df):
69
- url = "https://api.alternative.me/fng/?limit=0&format=json"
70
- response = requests.get(url)
71
- fg_df = pd.DataFrame(response.json()["data"])
72
- fg_df["timestamp"] = pd.to_datetime(fg_df["timestamp"], unit="s")
73
- fg_df.set_index("timestamp", inplace=True)
74
- fg_df = fg_df[["value"]].astype(float)
75
- fg_df.rename(columns={"value":"fg_index"}, inplace=True)
76
- fg_df = fg_df.reindex(df.index, method="ffill")
77
- df["fg_index"] = fg_df["fg_index"].values
78
- return df
79
-
80
- def fetch_google_trend_for_date(keyword="Bitcoin", target_date="2024-01-15", window=7):
81
- pytrends = TrendReq(hl="en-US", tz=360)
82
- target_date = pd.to_datetime(target_date)
83
- start_date = (target_date - timedelta(days=window)).strftime("%Y-%m-%d")
84
- end_date = target_date.strftime("%Y-%m-%d")
85
- timeframe = f"{start_date} {end_date}"
86
- try:
87
- pytrends.build_payload([keyword], timeframe=timeframe)
88
- df = pytrends.interest_over_time()
89
- if df.empty:
90
- return 0
91
- df = df.rename(columns={keyword: "trend"})
92
- df = df.drop(columns=["isPartial"], errors="ignore")
93
- df.index = pd.to_datetime(df.index)
94
- if target_date in df.index:
95
- return df.loc[target_date, "trend"]
96
- else:
97
- return 0
98
- except:
99
- return 0
100
-
101
-
102
- ################### FEATURE ENGINEERING
103
- def engineer_features(df):
104
- df["log_return"] = np.log(df["close"] / df["close"].shift(1))
105
- df["hl_spread"] = df["high"] - df["low"]
106
- df["co_spread"] = df["close"] - df["open"]
107
- df["momentum_3"] = df["close"] - df["close"].shift(3)
108
- df["vol_change"] = df["volume"] - df["volume"].shift(1)
109
- df["rolling_std_5"] = df["log_return"].rolling(5).std()
110
- # Fill NaNs for first few rows
111
- df = df.fillna(0)
112
- return df
113
-
114
- ################### ASSIGN CLUSTER
115
- def assign_cluster(df):
116
- cluster_features = df[cluster_features_names]
117
- scaled = cluster_scaler.transform(cluster_features)
118
- df["cluster"] = kmeans_model.predict(scaled)
119
- return df
120
-
121
- ################### PREDICTION FUNCTION
122
- def predict_volatility(date):
123
- # Fetch raw data
124
- df = fetch_ohlcv_last_n_days(date=date, n_days=90)
125
- df = fetch_fg_last_6_days(df)
126
- trend_value = fetch_google_trend_for_date("Bitcoin", date)
127
- df["trend"] = trend_value
128
- df["trend"] = df["trend"].ffill().fillna(0)
129
-
130
- # Feature engineering
131
- df = engineer_features(df)
132
-
133
- # Clustering
134
- # Clustering
135
- df = assign_cluster(df)
136
-
137
- assert "cluster" in df.columns, "Cluster feature missing after assignment"
138
-
139
-
140
- # ---------------- NOWCASTING ----------------
141
- X_xgb = df.iloc[-1:][xgb_features]
142
- X_ngb = df.iloc[-1:][ngb_features]
143
-
144
- point = xgb_model.predict(X_xgb)[0]
145
- dist = ngb_model.pred_dist(X_ngb)
146
- low, high = dist.ppf([0.025, 0.975])
147
-
148
- # ---------------- FORECASTING (t+1) ----------------
149
- X_ngb_fore = df.iloc[-1:][forecast_ngb_features]
150
-
151
- for_point = forecast_ngb_model.predict(X_ngb_fore)[0]
152
- for_dist = forecast_ngb_model.pred_dist(X_ngb_fore)
153
- for_low, for_high = for_dist.ppf([0.025, 0.975])
154
-
155
- return point, low, high, for_point, for_low, for_high
156
-
157
-
158
-
159
- ################### GRADIO INTERFACE
160
- import gradio as gr
161
- import pandas as pd
162
-
163
- ################### HELPER FUNCTION TO RETURN TABLE ###################
164
- def predict_volatility_for_table(date):
165
- """
166
- Returns a DataFrame with Nowcast and Forecast predictions for the given date.
167
- """
168
- # Run your existing predict_volatility function
169
- point, low, high, for_point, for_low, for_high = predict_volatility(date)
170
-
171
- # Create a DataFrame to display nicely
172
- data = {
173
- "Type": ["Nowcast (t)", "Forecast (t+1)"],
174
- "Volatility": [point, for_point],
175
- "Low 95% CI": [low, for_low],
176
- "High 95% CI": [high, for_high]
177
- }
178
-
179
- df = pd.DataFrame(data)
180
-
181
- # Round values for better readability
182
- df[["Volatility", "Low 95% CI", "High 95% CI"]] = df[["Volatility", "Low 95% CI", "High 95% CI"]].round(4)
183
-
184
- return df
185
-
186
- ################### GRADIO WRAPPER ###################
187
- def gradio_predict(date):
188
- """
189
- Wrapper for Gradio. Returns a DataFrame for display.
190
- """
191
- # Validate date format
192
- try:
193
- pd.to_datetime(date)
194
- except:
195
- return pd.DataFrame({"Error": ["❌ Invalid date format. Use YYYY-MM-DD."]})
196
-
197
- # Attempt to predict
198
- try:
199
- df = predict_volatility_for_table(date)
200
- return df
201
- except Exception as e:
202
- return pd.DataFrame({"Error": [f"⚠️ Error while computing prediction:\n{str(e)}"]})
203
-
204
- ################### GRADIO INTERFACE ###################
205
- demo = gr.Interface(
206
- fn=gradio_predict,
207
- inputs=gr.Textbox(label="📆 Date (YYYY-MM-DD)"),
208
- outputs=gr.Dataframe(label="Volatility Predictions", headers=["Type", "🎯 Volatility", "Low 95% CI", "High 95% CI"]),
209
- title="BTC Volatility Predictor",
210
- description=(
211
- "Enter a date to get predicted BTC volatility and 95% confidence intervals.\n"
212
- "Nowcast = today's volatility, Forecast = next day's volatility."
213
- )
214
- )
215
-
216
- if __name__ == "__main__":
217
- demo.launch()
218
-