Upload 2 files
Browse files
app1.py
ADDED
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import Flask, request, jsonify
|
2 |
+
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
+
from sklearn.preprocessing import MinMaxScaler
|
5 |
+
from sklearn.model_selection import train_test_split
|
6 |
+
from tensorflow.keras.models import Sequential, load_model
|
7 |
+
from tensorflow.keras.layers import LSTM, Dense
|
8 |
+
from tensorflow.keras.optimizers import Adam
|
9 |
+
import os
|
10 |
+
|
11 |
+
np.seterr(invalid='ignore') # Ignore invalid (NaN) values
|
12 |
+
from flask_cors import CORS # Add this import
|
13 |
+
app = Flask(__name__)
|
14 |
+
CORS(app)
|
15 |
+
|
16 |
+
# Load and prepare the data
|
17 |
+
df = pd.read_csv('complete_data.csv')
|
18 |
+
df['Date'] = pd.to_datetime(df['Date'], format='mixed')
|
19 |
+
df = df.sort_values(['Company', 'Date'])
|
20 |
+
|
21 |
+
# Create target variable (1 if price went up, 0 if down)
|
22 |
+
df['Target'] = (df.groupby('Company')['Close'].shift(-1) > df['Close']).astype(int)
|
23 |
+
|
24 |
+
# Select features for the model
|
25 |
+
features = ['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume', 'Sentiment']
|
26 |
+
|
27 |
+
# Handle null values
|
28 |
+
def handle_nulls(group):
|
29 |
+
for feature in features:
|
30 |
+
if group[feature].isnull().any():
|
31 |
+
group[feature] = group[feature].fillna(group[feature].median())
|
32 |
+
return group
|
33 |
+
|
34 |
+
df = df.groupby('Company').apply(handle_nulls).reset_index(drop=True)
|
35 |
+
|
36 |
+
# Normalize the features
|
37 |
+
scaler = MinMaxScaler()
|
38 |
+
df[features] = scaler.fit_transform(df[features])
|
39 |
+
|
40 |
+
# Function to create sequences
|
41 |
+
def create_sequences(data, seq_length):
|
42 |
+
X, y = [], []
|
43 |
+
for i in range(len(data) - seq_length):
|
44 |
+
X.append(data.iloc[i:(i + seq_length)][features].values)
|
45 |
+
y.append(data.iloc[i + seq_length]['Target'])
|
46 |
+
return np.array(X), np.array(y)
|
47 |
+
|
48 |
+
# Prepare data for each company
|
49 |
+
sequence_length = 10 # You can adjust this
|
50 |
+
company_models = {}
|
51 |
+
models_dir = 'models'
|
52 |
+
|
53 |
+
if not os.path.exists(models_dir):
|
54 |
+
os.makedirs(models_dir)
|
55 |
+
|
56 |
+
def load_company_models():
|
57 |
+
for file in os.listdir(models_dir):
|
58 |
+
if file.endswith('.h5'):
|
59 |
+
company = file.split('.h5')[0]
|
60 |
+
model_path = os.path.join(models_dir, file)
|
61 |
+
company_models[company] = load_model(model_path)
|
62 |
+
|
63 |
+
# Load the models when the app starts
|
64 |
+
load_company_models()
|
65 |
+
|
66 |
+
for company in df['Company'].unique():
|
67 |
+
if pd.isna(company):
|
68 |
+
print("Skipping NaN company name")
|
69 |
+
continue
|
70 |
+
|
71 |
+
print(f"Processing company: {company}")
|
72 |
+
company_data = df[df['Company'] == company]
|
73 |
+
print(f"Company data shape: {company_data.shape}")
|
74 |
+
|
75 |
+
if len(company_data) <= sequence_length:
|
76 |
+
print(f"Skipping {company} due to insufficient data")
|
77 |
+
continue
|
78 |
+
|
79 |
+
model_path = os.path.join(models_dir, f'{company}.h5')
|
80 |
+
|
81 |
+
if os.path.exists(model_path):
|
82 |
+
print(f"Loading existing model for {company}")
|
83 |
+
company_models[company] = load_model(model_path)
|
84 |
+
else:
|
85 |
+
try:
|
86 |
+
X, y = create_sequences(company_data, sequence_length)
|
87 |
+
print(f"Sequences created. X shape: {X.shape}, y shape: {y.shape}")
|
88 |
+
|
89 |
+
# Split into train and test sets
|
90 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
91 |
+
|
92 |
+
# Create and compile the model
|
93 |
+
model = Sequential([
|
94 |
+
LSTM(50, activation='relu', input_shape=(sequence_length, len(features))),
|
95 |
+
Dense(1, activation='sigmoid')
|
96 |
+
])
|
97 |
+
model.compile(optimizer=Adam(learning_rate=0.001), loss='binary_crossentropy', metrics=['accuracy'])
|
98 |
+
|
99 |
+
# Train the model
|
100 |
+
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_split=0.1, verbose=0)
|
101 |
+
|
102 |
+
# Evaluate the model
|
103 |
+
loss, accuracy = model.evaluate(X_test, y_test, verbose=0)
|
104 |
+
print(f"{company} - Test Accuracy: {accuracy:.4f}")
|
105 |
+
|
106 |
+
# Save the model
|
107 |
+
model.save(model_path)
|
108 |
+
|
109 |
+
company_models[company] = model
|
110 |
+
|
111 |
+
except Exception as e:
|
112 |
+
print(f"Error processing {company}: {str(e)}")
|
113 |
+
continue
|
114 |
+
|
115 |
+
def predict_stock_movement(company, latest_data):
|
116 |
+
if company not in company_models:
|
117 |
+
return "Company not found in the dataset."
|
118 |
+
|
119 |
+
model = company_models[company]
|
120 |
+
|
121 |
+
# Ensure we're only using the specified features
|
122 |
+
latest_data_features = latest_data[features]
|
123 |
+
|
124 |
+
# Scale the data
|
125 |
+
latest_data_scaled = scaler.transform(latest_data_features)
|
126 |
+
|
127 |
+
# Reshape for LSTM input (samples, time steps, features)
|
128 |
+
sequence = latest_data_scaled.reshape(1, sequence_length, len(features))
|
129 |
+
|
130 |
+
prediction = model.predict(sequence)[0, 0]
|
131 |
+
|
132 |
+
return "Up" if prediction > 0.51 else "Down"
|
133 |
+
|
134 |
+
@app.route('/predict', methods=['POST'])
|
135 |
+
def predict():
|
136 |
+
data = request.json
|
137 |
+
company_name = data.get('company')
|
138 |
+
|
139 |
+
if not company_name:
|
140 |
+
return jsonify({"error": "Company name is required"}), 400
|
141 |
+
|
142 |
+
latest_data = df[df['Company'] == company_name].tail(sequence_length)
|
143 |
+
|
144 |
+
if latest_data.empty:
|
145 |
+
return jsonify({"error": "Company not found or insufficient data"}), 404
|
146 |
+
|
147 |
+
prediction = predict_stock_movement(company_name, latest_data)
|
148 |
+
return jsonify({"company": company_name, "prediction": prediction})
|
149 |
+
|
150 |
+
if __name__ == '__main__':
|
151 |
+
app.run(debug=True)
|
app2.py
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import Flask, request, jsonify
|
2 |
+
import joblib
|
3 |
+
import pandas as pd
|
4 |
+
|
5 |
+
|
6 |
+
|
7 |
+
# Load the model
|
8 |
+
model = joblib.load('investment_model.pkl')
|
9 |
+
|
10 |
+
from flask_cors import CORS # Add this import
|
11 |
+
app = Flask(__name__)
|
12 |
+
CORS(app)
|
13 |
+
def get_investment_advice(model, user_inputs):
|
14 |
+
user_data = pd.DataFrame([user_inputs])
|
15 |
+
|
16 |
+
# Make prediction using the model
|
17 |
+
predictions = model.predict(user_data)
|
18 |
+
advice = predictions[0]
|
19 |
+
return advice
|
20 |
+
|
21 |
+
@app.route('/predict/stock', methods=['POST'])
|
22 |
+
def predict():
|
23 |
+
try:
|
24 |
+
data = request.get_json()
|
25 |
+
user_inputs = {
|
26 |
+
'Age_Group': data['Age_Group'],
|
27 |
+
'Risk_Level': data['Risk_Level'],
|
28 |
+
'Amount_to_Invest': data['Amount_to_Invest'],
|
29 |
+
'Investment_Term': data['Investment_Term'],
|
30 |
+
'Diversity_Option': data['Diversity_Option']
|
31 |
+
}
|
32 |
+
advice = get_investment_advice(model, user_inputs)
|
33 |
+
return jsonify({'Investment Advice': advice})
|
34 |
+
except Exception as e:
|
35 |
+
print(f"Error: {e}")
|
36 |
+
return jsonify({'error': 'An error occurred'}), 500
|
37 |
+
|
38 |
+
|
39 |
+
if __name__ == '__main__':
|
40 |
+
app.run(debug=True, port=5002)
|