Poowanath commited on
Commit
4faea2e
·
verified ·
1 Parent(s): 3d38b82

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -187
app.py DELETED
@@ -1,187 +0,0 @@
1
- """Hugging Face Space - BTC Prediction API"""
2
- from fastapi import FastAPI, HTTPException
3
- from pydantic import BaseModel
4
- import pandas as pd
5
- import yfinance as yf
6
- import torch
7
- import numpy as np
8
- import random
9
- from chronos import ChronosPipeline
10
- from datetime import date, timedelta
11
- from typing import Optional
12
-
13
- # ตั้ง seed
14
- SEED = 42
15
- random.seed(SEED)
16
- np.random.seed(SEED)
17
- torch.manual_seed(SEED)
18
-
19
- app = FastAPI(title="BTC Prediction API", version="1.0.0")
20
-
21
- # โหลด model ตอน startup
22
- model_pipeline = None
23
-
24
- @app.on_event("startup")
25
- async def load_model():
26
- global model_pipeline
27
- print("🤖 Loading Chronos model...")
28
- model_pipeline = ChronosPipeline.from_pretrained(
29
- "amazon/chronos-t5-tiny",
30
- device_map="cpu",
31
- torch_dtype=torch.float32
32
- )
33
- print("✅ Model loaded successfully")
34
-
35
-
36
- class PredictionRequest(BaseModel):
37
- start_date: str = "2020-01-01"
38
- window_size: int = 256
39
-
40
-
41
- class BatchPredictionRequest(BaseModel):
42
- """สำหรับทำนายหลายวัน (ใช้ใน strategy filter)"""
43
- prices: list[float] # ราคาที่ต้องการทำนาย
44
- window_size: int = 256
45
-
46
-
47
- def get_btc_data(start: str) -> pd.DataFrame:
48
- """ดึงข้อมูล BTC"""
49
- end = (date.today() + timedelta(days=1)).strftime("%Y-%m-%d")
50
- btc = yf.download("BTC-USD", start=start, end=end, progress=False)
51
-
52
- if isinstance(btc.columns, pd.MultiIndex):
53
- btc.columns = btc.columns.get_level_values(0)
54
-
55
- df = btc[["Close"]].copy()
56
- df = df.ffill().dropna()
57
- return df
58
-
59
-
60
- def predict_price(data: pd.DataFrame, window_size: int = 256) -> Optional[float]:
61
- """ทำนายราคา"""
62
- if model_pipeline is None:
63
- raise RuntimeError("Model not loaded")
64
-
65
- if len(data) < window_size:
66
- context = data['Close'].values.tolist()
67
- else:
68
- context = data['Close'].values[-window_size:].tolist()
69
-
70
- context_tensor = torch.tensor([context])
71
-
72
- torch.manual_seed(SEED)
73
-
74
- with torch.no_grad():
75
- forecast = model_pipeline.predict(
76
- context_tensor,
77
- prediction_length=1,
78
- num_samples=1
79
- )
80
-
81
- predicted_price = forecast[0, 0, 0].item()
82
- return float(predicted_price)
83
-
84
-
85
- @app.get("/")
86
- def root():
87
- return {
88
- "service": "BTC Prediction API",
89
- "model": "amazon/chronos-t5-tiny",
90
- "status": "ready" if model_pipeline else "loading"
91
- }
92
-
93
-
94
- @app.get("/health")
95
- def health():
96
- return {
97
- "status": "ok",
98
- "model_loaded": model_pipeline is not None
99
- }
100
-
101
-
102
- @app.post("/predict")
103
- def predict(req: PredictionRequest):
104
- """ทำนายราคา BTC วันถัดไป"""
105
- try:
106
- if model_pipeline is None:
107
- raise HTTPException(status_code=503, detail="Model is still loading")
108
-
109
- # ดึงข้อมูล
110
- data = get_btc_data(req.start_date)
111
-
112
- if len(data) < 30:
113
- raise HTTPException(status_code=400, detail="Not enough data")
114
-
115
- # ทำนาย
116
- predicted_price = predict_price(data, req.window_size)
117
-
118
- if predicted_price is None:
119
- raise HTTPException(status_code=500, detail="Prediction failed")
120
-
121
- # คำนวณผลลัพธ์
122
- last_close = float(data["Close"].iloc[-1])
123
- last_date = data.index[-1]
124
- next_date = last_date + pd.Timedelta(days=1)
125
- change_pct = ((predicted_price / last_close) - 1) * 100
126
-
127
- return {
128
- "symbol": "BTC-USD",
129
- "last_date": str(last_date.date()),
130
- "next_date": str(next_date.date()),
131
- "last_close": last_close,
132
- "predicted_close": predicted_price,
133
- "predicted_change_pct": float(change_pct),
134
- "model": "amazon/chronos-t5-tiny",
135
- "window_size": req.window_size
136
- }
137
-
138
- except HTTPException:
139
- raise
140
- except Exception as e:
141
- raise HTTPException(status_code=500, detail=str(e))
142
-
143
-
144
- @app.post("/predict_from_data")
145
- def predict_from_data(req: BatchPredictionRequest):
146
- """ทำนายราคาจากข้อมูลที่ส่งมา (สำหรับ strategy filter)"""
147
- try:
148
- if model_pipeline is None:
149
- raise HTTPException(status_code=503, detail="Model is still loading")
150
-
151
- if len(req.prices) < 30:
152
- raise HTTPException(status_code=400, detail="Not enough data (need at least 30 prices)")
153
-
154
- # ใช้ราคาที่ส่งมา
155
- if len(req.prices) < req.window_size:
156
- context = req.prices
157
- else:
158
- context = req.prices[-req.window_size:]
159
-
160
- context_tensor = torch.tensor([context])
161
-
162
- torch.manual_seed(SEED)
163
-
164
- with torch.no_grad():
165
- forecast = model_pipeline.predict(
166
- context_tensor,
167
- prediction_length=1,
168
- num_samples=1
169
- )
170
-
171
- predicted_price = forecast[0, 0, 0].item()
172
-
173
- return {
174
- "predicted_price": float(predicted_price),
175
- "input_length": len(req.prices),
176
- "window_size": req.window_size
177
- }
178
-
179
- except HTTPException:
180
- raise
181
- except Exception as e:
182
- raise HTTPException(status_code=500, detail=str(e))
183
-
184
-
185
- if __name__ == "__main__":
186
- import uvicorn
187
- uvicorn.run(app, host="0.0.0.0", port=7860)