Jitendra12421 commited on
Commit
e7e9c65
·
verified ·
1 Parent(s): 93d68ca

Upload 4 files

Browse files
Files changed (2) hide show
  1. forecaster_engine.py +87 -51
  2. predictions.json +106 -106
forecaster_engine.py CHANGED
@@ -3,10 +3,19 @@ import json
3
  import pandas as pd
4
  import numpy as np
5
  from datetime import datetime
 
 
6
 
7
  DATA_FILE = os.path.join(os.path.dirname(__file__), "data", "nifty50_daily.parquet")
8
  PREDICTIONS_FILE = os.path.join(os.path.dirname(__file__), "predictions.json")
9
 
 
 
 
 
 
 
 
10
  def generate_predictions():
11
  if not os.path.exists(DATA_FILE):
12
  print(f"Data file missing: {DATA_FILE}")
@@ -23,11 +32,10 @@ def generate_predictions():
23
  df.sort_values('date', inplace=True)
24
  df.set_index('date', inplace=True)
25
 
26
- if len(df) < 130:
27
  continue
28
 
29
  forecast_date_ts = df.index[-1] + pd.Timedelta(days=1)
30
- # Advance past weekends roughly for display
31
  if forecast_date_ts.weekday() >= 5:
32
  forecast_date_ts += pd.Timedelta(days=(7 - forecast_date_ts.weekday()))
33
 
@@ -35,64 +43,85 @@ def generate_predictions():
35
  forecast_date = forecast_date_ts.strftime('%Y-%m-%d')
36
 
37
  daily_close = df['close']
 
 
38
 
39
- # Features
40
- delta = daily_close.diff()
41
- gain = (delta.where(delta > 0, 0)).rolling(window=2).mean()
42
- loss = (-delta.where(delta < 0, 0)).rolling(window=2).mean()
43
- rs = gain / loss
44
- rsi_2 = 100 - (100 / (1 + rs))
45
-
46
- sma_3 = daily_close.rolling(window=3).mean()
47
- dist_sma3 = daily_close / sma_3
48
-
49
- sma_5 = daily_close.rolling(window=5).mean()
50
- dist_sma5 = daily_close / sma_5
51
-
52
- df_eval = pd.DataFrame({
53
- 'close': daily_close,
54
- 'rsi_2': rsi_2,
55
- 'dist_sma3': dist_sma3,
56
- 'dist_sma5': dist_sma5,
57
- '1d_ret': daily_close.pct_change()
58
- }).dropna()
59
 
 
 
 
60
  # Target for historical testing
61
- df_eval['actual_dir'] = np.where(df_eval['close'].shift(-1) > df_eval['close'], 1, -1)
62
 
63
- # The last row is TODAY. We don't have tomorrow's close, so actual_dir is wrong for the last row.
64
- # We test on the 120 days BEFORE today
65
- test_set = df_eval.iloc[-121:-1]
66
- today_data = df_eval.iloc[-1]
67
 
68
  best_acc = 0
69
  best_rule = None
70
 
71
- # 1. RSI-2 threshold
72
- for thresh in [10, 20, 30, 40, 50, 60, 70, 80, 90]:
73
- for op in ['<', '>']:
74
- sig = np.where(test_set['rsi_2'] < thresh if op == '<' else test_set['rsi_2'] > thresh, 1, -1)
75
- acc = (sig == test_set['actual_dir']).mean()
76
- if acc > best_acc:
77
- best_acc = acc
78
- best_rule = ('rsi_2', thresh, op)
 
 
79
 
80
- # 2. SMA distance threshold
81
- for feature in ['dist_sma3', 'dist_sma5']:
82
- for thresh in [0.95, 0.98, 1.0, 1.02, 1.05]:
83
- sig = np.where(test_set[feature] < thresh, 1, -1)
84
- acc = (sig == test_set['actual_dir']).mean()
85
- if acc > best_acc:
86
- best_acc = acc
87
- best_rule = (feature, thresh, '<')
88
 
89
- # 3. 1d return
90
- sig = np.where(test_set['1d_ret'] < 0, 1, -1)
91
- acc = (sig == test_set['actual_dir']).mean()
92
- if acc > best_acc:
93
- best_acc = acc
94
- best_rule = ('1d_ret', 0, '<')
95
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  feature, thresh, op = best_rule
97
  val = today_data[feature]
98
 
@@ -101,10 +130,16 @@ def generate_predictions():
101
  else:
102
  prediction = 1 if val > thresh else -1
103
 
 
 
 
 
 
 
104
  predictions[ticker] = {
105
  "prediction": "UP" if prediction == 1 else "DOWN",
106
  "probability": round(best_acc * 100, 2),
107
- "rule_used": f"{feature} {op} {thresh}"
108
  }
109
 
110
  # Calculate aggregate metrics
@@ -124,6 +159,7 @@ def generate_predictions():
124
  json.dump(output, f, indent=4)
125
 
126
  print(f"Generated predictions for {forecast_date}. Saved to {PREDICTIONS_FILE}")
 
127
  return output
128
 
129
  if __name__ == "__main__":
 
3
  import pandas as pd
4
  import numpy as np
5
  from datetime import datetime
6
+ import warnings
7
+ warnings.filterwarnings('ignore')
8
 
9
  DATA_FILE = os.path.join(os.path.dirname(__file__), "data", "nifty50_daily.parquet")
10
  PREDICTIONS_FILE = os.path.join(os.path.dirname(__file__), "predictions.json")
11
 
12
+ def compute_rsi(series, window):
13
+ delta = series.diff()
14
+ gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
15
+ loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
16
+ rs = gain / (loss + 1e-9)
17
+ return 100 - (100 / (1 + rs))
18
+
19
  def generate_predictions():
20
  if not os.path.exists(DATA_FILE):
21
  print(f"Data file missing: {DATA_FILE}")
 
32
  df.sort_values('date', inplace=True)
33
  df.set_index('date', inplace=True)
34
 
35
+ if len(df) < 150:
36
  continue
37
 
38
  forecast_date_ts = df.index[-1] + pd.Timedelta(days=1)
 
39
  if forecast_date_ts.weekday() >= 5:
40
  forecast_date_ts += pd.Timedelta(days=(7 - forecast_date_ts.weekday()))
41
 
 
43
  forecast_date = forecast_date_ts.strftime('%Y-%m-%d')
44
 
45
  daily_close = df['close']
46
+ df_feat = pd.DataFrame(index=df.index)
47
+ df_feat['close'] = daily_close
48
 
49
+ # Massive Feature Set
50
+ for w in [2, 3, 5, 7, 14]:
51
+ df_feat[f'rsi_{w}'] = compute_rsi(daily_close, w)
52
+
53
+ for w in [3, 5, 10, 20]:
54
+ df_feat[f'dist_sma_{w}'] = daily_close / daily_close.rolling(w).mean()
55
+
56
+ for lag in [1, 2, 3, 5]:
57
+ df_feat[f'ret_{lag}d'] = daily_close.pct_change(lag)
58
+
59
+ df_feat.replace([np.inf, -np.inf], np.nan, inplace=True)
60
+ df_feat = df_feat.dropna()
 
 
 
 
 
 
 
 
61
 
62
+ if len(df_feat) < 130:
63
+ continue
64
+
65
  # Target for historical testing
66
+ df_feat['actual_dir'] = np.where(df_feat['close'].shift(-1) > df_feat['close'], 1, -1)
67
 
68
+ # Test on 120 days BEFORE today to find the best rule
69
+ test_set = df_feat.iloc[-121:-1]
70
+ today_data = df_feat.iloc[-1]
 
71
 
72
  best_acc = 0
73
  best_rule = None
74
 
75
+ # --- MASSIVE GRID SEARCH ---
76
+ # 1. RSI Rules
77
+ for w in [2, 3, 5, 7, 14]:
78
+ feat = f'rsi_{w}'
79
+ for thresh in range(10, 92, 2):
80
+ sig_lt = np.where(test_set[feat] < thresh, 1, -1)
81
+ acc_lt = (sig_lt == test_set['actual_dir']).mean()
82
+ if acc_lt > best_acc:
83
+ best_acc = acc_lt
84
+ best_rule = (feat, thresh, '<')
85
 
86
+ sig_gt = np.where(test_set[feat] > thresh, 1, -1)
87
+ acc_gt = (sig_gt == test_set['actual_dir']).mean()
88
+ if acc_gt > best_acc:
89
+ best_acc = acc_gt
90
+ best_rule = (feat, thresh, '>')
 
 
 
91
 
92
+ # 2. SMA Distance Rules
93
+ for w in [3, 5, 10, 20]:
94
+ feat = f'dist_sma_{w}'
95
+ for thresh in np.arange(0.85, 1.15, 0.005):
96
+ sig_lt = np.where(test_set[feat] < thresh, 1, -1)
97
+ acc_lt = (sig_lt == test_set['actual_dir']).mean()
98
+ if acc_lt > best_acc:
99
+ best_acc = acc_lt
100
+ best_rule = (feat, thresh, '<')
101
+
102
+ sig_gt = np.where(test_set[feat] > thresh, 1, -1)
103
+ acc_gt = (sig_gt == test_set['actual_dir']).mean()
104
+ if acc_gt > best_acc:
105
+ best_acc = acc_gt
106
+ best_rule = (feat, thresh, '>')
107
+
108
+ # 3. Return Rules
109
+ for lag in [1, 2, 3, 5]:
110
+ feat = f'ret_{lag}d'
111
+ for thresh in np.arange(-0.05, 0.052, 0.0025):
112
+ sig_lt = np.where(test_set[feat] < thresh, 1, -1)
113
+ acc_lt = (sig_lt == test_set['actual_dir']).mean()
114
+ if acc_lt > best_acc:
115
+ best_acc = acc_lt
116
+ best_rule = (feat, thresh, '<')
117
+
118
+ sig_gt = np.where(test_set[feat] > thresh, 1, -1)
119
+ acc_gt = (sig_gt == test_set['actual_dir']).mean()
120
+ if acc_gt > best_acc:
121
+ best_acc = acc_gt
122
+ best_rule = (feat, thresh, '>')
123
+
124
+ # Apply the best rule found on test_set to TODAY
125
  feature, thresh, op = best_rule
126
  val = today_data[feature]
127
 
 
130
  else:
131
  prediction = 1 if val > thresh else -1
132
 
133
+ # Format rule for display
134
+ if 'dist_sma' in feature or 'ret_' in feature:
135
+ rule_str = f"{feature} {op} {thresh:.4f}"
136
+ else:
137
+ rule_str = f"{feature} {op} {thresh}"
138
+
139
  predictions[ticker] = {
140
  "prediction": "UP" if prediction == 1 else "DOWN",
141
  "probability": round(best_acc * 100, 2),
142
+ "rule_used": rule_str
143
  }
144
 
145
  # Calculate aggregate metrics
 
159
  json.dump(output, f, indent=4)
160
 
161
  print(f"Generated predictions for {forecast_date}. Saved to {PREDICTIONS_FILE}")
162
+ print(f"Overall Test Accuracy: {mean_accuracy}%")
163
  return output
164
 
165
  if __name__ == "__main__":
predictions.json CHANGED
@@ -1,53 +1,53 @@
1
  {
2
- "generated_at": "2026-06-18T17:42:45.810183",
3
  "forecast_date": "2026-06-19",
4
- "mean_accuracy": 57.62,
5
- "median_accuracy": 57.5,
6
  "predictions": {
7
  "ADANIENT": {
8
  "prediction": "DOWN",
9
- "probability": 55.83,
10
- "rule_used": "rsi_2 < 10"
11
  },
12
  "ADANIPORTS": {
13
  "prediction": "DOWN",
14
- "probability": 57.5,
15
- "rule_used": "dist_sma5 < 1.0"
16
  },
17
  "APOLLOHOSP": {
18
- "prediction": "DOWN",
19
- "probability": 56.67,
20
- "rule_used": "rsi_2 > 10"
21
  },
22
  "ASIANPAINT": {
23
  "prediction": "DOWN",
24
- "probability": 55.0,
25
- "rule_used": "dist_sma5 < 0.95"
26
  },
27
  "AXISBANK": {
28
  "prediction": "DOWN",
29
- "probability": 59.17,
30
- "rule_used": "rsi_2 > 90"
31
  },
32
  "BAJAJ-AUTO": {
33
- "prediction": "DOWN",
34
- "probability": 57.5,
35
- "rule_used": "rsi_2 < 40"
36
  },
37
  "BAJAJFINSV": {
38
  "prediction": "DOWN",
39
- "probability": 55.0,
40
- "rule_used": "rsi_2 < 20"
41
  },
42
  "BAJFINANCE": {
43
  "prediction": "DOWN",
44
- "probability": 55.83,
45
- "rule_used": "dist_sma5 < 1.0"
46
  },
47
  "BHARTIARTL": {
48
  "prediction": "DOWN",
49
- "probability": 55.0,
50
- "rule_used": "rsi_2 < 20"
51
  },
52
  "BPCL": {
53
  "prediction": "DOWN",
@@ -55,194 +55,194 @@
55
  "rule_used": "rsi_2 < 10"
56
  },
57
  "BRITANNIA": {
58
- "prediction": "DOWN",
59
- "probability": 54.17,
60
- "rule_used": "rsi_2 < 70"
61
  },
62
  "CIPLA": {
63
  "prediction": "DOWN",
64
- "probability": 57.5,
65
- "rule_used": "dist_sma3 < 0.95"
66
  },
67
  "COALINDIA": {
68
- "prediction": "DOWN",
69
- "probability": 57.5,
70
- "rule_used": "rsi_2 < 30"
71
  },
72
  "DIVISLAB": {
73
  "prediction": "DOWN",
74
- "probability": 57.5,
75
- "rule_used": "dist_sma5 < 1.0"
76
  },
77
  "DRREDDY": {
78
  "prediction": "UP",
79
- "probability": 65.0,
80
- "rule_used": "rsi_2 < 60"
81
  },
82
  "EICHERMOT": {
83
- "prediction": "UP",
84
- "probability": 58.33,
85
- "rule_used": "rsi_2 < 90"
86
  },
87
  "GRASIM": {
88
  "prediction": "UP",
89
  "probability": 63.33,
90
- "rule_used": "1d_ret < 0"
91
  },
92
  "HCLTECH": {
93
  "prediction": "UP",
94
- "probability": 55.0,
95
- "rule_used": "rsi_2 > 20"
96
  },
97
  "HDFCBANK": {
98
- "prediction": "DOWN",
99
- "probability": 59.17,
100
- "rule_used": "dist_sma3 < 0.98"
101
  },
102
  "HDFCLIFE": {
103
  "prediction": "DOWN",
104
- "probability": 62.5,
105
- "rule_used": "dist_sma3 < 0.98"
106
  },
107
  "HEROMOTOCO": {
108
  "prediction": "DOWN",
109
- "probability": 55.0,
110
- "rule_used": "rsi_2 < 30"
111
  },
112
  "HINDALCO": {
113
- "prediction": "UP",
114
  "probability": 63.33,
115
- "rule_used": "dist_sma5 < 1.05"
116
  },
117
  "HINDUNILVR": {
118
  "prediction": "UP",
119
- "probability": 54.17,
120
- "rule_used": "rsi_2 > 20"
121
  },
122
  "ICICIBANK": {
123
  "prediction": "DOWN",
124
- "probability": 55.0,
125
- "rule_used": "dist_sma5 < 0.98"
126
  },
127
  "INDUSINDBK": {
128
- "prediction": "UP",
129
- "probability": 55.0,
130
- "rule_used": "rsi_2 > 70"
131
  },
132
  "INFY": {
133
  "prediction": "DOWN",
134
- "probability": 55.0,
135
- "rule_used": "dist_sma3 < 0.95"
136
  },
137
  "ITC": {
138
  "prediction": "DOWN",
139
- "probability": 56.67,
140
- "rule_used": "dist_sma3 < 0.95"
141
  },
142
  "JSWSTEEL": {
143
- "prediction": "UP",
144
- "probability": 61.67,
145
- "rule_used": "rsi_2 < 40"
146
  },
147
  "KOTAKBANK": {
148
  "prediction": "DOWN",
149
- "probability": 53.33,
150
- "rule_used": "rsi_2 < 10"
151
  },
152
  "LT": {
153
- "prediction": "DOWN",
154
  "probability": 57.5,
155
- "rule_used": "1d_ret < 0"
156
  },
157
  "LTIM": {
158
  "prediction": "UP",
159
  "probability": 60.0,
160
- "rule_used": "1d_ret < 0"
161
  },
162
  "MARUTI": {
163
  "prediction": "DOWN",
164
- "probability": 61.67,
165
- "rule_used": "rsi_2 < 40"
166
  },
167
  "MM": {
168
- "prediction": "DOWN",
169
- "probability": 55.0,
170
- "rule_used": "rsi_2 < 30"
171
  },
172
  "NESTLEIND": {
173
  "prediction": "DOWN",
174
- "probability": 57.5,
175
- "rule_used": "rsi_2 < 70"
176
  },
177
  "NTPC": {
178
  "prediction": "UP",
179
- "probability": 58.33,
180
- "rule_used": "rsi_2 < 80"
181
  },
182
  "ONGC": {
183
  "prediction": "UP",
184
- "probability": 59.17,
185
- "rule_used": "rsi_2 < 40"
186
  },
187
  "POWERGRID": {
188
  "prediction": "UP",
189
- "probability": 55.0,
190
- "rule_used": "rsi_2 > 70"
191
  },
192
  "RELIANCE": {
193
  "prediction": "DOWN",
194
- "probability": 55.0,
195
- "rule_used": "dist_sma5 < 0.98"
196
  },
197
  "SBILIFE": {
198
  "prediction": "DOWN",
199
- "probability": 60.0,
200
- "rule_used": "1d_ret < 0"
201
  },
202
  "SBIN": {
203
  "prediction": "UP",
204
- "probability": 55.83,
205
- "rule_used": "rsi_2 > 10"
206
  },
207
  "SUNPHARMA": {
208
  "prediction": "UP",
209
- "probability": 54.17,
210
- "rule_used": "rsi_2 > 60"
211
  },
212
  "TATACONSUM": {
213
- "prediction": "DOWN",
214
- "probability": 57.5,
215
- "rule_used": "dist_sma3 < 1.0"
216
  },
217
  "TATASTEEL": {
218
  "prediction": "DOWN",
219
- "probability": 56.67,
220
- "rule_used": "rsi_2 < 10"
221
  },
222
  "TCS": {
223
  "prediction": "UP",
224
- "probability": 57.5,
225
- "rule_used": "rsi_2 > 20"
226
  },
227
  "TECHM": {
228
- "prediction": "UP",
229
- "probability": 58.33,
230
- "rule_used": "dist_sma3 < 1.02"
231
  },
232
  "TITAN": {
233
  "prediction": "DOWN",
234
- "probability": 54.17,
235
- "rule_used": "rsi_2 < 40"
236
  },
237
  "ULTRACEMCO": {
238
  "prediction": "DOWN",
239
- "probability": 57.5,
240
- "rule_used": "rsi_2 < 50"
241
  },
242
  "UPL": {
243
  "prediction": "DOWN",
244
- "probability": 60.83,
245
- "rule_used": "dist_sma5 < 1.0"
246
  },
247
  "WIPRO": {
248
  "prediction": "UP",
 
1
  {
2
+ "generated_at": "2026-06-19T16:14:00.701098",
3
  "forecast_date": "2026-06-19",
4
+ "mean_accuracy": 60.88,
5
+ "median_accuracy": 60.83,
6
  "predictions": {
7
  "ADANIENT": {
8
  "prediction": "DOWN",
9
+ "probability": 58.33,
10
+ "rule_used": "dist_sma_3 < 1.0100"
11
  },
12
  "ADANIPORTS": {
13
  "prediction": "DOWN",
14
+ "probability": 61.67,
15
+ "rule_used": "ret_2d < -0.0150"
16
  },
17
  "APOLLOHOSP": {
18
+ "prediction": "UP",
19
+ "probability": 64.17,
20
+ "rule_used": "ret_1d < 0.0075"
21
  },
22
  "ASIANPAINT": {
23
  "prediction": "DOWN",
24
+ "probability": 60.0,
25
+ "rule_used": "rsi_14 < 22"
26
  },
27
  "AXISBANK": {
28
  "prediction": "DOWN",
29
+ "probability": 60.83,
30
+ "rule_used": "rsi_14 < 52"
31
  },
32
  "BAJAJ-AUTO": {
33
+ "prediction": "UP",
34
+ "probability": 60.83,
35
+ "rule_used": "rsi_7 < 76"
36
  },
37
  "BAJAJFINSV": {
38
  "prediction": "DOWN",
39
+ "probability": 61.67,
40
+ "rule_used": "rsi_14 < 44"
41
  },
42
  "BAJFINANCE": {
43
  "prediction": "DOWN",
44
+ "probability": 57.5,
45
+ "rule_used": "rsi_5 < 56"
46
  },
47
  "BHARTIARTL": {
48
  "prediction": "DOWN",
49
+ "probability": 60.83,
50
+ "rule_used": "ret_2d < -0.0125"
51
  },
52
  "BPCL": {
53
  "prediction": "DOWN",
 
55
  "rule_used": "rsi_2 < 10"
56
  },
57
  "BRITANNIA": {
58
+ "prediction": "UP",
59
+ "probability": 59.17,
60
+ "rule_used": "ret_5d > 0.0050"
61
  },
62
  "CIPLA": {
63
  "prediction": "DOWN",
64
+ "probability": 60.0,
65
+ "rule_used": "rsi_14 < 18"
66
  },
67
  "COALINDIA": {
68
+ "prediction": "UP",
69
+ "probability": 63.33,
70
+ "rule_used": "dist_sma_20 < 1.0000"
71
  },
72
  "DIVISLAB": {
73
  "prediction": "DOWN",
74
+ "probability": 60.0,
75
+ "rule_used": "rsi_5 < 44"
76
  },
77
  "DRREDDY": {
78
  "prediction": "UP",
79
+ "probability": 66.67,
80
+ "rule_used": "rsi_2 < 64"
81
  },
82
  "EICHERMOT": {
83
+ "prediction": "DOWN",
84
+ "probability": 60.83,
85
+ "rule_used": "ret_2d < -0.0100"
86
  },
87
  "GRASIM": {
88
  "prediction": "UP",
89
  "probability": 63.33,
90
+ "rule_used": "ret_1d < 0.0000"
91
  },
92
  "HCLTECH": {
93
  "prediction": "UP",
94
+ "probability": 60.0,
95
+ "rule_used": "dist_sma_10 > 0.9800"
96
  },
97
  "HDFCBANK": {
98
+ "prediction": "UP",
99
+ "probability": 62.5,
100
+ "rule_used": "ret_1d > 0.0125"
101
  },
102
  "HDFCLIFE": {
103
  "prediction": "DOWN",
104
+ "probability": 67.5,
105
+ "rule_used": "rsi_14 < 36"
106
  },
107
  "HEROMOTOCO": {
108
  "prediction": "DOWN",
109
+ "probability": 58.33,
110
+ "rule_used": "rsi_14 < 46"
111
  },
112
  "HINDALCO": {
113
+ "prediction": "DOWN",
114
  "probability": 63.33,
115
+ "rule_used": "rsi_5 > 28"
116
  },
117
  "HINDUNILVR": {
118
  "prediction": "UP",
119
+ "probability": 59.17,
120
+ "rule_used": "ret_3d > -0.0275"
121
  },
122
  "ICICIBANK": {
123
  "prediction": "DOWN",
124
+ "probability": 58.33,
125
+ "rule_used": "dist_sma_20 < 1.0100"
126
  },
127
  "INDUSINDBK": {
128
+ "prediction": "DOWN",
129
+ "probability": 60.0,
130
+ "rule_used": "ret_5d < -0.0050"
131
  },
132
  "INFY": {
133
  "prediction": "DOWN",
134
+ "probability": 57.5,
135
+ "rule_used": "rsi_14 > 56"
136
  },
137
  "ITC": {
138
  "prediction": "DOWN",
139
+ "probability": 61.67,
140
+ "rule_used": "ret_1d < -0.0100"
141
  },
142
  "JSWSTEEL": {
143
+ "prediction": "DOWN",
144
+ "probability": 64.17,
145
+ "rule_used": "rsi_5 < 46"
146
  },
147
  "KOTAKBANK": {
148
  "prediction": "DOWN",
149
+ "probability": 57.5,
150
+ "rule_used": "rsi_5 < 64"
151
  },
152
  "LT": {
153
+ "prediction": "UP",
154
  "probability": 57.5,
155
+ "rule_used": "rsi_3 > 40"
156
  },
157
  "LTIM": {
158
  "prediction": "UP",
159
  "probability": 60.0,
160
+ "rule_used": "ret_1d < 0.0000"
161
  },
162
  "MARUTI": {
163
  "prediction": "DOWN",
164
+ "probability": 62.5,
165
+ "rule_used": "rsi_2 < 32"
166
  },
167
  "MM": {
168
+ "prediction": "UP",
169
+ "probability": 65.83,
170
+ "rule_used": "rsi_14 < 54"
171
  },
172
  "NESTLEIND": {
173
  "prediction": "DOWN",
174
+ "probability": 60.0,
175
+ "rule_used": "ret_1d < -0.0025"
176
  },
177
  "NTPC": {
178
  "prediction": "UP",
179
+ "probability": 63.33,
180
+ "rule_used": "rsi_7 < 60"
181
  },
182
  "ONGC": {
183
  "prediction": "UP",
184
+ "probability": 60.83,
185
+ "rule_used": "rsi_2 < 46"
186
  },
187
  "POWERGRID": {
188
  "prediction": "UP",
189
+ "probability": 59.17,
190
+ "rule_used": "rsi_14 < 50"
191
  },
192
  "RELIANCE": {
193
  "prediction": "DOWN",
194
+ "probability": 60.83,
195
+ "rule_used": "rsi_7 < 50"
196
  },
197
  "SBILIFE": {
198
  "prediction": "DOWN",
199
+ "probability": 60.83,
200
+ "rule_used": "ret_1d < -0.0025"
201
  },
202
  "SBIN": {
203
  "prediction": "UP",
204
+ "probability": 56.67,
205
+ "rule_used": "rsi_7 > 42"
206
  },
207
  "SUNPHARMA": {
208
  "prediction": "UP",
209
+ "probability": 57.5,
210
+ "rule_used": "ret_3d > -0.0025"
211
  },
212
  "TATACONSUM": {
213
+ "prediction": "UP",
214
+ "probability": 60.83,
215
+ "rule_used": "rsi_14 < 50"
216
  },
217
  "TATASTEEL": {
218
  "prediction": "DOWN",
219
+ "probability": 60.0,
220
+ "rule_used": "rsi_7 > 40"
221
  },
222
  "TCS": {
223
  "prediction": "UP",
224
+ "probability": 60.83,
225
+ "rule_used": "rsi_14 > 32"
226
  },
227
  "TECHM": {
228
+ "prediction": "DOWN",
229
+ "probability": 60.83,
230
+ "rule_used": "rsi_5 > 44"
231
  },
232
  "TITAN": {
233
  "prediction": "DOWN",
234
+ "probability": 59.17,
235
+ "rule_used": "rsi_14 < 36"
236
  },
237
  "ULTRACEMCO": {
238
  "prediction": "DOWN",
239
+ "probability": 59.17,
240
+ "rule_used": "ret_1d < -0.0300"
241
  },
242
  "UPL": {
243
  "prediction": "DOWN",
244
+ "probability": 63.33,
245
+ "rule_used": "rsi_3 < 44"
246
  },
247
  "WIPRO": {
248
  "prediction": "UP",