Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -3,161 +3,154 @@ import torch
|
|
3 |
import torch.nn as nn
|
4 |
import torch.optim as optim
|
5 |
from torch.utils.data import Dataset, DataLoader
|
6 |
-
from sklearn.model_selection import
|
7 |
from sklearn.preprocessing import StandardScaler
|
8 |
-
from sklearn.metrics import mean_squared_error
|
9 |
-
import numpy as np
|
10 |
-
import os
|
11 |
-
import gradio as gr
|
12 |
-
import time
|
13 |
import joblib
|
|
|
|
|
14 |
|
15 |
-
# Load
|
16 |
-
|
17 |
-
# Load the latest CSV data (assume it's updated periodically)
|
18 |
-
data = pd.read_csv('BANKNIFTY_OPTION_CHAIN_data.csv')
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
data['close'].diff(1).clip(upper=0).mean())))
|
25 |
-
data.fillna(0, inplace=True)
|
26 |
-
return data
|
27 |
|
28 |
-
#
|
|
|
|
|
|
|
29 |
class BankNiftyDataset(Dataset):
|
30 |
-
def __init__(self, data, seq_len
|
31 |
self.data = data
|
32 |
self.seq_len = seq_len
|
33 |
-
self.features = features
|
34 |
|
35 |
def __len__(self):
|
36 |
return len(self.data) - self.seq_len
|
37 |
|
38 |
def __getitem__(self, idx):
|
39 |
-
seq_data = self.data.iloc[idx:idx
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
def __init__(self, input_dim, hidden_dim, output_dim, nhead=4, num_encoder_layers=2):
|
49 |
-
super(TransformerLSTMModel, self).__init__()
|
50 |
self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers=1, batch_first=True)
|
51 |
-
self.transformer_encoder = nn.TransformerEncoder(
|
52 |
-
nn.TransformerEncoderLayer(d_model=hidden_dim, nhead=nhead), num_layers=num_encoder_layers
|
53 |
-
)
|
54 |
self.fc = nn.Linear(hidden_dim, output_dim)
|
55 |
|
56 |
def forward(self, x):
|
57 |
-
h0 = torch.zeros(1, x.size(0),
|
58 |
-
c0 = torch.zeros(1, x.size(0),
|
|
|
59 |
out, _ = self.lstm(x, (h0, c0))
|
60 |
-
out = self.transformer_encoder(out)
|
61 |
out = self.fc(out[:, -1, :])
|
62 |
return out
|
63 |
|
64 |
-
#
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
criterion = nn.MSELoss()
|
70 |
-
|
71 |
-
tscv = TimeSeriesSplit(n_splits=n_splits)
|
72 |
-
best_loss = float('inf')
|
73 |
-
|
74 |
-
for fold, (train_idx, val_idx) in enumerate(tscv.split(data)):
|
75 |
-
train_data, val_data = data.iloc[train_idx], data.iloc[val_idx]
|
76 |
-
train_dataset = BankNiftyDataset(train_data, seq_len, features)
|
77 |
-
val_dataset = BankNiftyDataset(val_data, seq_len, features)
|
78 |
-
|
79 |
-
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
|
80 |
-
val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)
|
81 |
-
|
82 |
-
for epoch in range(10): # Train for 10 epochs per fold
|
83 |
-
model.train()
|
84 |
-
for batch in train_loader:
|
85 |
-
features = batch['features']
|
86 |
-
labels = batch['label'].unsqueeze(1)
|
87 |
-
|
88 |
-
optimizer.zero_grad()
|
89 |
-
outputs = model(features)
|
90 |
-
loss = criterion(outputs, labels)
|
91 |
-
loss.backward()
|
92 |
-
optimizer.step()
|
93 |
-
|
94 |
-
# Validation
|
95 |
-
model.eval()
|
96 |
-
val_loss = 0
|
97 |
-
with torch.no_grad():
|
98 |
-
for batch in val_loader:
|
99 |
-
features = batch['features']
|
100 |
-
labels = batch['label'].unsqueeze(1)
|
101 |
-
outputs = model(features)
|
102 |
-
val_loss += criterion(outputs, labels).item()
|
103 |
-
|
104 |
-
val_loss /= len(val_loader)
|
105 |
-
print(f'Fold {fold + 1}, Epoch {epoch + 1}, Val Loss: {val_loss}')
|
106 |
-
|
107 |
-
# Save the best model
|
108 |
-
if val_loss < best_loss:
|
109 |
-
best_loss = val_loss
|
110 |
-
torch.save(model.state_dict(), 'best_model.pth')
|
111 |
-
print("Model updated with new best performance.")
|
112 |
-
|
113 |
-
# Periodically check for new data and retrain
|
114 |
-
def schedule_retraining(interval_hours=24):
|
115 |
-
while True:
|
116 |
-
print("Retraining model...")
|
117 |
-
data = load_data() # Load the latest data
|
118 |
-
retrain_model(data) # Retrain the model
|
119 |
-
print(f"Next retraining scheduled in {interval_hours} hours.")
|
120 |
-
time.sleep(interval_hours * 3600) # Sleep for the specified interval
|
121 |
-
|
122 |
-
# Gradio interface for user prediction after automatic retraining
|
123 |
-
def generate_strategy(open_, high, low, close, volume, oi, sma20, sma50, rsi):
|
124 |
-
# Prepare new data
|
125 |
-
new_data = pd.DataFrame({
|
126 |
-
'open': [open_], 'high': [high], 'low': [low], 'close': [close],
|
127 |
-
'volume': [volume], 'oi': [oi], 'SMA_20': [sma20], 'SMA_50': [sma50], 'RSI': [rsi]
|
128 |
-
})
|
129 |
-
new_data[features] = scaler.transform(new_data[features])
|
130 |
-
seq_data = new_data[features].values
|
131 |
-
|
132 |
-
# Load best model
|
133 |
-
model = TransformerLSTMModel(input_dim=len(features), hidden_dim=128, output_dim=1)
|
134 |
-
model.load_state_dict(torch.load('best_model.pth'))
|
135 |
-
model.eval()
|
136 |
|
137 |
-
|
138 |
-
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
output = model(features)
|
141 |
-
|
|
|
|
|
142 |
|
143 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
144 |
inputs = [
|
145 |
-
gr.
|
146 |
-
gr.
|
147 |
-
gr.
|
148 |
-
gr.
|
149 |
-
gr.
|
150 |
-
gr.
|
151 |
-
gr.
|
152 |
-
gr.
|
153 |
-
gr.
|
154 |
]
|
155 |
|
156 |
-
outputs = gr.
|
157 |
|
158 |
-
# Launch Gradio interface
|
159 |
gr.Interface(fn=generate_strategy, inputs=inputs, outputs=outputs, title="BankNifty Strategy Generator").launch()
|
160 |
|
161 |
-
# Start automatic retraining (optional, can be run separately)
|
162 |
-
if __name__ == "__main__":
|
163 |
-
schedule_retraining(interval_hours=24) # Retrain every 24 hours
|
|
|
3 |
import torch.nn as nn
|
4 |
import torch.optim as optim
|
5 |
from torch.utils.data import Dataset, DataLoader
|
6 |
+
from sklearn.model_selection import train_test_split
|
7 |
from sklearn.preprocessing import StandardScaler
|
|
|
|
|
|
|
|
|
|
|
8 |
import joblib
|
9 |
+
import gradio as gr
|
10 |
+
from apscheduler.schedulers.background import BackgroundScheduler
|
11 |
|
12 |
+
# Load the data
|
13 |
+
data = pd.read_csv('BANKNIFTY_OPTION_CHAIN_data.csv')
|
|
|
|
|
14 |
|
15 |
+
# Preprocess the data
|
16 |
+
scaler = StandardScaler()
|
17 |
+
scaled_data = scaler.fit_transform(data[['open', 'high', 'low', 'close', 'volume', 'oi']])
|
18 |
+
data[['open', 'high', 'low', 'close', 'volume', 'oi']] = scaled_data
|
|
|
|
|
|
|
19 |
|
20 |
+
# Save the scaler for later use
|
21 |
+
joblib.dump(scaler, 'scaler.gz')
|
22 |
+
|
23 |
+
# Create a custom dataset class
|
24 |
class BankNiftyDataset(Dataset):
|
25 |
+
def __init__(self, data, seq_len):
|
26 |
self.data = data
|
27 |
self.seq_len = seq_len
|
|
|
28 |
|
29 |
def __len__(self):
|
30 |
return len(self.data) - self.seq_len
|
31 |
|
32 |
def __getitem__(self, idx):
|
33 |
+
seq_data = self.data.iloc[idx:idx+self.seq_len]
|
34 |
+
features = torch.tensor(seq_data[['open', 'high', 'low', 'close', 'volume', 'oi']].values, dtype=torch.float32)
|
35 |
+
label = torch.tensor(seq_data['close'].iloc[-1], dtype=torch.float32)
|
36 |
+
return features, label
|
37 |
+
|
38 |
+
# Define the LSTM-RNN model
|
39 |
+
class LSTMModel(nn.Module):
|
40 |
+
def __init__(self, input_dim, hidden_dim, output_dim):
|
41 |
+
super(LSTMModel, self).__init__()
|
|
|
|
|
42 |
self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers=1, batch_first=True)
|
|
|
|
|
|
|
43 |
self.fc = nn.Linear(hidden_dim, output_dim)
|
44 |
|
45 |
def forward(self, x):
|
46 |
+
h0 = torch.zeros(1, x.size(0), self.lstm.hidden_size).to(x.device)
|
47 |
+
c0 = torch.zeros(1, x.size(0), self.lstm.hidden_size).to(x.device)
|
48 |
+
|
49 |
out, _ = self.lstm(x, (h0, c0))
|
|
|
50 |
out = self.fc(out[:, -1, :])
|
51 |
return out
|
52 |
|
53 |
+
# Initialize model, optimizer, and loss function
|
54 |
+
input_dim = 6
|
55 |
+
hidden_dim = 128
|
56 |
+
output_dim = 1
|
57 |
+
seq_len = 10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
|
59 |
+
model = LSTMModel(input_dim=input_dim, hidden_dim=hidden_dim, output_dim=output_dim)
|
60 |
+
optimizer = optim.Adam(model.parameters(), lr=0.001)
|
61 |
+
criterion = nn.MSELoss()
|
62 |
+
|
63 |
+
# Split the data into training and validation sets
|
64 |
+
train_data, val_data = train_test_split(data, test_size=0.2, random_state=42)
|
65 |
+
|
66 |
+
train_dataset = BankNiftyDataset(train_data, seq_len)
|
67 |
+
val_dataset = BankNiftyDataset(val_data, seq_len)
|
68 |
+
|
69 |
+
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
|
70 |
+
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)
|
71 |
+
|
72 |
+
# Function to train the model
|
73 |
+
def train_model():
|
74 |
+
model.train()
|
75 |
+
for batch in train_loader:
|
76 |
+
features, label = batch
|
77 |
+
optimizer.zero_grad()
|
78 |
output = model(features)
|
79 |
+
loss = criterion(output, label)
|
80 |
+
loss.backward()
|
81 |
+
optimizer.step()
|
82 |
|
83 |
+
# Function to evaluate the model on the validation set
|
84 |
+
def evaluate_model():
|
85 |
+
model.eval()
|
86 |
+
total_loss = 0
|
87 |
+
with torch.no_grad():
|
88 |
+
for batch in val_loader:
|
89 |
+
features, label = batch
|
90 |
+
output = model(features)
|
91 |
+
loss = criterion(output, label)
|
92 |
+
total_loss += loss.item()
|
93 |
+
return total_loss / len(val_loader)
|
94 |
+
|
95 |
+
# Function to generate a strategy based on user input
|
96 |
+
def generate_strategy(open_price, high_price, low_price, close_price, volume, oi, sma_20, sma_50, rsi):
|
97 |
+
model.eval()
|
98 |
+
|
99 |
+
input_data = torch.tensor([[open_price, high_price, low_price, close_price, volume, oi]], dtype=torch.float32)
|
100 |
+
|
101 |
+
with torch.no_grad():
|
102 |
+
output = model(input_data)
|
103 |
+
strategy = f"Predicted Close Price: {output.item():.2f}"
|
104 |
+
return strategy
|
105 |
+
|
106 |
+
# Retrain the model every week or month (depending on schedule)
|
107 |
+
def retrain_model():
|
108 |
+
# Load fresh data, scale it, and retrain the model
|
109 |
+
new_data = pd.read_csv('BANKNIFTY_OPTION_CHAIN_data.csv')
|
110 |
+
new_scaled_data = scaler.transform(new_data[['open', 'high', 'low', 'close', 'volume', 'oi']])
|
111 |
+
new_data[['open', 'high', 'low', 'close', 'volume', 'oi']] = new_scaled_data
|
112 |
+
|
113 |
+
new_train_data, new_val_data = train_test_split(new_data, test_size=0.2, random_state=42)
|
114 |
+
new_train_dataset = BankNiftyDataset(new_train_data, seq_len)
|
115 |
+
new_val_dataset = BankNiftyDataset(new_val_data, seq_len)
|
116 |
+
|
117 |
+
new_train_loader = DataLoader(new_train_dataset, batch_size=32, shuffle=True)
|
118 |
+
new_val_loader = DataLoader(new_val_dataset, batch_size=32, shuffle=False)
|
119 |
+
|
120 |
+
# Training on new data
|
121 |
+
model.train()
|
122 |
+
for epoch in range(5): # Train for 5 epochs
|
123 |
+
for batch in new_train_loader:
|
124 |
+
features, label = batch
|
125 |
+
optimizer.zero_grad()
|
126 |
+
output = model(features)
|
127 |
+
loss = criterion(output, label)
|
128 |
+
loss.backward()
|
129 |
+
optimizer.step()
|
130 |
+
|
131 |
+
# Save the retrained model
|
132 |
+
torch.save(model.state_dict(), 'retrained_model.pth')
|
133 |
+
|
134 |
+
# Scheduler for automatic retraining
|
135 |
+
scheduler = BackgroundScheduler()
|
136 |
+
scheduler.add_job(retrain_model, 'interval', weeks=1) # Schedule weekly retraining
|
137 |
+
scheduler.start()
|
138 |
+
|
139 |
+
# Gradio interface
|
140 |
inputs = [
|
141 |
+
gr.components.Number(label="Open Price"),
|
142 |
+
gr.components.Number(label="High Price"),
|
143 |
+
gr.components.Number(label="Low Price"),
|
144 |
+
gr.components.Number(label="Close Price"),
|
145 |
+
gr.components.Number(label="Volume"),
|
146 |
+
gr.components.Number(label="Open Interest"),
|
147 |
+
gr.components.Number(label="SMA 20"),
|
148 |
+
gr.components.Number(label="SMA 50"),
|
149 |
+
gr.components.Number(label="RSI")
|
150 |
]
|
151 |
|
152 |
+
outputs = gr.components.Textbox(label="Predicted Strategy")
|
153 |
|
154 |
+
# Launch Gradio interface
|
155 |
gr.Interface(fn=generate_strategy, inputs=inputs, outputs=outputs, title="BankNifty Strategy Generator").launch()
|
156 |
|
|
|
|
|
|