Miruzen commited on
Commit
4c99a8e
·
verified ·
1 Parent(s): 286df99

Upload 6 files

Browse files
Files changed (6) hide show
  1. app.py +105 -0
  2. best_model_lstm.h5 +3 -0
  3. best_params.json +8 -0
  4. requirments.txt +7 -0
  5. runtime.txt +0 -0
  6. scaler.pkl +3 -0
app.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ from fastapi import FastAPI
3
+ from pydantic import BaseModel
4
+ import numpy as np
5
+ import pandas as pd
6
+ import joblib
7
+ import json
8
+ import tensorflow as tf
9
+ from tensorflow.keras.models import load_model
10
+ from sklearn.preprocessing import MinMaxScaler
11
+
12
+ app = FastAPI(
13
+ title="Forex LSTM Prediction API",
14
+ description="API untuk prediksi harga EUR/USD H+1 menggunakan model LSTM terbaik",
15
+ version="1.0"
16
+ )
17
+
18
+ # ==========================================================
19
+ # LOAD MODEL, PARAMETER, DAN SCALER
20
+ # ==========================================================
21
+ MODEL_PATH = "lstm_model.h5"
22
+ SCALER_PATH = "scaler.pkl"
23
+ PARAMS_PATH = "best_params.json"
24
+
25
+ print("📥 Loading LSTM model...")
26
+ model = load_model(MODEL_PATH)
27
+
28
+ print("📥 Loading scaler...")
29
+ scaler = joblib.load(SCALER_PATH)
30
+
31
+ print("📥 Loading best parameters...")
32
+ with open(PARAMS_PATH, "r") as f:
33
+ best_params = json.load(f)
34
+
35
+ LOOKBACK = best_params.get("lookback", 7) # default 7 jika tidak ada
36
+ FEATURE_ORDER = best_params.get("features", [
37
+ "mood_score", "t_pos", "t_neg", "c_pos", "c_neg",
38
+ "norm_ema20", "norm_ema50", "norm_close"
39
+ ])
40
+
41
+ print(f"✅ Model loaded. Lookback={LOOKBACK}, Features={FEATURE_ORDER}")
42
+
43
+ # ==========================================================
44
+ # INPUT SCHEMA
45
+ # ==========================================================
46
+ class LSTMInput(BaseModel):
47
+ data: list # list of daily records (latest LOOKBACK hari)
48
+ # contoh format:
49
+ # [
50
+ # {"date": "2025-10-23", "mood_score": 0.5, "t_pos": 0.3, "t_neg": 0.2, ...},
51
+ # ...
52
+ # ]
53
+
54
+ # ==========================================================
55
+ # HELPER FUNCTION
56
+ # ==========================================================
57
+ def prepare_input(data):
58
+ """Convert input list to numpy array sesuai urutan fitur dan lookback"""
59
+ df = pd.DataFrame(data)
60
+ missing_cols = [f for f in FEATURE_ORDER if f not in df.columns]
61
+ if missing_cols:
62
+ raise ValueError(f"Missing columns: {missing_cols}")
63
+
64
+ X = df[FEATURE_ORDER].values[-LOOKBACK:]
65
+ if X.shape[0] < LOOKBACK:
66
+ raise ValueError(f"Need at least {LOOKBACK} timesteps, got {X.shape[0]}")
67
+
68
+ X = np.expand_dims(X, axis=0)
69
+ return X, df
70
+
71
+ # ==========================================================
72
+ # ENDPOINT
73
+ # ==========================================================
74
+ @app.post("/predict")
75
+ def predict_price(input_data: LSTMInput):
76
+ try:
77
+ X, df = prepare_input(input_data.data)
78
+ pred_norm = model.predict(X)[0][0]
79
+ pred_close = scaler.inverse_transform([[pred_norm]])[0][0]
80
+
81
+ last_date = pd.to_datetime(df["date"].iloc[-1])
82
+ next_date = (last_date + pd.Timedelta(days=1)).strftime("%Y-%m-%d")
83
+
84
+ response = {
85
+ "next_date": next_date,
86
+ "predicted_norm_close": float(pred_norm),
87
+ "predicted_close": float(pred_close),
88
+ "model_info": {
89
+ "lookback": LOOKBACK,
90
+ "features_used": FEATURE_ORDER,
91
+ "source_model": MODEL_PATH
92
+ }
93
+ }
94
+
95
+ return {"status": "ok", "result": response}
96
+
97
+ except Exception as e:
98
+ return {"status": "error", "message": str(e)}
99
+
100
+ # ==========================================================
101
+ # ROOT TEST
102
+ # ==========================================================
103
+ @app.get("/")
104
+ def root():
105
+ return {"message": "Forex LSTM Prediction API is active!"}
best_model_lstm.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3ed1efb761ce2aac4c09ff5e8beaf55e86d76c299b04477e59ad6a099dd53a7d
3
+ size 247104
best_params.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "lstm_units_1": 64,
3
+ "dropout_1": 0.1,
4
+ "lstm_units_2": 64,
5
+ "dropout_2": 0.3,
6
+ "dense_units": 16,
7
+ "optimizer": "adam"
8
+ }
requirments.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ tensorflow
4
+ numpy
5
+ pandas
6
+ joblib
7
+ scikit-learn
runtime.txt ADDED
File without changes
scaler.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ab8a87f6714de029e030c4a283abb1736134e4c0dfda779d1afa6792abd10eb7
3
+ size 630