nivakaran commited on
Commit
c70bd78
·
verified ·
1 Parent(s): 01d0ae1

Upload folder using huggingface_hub

Browse files
frontend/app/components/dashboard/StockPredictions.tsx CHANGED
@@ -89,7 +89,7 @@ const StockPredictions = () => {
89
  <div className="flex items-center justify-between mb-4">
90
  <div className="flex items-center gap-2">
91
  <Activity className="w-5 h-5 text-success" />
92
- <h2 className="text-lg font-bold">STOCK PREDICTIONS - ML MODELS</h2>
93
  </div>
94
  <div className="flex items-center gap-2">
95
  <button
@@ -165,7 +165,7 @@ const StockPredictions = () => {
165
  </div>
166
  <div className="text-right">
167
  <div className="font-mono text-lg">
168
- ${stock.predicted_price?.toFixed(2) || '---'}
169
  </div>
170
  <div className={`text-sm font-mono ${stock.expected_change_pct >= 0 ? 'text-green-400' : 'text-red-400'}`}>
171
  {stock.expected_change_pct >= 0 ? '+' : ''}{stock.expected_change_pct?.toFixed(2) || '0.00'}%
 
89
  <div className="flex items-center justify-between mb-4">
90
  <div className="flex items-center gap-2">
91
  <Activity className="w-5 h-5 text-success" />
92
+ <h2 className="text-lg font-bold">CSE STOCK PREDICTIONS 🇱🇰</h2>
93
  </div>
94
  <div className="flex items-center gap-2">
95
  <button
 
165
  </div>
166
  <div className="text-right">
167
  <div className="font-mono text-lg">
168
+ LKR {stock.predicted_price?.toFixed(2) || '---'}
169
  </div>
170
  <div className={`text-sm font-mono ${stock.expected_change_pct >= 0 ? 'text-green-400' : 'text-red-400'}`}>
171
  {stock.expected_change_pct >= 0 ? '+' : ''}{stock.expected_change_pct?.toFixed(2) || '0.00'}%
main.py CHANGED
@@ -15,7 +15,7 @@ from pydantic import BaseModel
15
  from typing import Dict, Any, List, Set, Optional
16
  import asyncio
17
  import json
18
- from datetime import datetime
19
  import sys
20
  import os
21
  import logging
 
15
  from typing import Dict, Any, List, Set, Optional
16
  import asyncio
17
  import json
18
+ from datetime import datetime, timedelta
19
  import sys
20
  import os
21
  import logging
models/stock-price-prediction/README.md CHANGED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Stock Price Prediction Module 🇱🇰
2
+
3
+ BiLSTM-based stock price prediction for **10 Sri Lankan CSE stocks**.
4
+
5
+ ## Stocks Covered
6
+
7
+ | Symbol | Company | Sector |
8
+ |--------|---------|--------|
9
+ | COMB | Commercial Bank of Ceylon PLC | Banking |
10
+ | JKH | John Keells Holdings PLC | Diversified Holdings |
11
+ | SAMP | Sampath Bank PLC | Banking |
12
+ | HNB | Hatton National Bank PLC | Banking |
13
+ | DIAL | Dialog Axiata PLC | Telecommunications |
14
+ | CTC | Ceylon Tobacco Company PLC | Consumer Goods |
15
+ | NEST | Nestle Lanka PLC | Consumer Goods |
16
+ | CARG | Cargills Ceylon PLC | Retail |
17
+ | HNBA | HNB Assurance PLC | Insurance |
18
+ | CARS | Carson Cumberbatch PLC | Diversified Holdings |
19
+
20
+ ## ⚠️ Important Note
21
+
22
+ **Yahoo Finance does NOT support CSE (Colombo Stock Exchange) tickers directly.**
23
+
24
+ The module uses fallback predictions with simulated market data. For real CSE data, integrate with:
25
+ - CSE official API
26
+ - Bloomberg Terminal
27
+ - Reuters/Refinitiv
28
+
29
+ ## Architecture
30
+
31
+ - **Model**: Bidirectional LSTM (BiLSTM)
32
+ - **Epochs**: 10 (configurable)
33
+ - **Sequence Length**: 60 days
34
+ - **Features**: Close price, technical indicators
35
+ - **Tracking**: MLflow + DagsHub
36
+
37
+ ## Quick Start
38
+
39
+ ```bash
40
+ # Train all 10 stocks
41
+ cd models/stock-price-prediction
42
+ python main.py
43
+
44
+ # Test predictor
45
+ python src/components/predictor.py
46
+ ```
47
+
48
+ ## API Endpoints
49
+
50
+ | Endpoint | Description |
51
+ |----------|-------------|
52
+ | `GET /api/stocks/predictions` | All 10 stock predictions |
53
+ | `GET /api/stocks/predictions/{symbol}` | Single stock (COMB, JKH, etc.) |
54
+ | `GET /api/stocks/model/status` | Model training status |
55
+
56
+ ## Output
57
+
58
+ Predictions include:
59
+ - Current price (LKR)
60
+ - Predicted next-day price
61
+ - Expected change %
62
+ - Trend (bullish/bearish/neutral)
63
+ - Confidence score
64
+
65
+ ## Directory Structure
66
+
67
+ ```
68
+ stock-price-prediction/
69
+ ├── main.py # Multi-stock training entry
70
+ ├── src/
71
+ │ ├── components/
72
+ │ │ ├── data_ingestion.py
73
+ │ │ ├── data_validation.py
74
+ │ │ ├── data_transformation.py
75
+ │ │ ├── model_trainer.py
76
+ │ │ └── predictor.py # Inference API
77
+ │ └── constants/
78
+ │ └── training_pipeline/
79
+ ├── Artifacts/ # Trained models
80
+ └── output/predictions/ # JSON predictions
81
+ ```
82
+
83
+ ## Airflow DAG
84
+
85
+ Schedule: **4:15 AM IST daily** (via centralized `airflow/dags/stock_prediction_dag.py`)
models/stock-price-prediction/src/components/predictor.py CHANGED
@@ -97,17 +97,25 @@ class StockPredictor:
97
  """Generate a fallback prediction when model is not available."""
98
  stock_info = STOCKS_TO_TRAIN.get(stock_code, {"name": stock_code, "sector": "Unknown"})
99
 
100
- # Simulated current price (would normally fetch from Yahoo Finance)
101
- np.random.seed(hash(stock_code) % 2**31)
102
- base_prices = {
103
- "AAPL": 175.0, "GOOGL": 140.0, "MSFT": 380.0, "AMZN": 180.0,
104
- "META": 500.0, "NVDA": 480.0, "TSLA": 250.0, "JPM": 190.0,
105
- "V": 275.0, "JNJ": 155.0
 
 
 
 
 
 
 
 
106
  }
107
- current_price = base_prices.get(stock_code, 100.0) * (1 + np.random.uniform(-0.05, 0.05))
108
 
109
  # Generate prediction with slight randomized movement
110
- change_pct = np.random.normal(0.1, 1.0) # Mean +0.1%, std 1%
111
  predicted_price = current_price * (1 + change_pct / 100)
112
 
113
  # Determine trend
@@ -125,6 +133,8 @@ class StockPredictor:
125
  "symbol": stock_code,
126
  "name": stock_info.get("name", stock_code),
127
  "sector": stock_info.get("sector", "Unknown"),
 
 
128
  "current_price": round(current_price, 2),
129
  "predicted_price": round(predicted_price, 2),
130
  "expected_change": round(predicted_price - current_price, 2),
@@ -134,7 +144,7 @@ class StockPredictor:
134
  "confidence": round(np.random.uniform(0.65, 0.85), 2),
135
  "model_architecture": "BiLSTM",
136
  "is_fallback": True,
137
- "note": "Using fallback predictions - train models for accurate forecasts"
138
  }
139
 
140
  def predict_stock(self, stock_code: str) -> Dict[str, Any]:
 
97
  """Generate a fallback prediction when model is not available."""
98
  stock_info = STOCKS_TO_TRAIN.get(stock_code, {"name": stock_code, "sector": "Unknown"})
99
 
100
+ # Realistic CSE stock prices in LKR (Sri Lankan Rupees)
101
+ # Based on typical market cap leaders on CSE
102
+ np.random.seed(hash(stock_code + datetime.now().strftime("%Y%m%d")) % 2**31)
103
+ base_prices_lkr = {
104
+ "COMB": 95.0, # Commercial Bank ~95 LKR
105
+ "JKH": 175.0, # John Keells Holdings ~175 LKR
106
+ "SAMP": 68.0, # Sampath Bank ~68 LKR
107
+ "HNB": 155.0, # Hatton National Bank ~155 LKR
108
+ "DIAL": 12.0, # Dialog Axiata ~12 LKR
109
+ "CTC": 1100.0, # Ceylon Tobacco ~1100 LKR
110
+ "NEST": 1450.0, # Nestle Lanka ~1450 LKR
111
+ "CARG": 215.0, # Cargills Ceylon ~215 LKR
112
+ "HNBA": 42.0, # HNB Assurance ~42 LKR
113
+ "CARS": 285.0, # Carson Cumberbatch ~285 LKR
114
  }
115
+ current_price = base_prices_lkr.get(stock_code, 100.0) * (1 + np.random.uniform(-0.03, 0.03))
116
 
117
  # Generate prediction with slight randomized movement
118
+ change_pct = np.random.normal(0.15, 1.5) # Mean +0.15%, std 1.5%
119
  predicted_price = current_price * (1 + change_pct / 100)
120
 
121
  # Determine trend
 
133
  "symbol": stock_code,
134
  "name": stock_info.get("name", stock_code),
135
  "sector": stock_info.get("sector", "Unknown"),
136
+ "exchange": stock_info.get("exchange", "CSE"),
137
+ "currency": "LKR",
138
  "current_price": round(current_price, 2),
139
  "predicted_price": round(predicted_price, 2),
140
  "expected_change": round(predicted_price - current_price, 2),
 
144
  "confidence": round(np.random.uniform(0.65, 0.85), 2),
145
  "model_architecture": "BiLSTM",
146
  "is_fallback": True,
147
+ "note": "CSE data via fallback - Yahoo Finance doesn't support CSE tickers"
148
  }
149
 
150
  def predict_stock(self, stock_code: str) -> Dict[str, Any]:
models/stock-price-prediction/src/constants/training_pipeline/__init__.py CHANGED
@@ -5,64 +5,75 @@ import numpy as np
5
  Defining common constant variable for training pipeline
6
  """
7
 
8
- # Stocks available on Yahoo Finance for training
9
- # NOTE: CSE (Sri Lanka) tickers are NOT available on Yahoo Finance
10
- # Using globally available tickers instead
 
11
  STOCKS_TO_TRAIN = {
12
- "AAPL": {
13
- "yahoo_symbol": "AAPL",
14
- "name": "Apple Inc.",
15
- "sector": "Technology"
 
16
  },
17
- "GOOGL": {
18
- "yahoo_symbol": "GOOGL",
19
- "name": "Alphabet Inc.",
20
- "sector": "Technology"
 
21
  },
22
- "MSFT": {
23
- "yahoo_symbol": "MSFT",
24
- "name": "Microsoft Corporation",
25
- "sector": "Technology"
 
26
  },
27
- "AMZN": {
28
- "yahoo_symbol": "AMZN",
29
- "name": "Amazon.com Inc.",
30
- "sector": "Consumer Discretionary"
 
31
  },
32
- "META": {
33
- "yahoo_symbol": "META",
34
- "name": "Meta Platforms Inc.",
35
- "sector": "Technology"
 
36
  },
37
- "NVDA": {
38
- "yahoo_symbol": "NVDA",
39
- "name": "NVIDIA Corporation",
40
- "sector": "Technology"
 
41
  },
42
- "TSLA": {
43
- "yahoo_symbol": "TSLA",
44
- "name": "Tesla Inc.",
45
- "sector": "Automotive"
 
46
  },
47
- "JPM": {
48
- "yahoo_symbol": "JPM",
49
- "name": "JPMorgan Chase & Co.",
50
- "sector": "Financial Services"
 
51
  },
52
- "V": {
53
- "yahoo_symbol": "V",
54
- "name": "Visa Inc.",
55
- "sector": "Financial Services"
 
56
  },
57
- "JNJ": {
58
- "yahoo_symbol": "JNJ",
59
- "name": "Johnson & Johnson",
60
- "sector": "Healthcare"
 
61
  }
62
  }
63
 
64
  # Default stock for single-stock training mode
65
- DEFAULT_STOCK = "AAPL"
66
 
67
  # Legacy alias for backward compatibility
68
  SRI_LANKA_STOCKS = STOCKS_TO_TRAIN
 
5
  Defining common constant variable for training pipeline
6
  """
7
 
8
+ # Top 10 Sri Lankan Stocks by market cap (CSE - Colombo Stock Exchange)
9
+ # NOTE: Yahoo Finance does NOT support CSE tickers directly.
10
+ # These stocks will use fallback predictions with simulated market data.
11
+ # For real CSE data, integrate with CSE API or data providers like Bloomberg.
12
  STOCKS_TO_TRAIN = {
13
+ "COMB": {
14
+ "yahoo_symbol": "COMB.N0000", # Commercial Bank of Ceylon
15
+ "name": "Commercial Bank of Ceylon PLC",
16
+ "sector": "Banking",
17
+ "exchange": "CSE"
18
  },
19
+ "JKH": {
20
+ "yahoo_symbol": "JKH.N0000", # John Keells Holdings
21
+ "name": "John Keells Holdings PLC",
22
+ "sector": "Diversified Holdings",
23
+ "exchange": "CSE"
24
  },
25
+ "SAMP": {
26
+ "yahoo_symbol": "SAMP.N0000", # Sampath Bank
27
+ "name": "Sampath Bank PLC",
28
+ "sector": "Banking",
29
+ "exchange": "CSE"
30
  },
31
+ "HNB": {
32
+ "yahoo_symbol": "HNB.N0000", # Hatton National Bank
33
+ "name": "Hatton National Bank PLC",
34
+ "sector": "Banking",
35
+ "exchange": "CSE"
36
  },
37
+ "DIAL": {
38
+ "yahoo_symbol": "DIAL.N0000", # Dialog Axiata
39
+ "name": "Dialog Axiata PLC",
40
+ "sector": "Telecommunications",
41
+ "exchange": "CSE"
42
  },
43
+ "CTC": {
44
+ "yahoo_symbol": "CTC.N0000", # Ceylon Tobacco
45
+ "name": "Ceylon Tobacco Company PLC",
46
+ "sector": "Consumer Goods",
47
+ "exchange": "CSE"
48
  },
49
+ "NEST": {
50
+ "yahoo_symbol": "NEST.N0000", # Nestle Lanka
51
+ "name": "Nestle Lanka PLC",
52
+ "sector": "Consumer Goods",
53
+ "exchange": "CSE"
54
  },
55
+ "CARG": {
56
+ "yahoo_symbol": "CARG.N0000", # Cargills Ceylon
57
+ "name": "Cargills Ceylon PLC",
58
+ "sector": "Retail",
59
+ "exchange": "CSE"
60
  },
61
+ "HNBA": {
62
+ "yahoo_symbol": "HNBA.N0000", # HNB Assurance
63
+ "name": "HNB Assurance PLC",
64
+ "sector": "Insurance",
65
+ "exchange": "CSE"
66
  },
67
+ "CARS": {
68
+ "yahoo_symbol": "CARS.N0000", # Carson Cumberbatch
69
+ "name": "Carson Cumberbatch PLC",
70
+ "sector": "Diversified Holdings",
71
+ "exchange": "CSE"
72
  }
73
  }
74
 
75
  # Default stock for single-stock training mode
76
+ DEFAULT_STOCK = "COMB"
77
 
78
  # Legacy alias for backward compatibility
79
  SRI_LANKA_STOCKS = STOCKS_TO_TRAIN