omniverse1 commited on
Commit
6b7b90d
·
verified ·
1 Parent(s): 091b5c7

update config

Browse files
Files changed (1) hide show
  1. config.py +64 -506
config.py CHANGED
@@ -1,511 +1,69 @@
1
- import yfinance as yf
2
- import pandas as pd
3
- import numpy as np
4
- import torch
5
- from datetime import datetime, timedelta
6
- import plotly.graph_objects as go
7
- import plotly.express as px
8
- from plotly.subplots import make_subplots
9
- import spaces
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- def get_indonesian_stocks():
12
- """Get list of major Indonesian stocks"""
13
- return {
14
- "BBCA.JK": "Bank Central Asia",
15
- "BBRI.JK": "Bank BRI",
16
- "BBNI.JK": "Bank BNI",
17
- "BMRI.JK": "Bank Mandiri",
18
- "TLKM.JK": "Telkom Indonesia",
19
- "UNVR.JK": "Unilever Indonesia",
20
- "ASII.JK": "Astra International",
21
- "INDF.JK": "Indofood Sukses Makmur",
22
- "KLBF.JK": "Kalbe Farma",
23
- "HMSP.JK": "HM Sampoerna",
24
- "GGRM.JK": "Gudang Garam",
25
- "ADRO.JK": "Adaro Energy",
26
- "PGAS.JK": "Perusahaan Gas Negara",
27
- "JSMR.JK": "Jasa Marga",
28
- "WIKA.JK": "Wijaya Karya",
29
- "PTBA.JK": "Tambang Batubara Bukit Asam",
30
- "ANTM.JK": "Aneka Tambang",
31
- "SMGR.JK": "Semen Indonesia",
32
- "INTP.JK": "Indocement Tunggal Prakasa",
33
- "ITMG.JK": "Indo Tambangraya Megah"
34
  }
 
35
 
36
- def calculate_technical_indicators(data):
37
- """Calculate various technical indicators"""
38
- indicators = {}
39
-
40
- # RSI (Relative Strength Index)
41
- def calculate_rsi(prices, period=14):
42
- delta = prices.diff()
43
- gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
44
- loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
45
- rs = gain / loss
46
- rsi = 100 - (100 / (1 + rs))
47
- return rsi
48
-
49
- indicators['rsi'] = {
50
- 'current': calculate_rsi(data['Close']).iloc[-1],
51
- 'values': calculate_rsi(data['Close'])
52
- }
53
-
54
- # MACD
55
- def calculate_macd(prices, fast=12, slow=26, signal=9):
56
- exp1 = prices.ewm(span=fast).mean()
57
- exp2 = prices.ewm(span=slow).mean()
58
- macd = exp1 - exp2
59
- signal_line = macd.ewm(span=signal).mean()
60
- histogram = macd - signal_line
61
- return macd, signal_line, histogram
62
-
63
- macd, signal_line, histogram = calculate_macd(data['Close'])
64
- indicators['macd'] = {
65
- 'macd': macd.iloc[-1],
66
- 'signal': signal_line.iloc[-1],
67
- 'histogram': histogram.iloc[-1],
68
- 'signal_text': 'BUY' if histogram.iloc[-1] > 0 else 'SELL'
69
- }
70
-
71
- # Bollinger Bands
72
- def calculate_bollinger_bands(prices, period=20, std_dev=2):
73
- sma = prices.rolling(window=period).mean()
74
- std = prices.rolling(window=period).std()
75
- upper_band = sma + (std * std_dev)
76
- lower_band = sma - (std * std_dev)
77
- return upper_band, sma, lower_band
78
-
79
- upper, middle, lower = calculate_bollinger_bands(data['Close'])
80
- current_price = data['Close'].iloc[-1]
81
- bb_position = (current_price - lower.iloc[-1]) / (upper.iloc[-1] - lower.iloc[-1])
82
-
83
- indicators['bollinger'] = {
84
- 'upper': upper.iloc[-1],
85
- 'middle': middle.iloc[-1],
86
- 'lower': lower.iloc[-1],
87
- 'position': 'UPPER' if bb_position > 0.8 else 'LOWER' if bb_position < 0.2 else 'MIDDLE'
88
- }
89
-
90
- # Moving Averages
91
- indicators['moving_averages'] = {
92
- 'sma_20': data['Close'].rolling(20).mean().iloc[-1],
93
- 'sma_50': data['Close'].rolling(50).mean().iloc[-1],
94
- 'sma_200': data['Close'].rolling(200).mean().iloc[-1],
95
- 'ema_12': data['Close'].ewm(span=12).mean().iloc[-1],
96
- 'ema_26': data['Close'].ewm(span=26).mean().iloc[-1]
97
- }
98
-
99
- # Volume indicators
100
- indicators['volume'] = {
101
- 'current': data['Volume'].iloc[-1],
102
- 'avg_20': data['Volume'].rolling(20).mean().iloc[-1],
103
- 'ratio': data['Volume'].iloc[-1] / data['Volume'].rolling(20).mean().iloc[-1]
104
- }
105
-
106
- return indicators
107
 
108
- def generate_trading_signals(data, indicators):
109
- """Generate trading signals based on technical indicators"""
110
- signals = {}
111
-
112
- current_price = data['Close'].iloc[-1]
113
-
114
- # Initialize scores
115
- buy_signals = 0
116
- sell_signals = 0
117
-
118
- signal_details = []
119
-
120
- # RSI Signal
121
- rsi = indicators['rsi']['current']
122
- if rsi < 30:
123
- buy_signals += 1
124
- signal_details.append(f"✅ RSI ({rsi:.1f}) - Oversold - BUY signal")
125
- elif rsi > 70:
126
- sell_signals += 1
127
- signal_details.append(f"❌ RSI ({rsi:.1f}) - Overbought - SELL signal")
128
- else:
129
- signal_details.append(f"⚪ RSI ({rsi:.1f}) - Neutral")
130
-
131
- # MACD Signal
132
- macd_hist = indicators['macd']['histogram']
133
- if macd_hist > 0:
134
- buy_signals += 1
135
- signal_details.append(f"✅ MACD Histogram ({macd_hist:.4f}) - Positive - BUY signal")
136
- else:
137
- sell_signals += 1
138
- signal_details.append(f"❌ MACD Histogram ({macd_hist:.4f}) - Negative - SELL signal")
139
-
140
- # Bollinger Bands Signal
141
- bb_position = indicators['bollinger']['position']
142
- if bb_position == 'LOWER':
143
- buy_signals += 1
144
- signal_details.append(f"✅ Bollinger Bands - Near lower band - BUY signal")
145
- elif bb_position == 'UPPER':
146
- sell_signals += 1
147
- signal_details.append(f"❌ Bollinger Bands - Near upper band - SELL signal")
148
- else:
149
- signal_details.append("⚪ Bollinger Bands - Middle position")
150
-
151
- # Moving Averages Signal
152
- sma_20 = indicators['moving_averages']['sma_20']
153
- sma_50 = indicators['moving_averages']['sma_50']
154
-
155
- if current_price > sma_20 > sma_50:
156
- buy_signals += 1
157
- signal_details.append(f"✅ Price above MA(20,50) - Bullish - BUY signal")
158
- elif current_price < sma_20 < sma_50:
159
- sell_signals += 1
160
- signal_details.append(f"❌ Price below MA(20,50) - Bearish - SELL signal")
161
- else:
162
- signal_details.append("⚪ Moving Averages - Mixed signals")
163
-
164
- # Volume Signal
165
- volume_ratio = indicators['volume']['ratio']
166
- if volume_ratio > 1.5:
167
- buy_signals += 0.5
168
- signal_details.append(f"✅ High volume ({volume_ratio:.1f}x avg) - Strengthens BUY signal")
169
- elif volume_ratio < 0.5:
170
- sell_signals += 0.5
171
- signal_details.append(f"❌ Low volume ({volume_ratio:.1f}x avg) - Weakens SELL signal")
172
- else:
173
- signal_details.append(f"⚪ Normal volume ({volume_ratio:.1f}x avg)")
174
-
175
- # Determine overall signal
176
- total_signals = buy_signals + sell_signals
177
- signal_strength = (buy_signals / max(total_signals, 1)) * 100
178
-
179
- if buy_signals > sell_signals:
180
- overall_signal = "BUY"
181
- elif sell_signals > buy_signals:
182
- overall_signal = "SELL"
183
- else:
184
- overall_signal = "HOLD"
185
-
186
- # Calculate support and resistance
187
- recent_high = data['High'].tail(20).max()
188
- recent_low = data['Low'].tail(20).min()
189
-
190
- signals = {
191
- 'overall': overall_signal,
192
- 'strength': signal_strength,
193
- 'details': '\n'.join(signal_details),
194
- 'support': recent_low,
195
- 'resistance': recent_high,
196
- 'stop_loss': recent_low * 0.95 if overall_signal == "BUY" else recent_high * 1.05
197
  }
198
-
199
- return signals
200
-
201
- def get_fundamental_data(stock):
202
- """Get fundamental data for the stock"""
203
- try:
204
- info = stock.info
205
- history = stock.history(period="1d")
206
-
207
- fundamental_info = {
208
- 'name': info.get('longName', 'N/A'),
209
- 'current_price': history['Close'].iloc[-1] if not history.empty else 0,
210
- 'market_cap': info.get('marketCap', 0),
211
- 'pe_ratio': info.get('forwardPE', 0),
212
- 'dividend_yield': info.get('dividendYield', 0) * 100 if info.get('dividendYield') else 0,
213
- 'volume': history['Volume'].iloc[-1] if not history.empty else 0,
214
- 'info': f"""
215
- Sector: {info.get('sector', 'N/A')}
216
- Industry: {info.get('industry', 'N/A')}
217
- Market Cap: {format_large_number(info.get('marketCap', 0))}
218
- 52 Week High: {info.get('fiftyTwoWeekHigh', 'N/A')}
219
- 52 Week Low: {info.get('fiftyTwoWeekLow', 'N/A')}
220
- Beta: {info.get('beta', 'N/A')}
221
- EPS: {info.get('forwardEps', 'N/A')}
222
- Book Value: {info.get('bookValue', 'N/A')}
223
- Price to Book: {info.get('priceToBook', 'N/A')}
224
- """.strip()
225
- }
226
-
227
- return fundamental_info
228
- except Exception as e:
229
- print(f"Error getting fundamental data: {e}")
230
- return {
231
- 'name': 'N/A',
232
- 'current_price': 0,
233
- 'market_cap': 0,
234
- 'pe_ratio': 0,
235
- 'dividend_yield': 0,
236
- 'volume': 0,
237
- 'info': 'Unable to fetch fundamental data'
238
- }
239
-
240
- def format_large_number(num):
241
- """Format large numbers to readable format"""
242
- if num >= 1e12:
243
- return f"{num/1e12:.2f}T"
244
- elif num >= 1e9:
245
- return f"{num/1e9:.2f}B"
246
- elif num >= 1e6:
247
- return f"{num/1e6:.2f}M"
248
- elif num >= 1e3:
249
- return f"{num/1e3:.2f}K"
250
- else:
251
- return f"{num:.2f}"
252
-
253
- @spaces.GPU(duration=120)
254
- def predict_prices(data, model, tokenizer, prediction_days=30):
255
- """Predict future prices using Chronos-Bolt model"""
256
- try:
257
- # Prepare data for prediction
258
- prices = data['Close'].values
259
- context_length = min(len(prices), 512)
260
-
261
- # Tokenize the input
262
- input_sequence = prices[-context_length:]
263
-
264
- # Create prediction input
265
- prediction_input = torch.tensor(input_sequence).unsqueeze(0).float()
266
-
267
- # Generate predictions
268
- with torch.no_grad():
269
- forecast = model.generate(
270
- prediction_input,
271
- prediction_length=prediction_days,
272
- temperature=1.0,
273
- top_k=50,
274
- top_p=0.9
275
- )
276
-
277
- predictions = forecast[0].numpy()
278
-
279
- # Calculate prediction statistics
280
- last_price = prices[-1]
281
- predicted_high = np.max(predictions)
282
- predicted_low = np.min(predictions)
283
- predicted_mean = np.mean(predictions)
284
- change_pct = ((predicted_mean - last_price) / last_price) * 100
285
-
286
- return {
287
- 'values': predictions,
288
- 'dates': pd.date_range(
289
- start=data.index[-1] + timedelta(days=1),
290
- periods=prediction_days,
291
- freq='D'
292
- ),
293
- 'high_30d': predicted_high,
294
- 'low_30d': predicted_low,
295
- 'mean_30d': predicted_mean,
296
- 'change_pct': change_pct,
297
- 'summary': f"""
298
- AI Model: Amazon Chronos-Bolt
299
- Prediction Period: {prediction_days} days
300
- Expected Change: {change_pct:.2f}%
301
- Confidence: Medium (based on historical patterns)
302
- Note: AI predictions are for reference only and not financial advice
303
- """.strip()
304
- }
305
- except Exception as e:
306
- print(f"Error in prediction: {e}")
307
- return {
308
- 'values': [],
309
- 'dates': [],
310
- 'high_30d': 0,
311
- 'low_30d': 0,
312
- 'mean_30d': 0,
313
- 'change_pct': 0,
314
- 'summary': 'Prediction unavailable due to model error'
315
- }
316
-
317
- def create_price_chart(data, indicators):
318
- """Create price chart with technical indicators"""
319
- fig = make_subplots(
320
- rows=3, cols=1,
321
- shared_xaxes=True,
322
- vertical_spacing=0.05,
323
- subplot_titles=('Price & Moving Averages', 'RSI', 'MACD'),
324
- row_width=[0.2, 0.2, 0.7]
325
- )
326
-
327
- # Price and Moving Averages
328
- fig.add_trace(
329
- go.Candlestick(
330
- x=data.index,
331
- open=data['Open'],
332
- high=data['High'],
333
- low=data['Low'],
334
- close=data['Close'],
335
- name='Price'
336
- ),
337
- row=1, col=1
338
- )
339
-
340
- # Add moving averages
341
- fig.add_trace(
342
- go.Scatter(
343
- x=data.index,
344
- y=indicators['moving_averages']['sma_20'],
345
- name='SMA 20',
346
- line=dict(color='orange', width=1)
347
- ),
348
- row=1, col=1
349
- )
350
-
351
- fig.add_trace(
352
- go.Scatter(
353
- x=data.index,
354
- y=indicators['moving_averages']['sma_50'],
355
- name='SMA 50',
356
- line=dict(color='blue', width=1)
357
- ),
358
- row=1, col=1
359
- )
360
-
361
- # RSI
362
- fig.add_trace(
363
- go.Scatter(
364
- x=data.index,
365
- y=indicators['rsi']['values'],
366
- name='RSI',
367
- line=dict(color='purple')
368
- ),
369
- row=2, col=1
370
- )
371
-
372
- fig.add_hline(y=70, line_dash="dash", line_color="red", row=2, col=1)
373
- fig.add_hline(y=30, line_dash="dash", line_color="green", row=2, col=1)
374
-
375
- # MACD
376
- fig.add_trace(
377
- go.Scatter(
378
- x=data.index,
379
- y=indicators['macd']['macd'],
380
- name='MACD',
381
- line=dict(color='blue')
382
- ),
383
- row=3, col=1
384
- )
385
-
386
- fig.add_trace(
387
- go.Scatter(
388
- x=data.index,
389
- y=indicators['macd']['signal'],
390
- name='Signal',
391
- line=dict(color='red')
392
- ),
393
- row=3, col=1
394
- )
395
-
396
- fig.update_layout(
397
- title='Technical Analysis Dashboard',
398
- height=900,
399
- showlegend=True,
400
- xaxis_rangeslider_visible=False
401
- )
402
-
403
- return fig
404
-
405
- def create_technical_chart(data, indicators):
406
- """Create technical indicators dashboard"""
407
- fig = make_subplots(
408
- rows=2, cols=2,
409
- subplot_titles=('Bollinger Bands', 'Volume', 'Price vs MA', 'RSI Analysis'),
410
- specs=[[{"secondary_y": False}, {"secondary_y": False}],
411
- [{"secondary_y": False}, {"secondary_y": False}]]
412
- )
413
-
414
- # Bollinger Bands
415
- fig.add_trace(
416
- go.Scatter(x=data.index, y=data['Close'], name='Price', line=dict(color='black')),
417
- row=1, col=1
418
- )
419
-
420
- # Volume
421
- fig.add_trace(
422
- go.Bar(x=data.index, y=data['Volume'], name='Volume', marker_color='lightblue'),
423
- row=1, col=2
424
- )
425
-
426
- # Price vs Moving Averages
427
- fig.add_trace(
428
- go.Scatter(x=data.index, y=data['Close'], name='Price', line=dict(color='black')),
429
- row=2, col=1
430
- )
431
-
432
- fig.add_trace(
433
- go.Scatter(
434
- x=data.index,
435
- y=[indicators['moving_averages']['sma_20']] * len(data),
436
- name='SMA 20',
437
- line=dict(color='orange', dash='dash')
438
- ),
439
- row=2, col=1
440
- )
441
-
442
- fig.update_layout(
443
- title='Technical Indicators Overview',
444
- height=600,
445
- showlegend=False
446
- )
447
-
448
- return fig
449
-
450
- def create_prediction_chart(data, predictions):
451
- """Create prediction visualization"""
452
- if not predictions['values'].size:
453
- return go.Figure()
454
-
455
- fig = go.Figure()
456
-
457
- # Historical prices
458
- fig.add_trace(
459
- go.Scatter(
460
- x=data.index[-60:],
461
- y=data['Close'].values[-60:],
462
- name='Historical Price',
463
- line=dict(color='blue', width=2)
464
- )
465
- )
466
-
467
- # Predictions
468
- fig.add_trace(
469
- go.Scatter(
470
- x=predictions['dates'],
471
- y=predictions['values'],
472
- name='AI Prediction',
473
- line=dict(color='red', width=2, dash='dash')
474
- )
475
- )
476
-
477
- # Confidence interval (simple)
478
- pred_std = np.std(predictions['values'])
479
- upper_band = predictions['values'] + (pred_std * 1.96)
480
- lower_band = predictions['values'] - (pred_std * 1.96)
481
-
482
- fig.add_trace(
483
- go.Scatter(
484
- x=predictions['dates'],
485
- y=upper_band,
486
- name='Upper Band',
487
- line=dict(color='lightcoral', width=1),
488
- fill=None
489
- )
490
- )
491
-
492
- fig.add_trace(
493
- go.Scatter(
494
- x=predictions['dates'],
495
- y=lower_band,
496
- name='Lower Band',
497
- line=dict(color='lightcoral', width=1),
498
- fill='tonexty',
499
- fillcolor='rgba(255,182,193,0.2)'
500
- )
501
- )
502
-
503
- fig.update_layout(
504
- title=f'Price Prediction - Next {len(predictions["dates"])} Days',
505
- xaxis_title='Date',
506
- yaxis_title='Price (IDR)',
507
- hovermode='x unified',
508
- height=500
509
- )
510
-
511
- return fig
 
1
+ # Indonesian Stock Exchange (IDX) major stocks
2
+ IDX_STOCKS = {
3
+ "BBCA.JK": "Bank Central Asia",
4
+ "BBRI.JK": "Bank BRI",
5
+ "BBNI.JK": "Bank BNI",
6
+ "BMRI.JK": "Bank Mandiri",
7
+ "TLKM.JK": "Telkom Indonesia",
8
+ "UNVR.JK": "Unilever Indonesia",
9
+ "ASII.JK": "Astra International",
10
+ "INDF.JK": "Indofood Sukses Makmur",
11
+ "KLBF.JK": "Kalbe Farma",
12
+ "HMSP.JK": "HM Sampoerna",
13
+ "GGRM.JK": "Gudang Garam",
14
+ "ADRO.JK": "Adaro Energy",
15
+ "PGAS.JK": "Perusahaan Gas Negara",
16
+ "JSMR.JK": "Jasa Marga",
17
+ "WIKA.JK": "Wijaya Karya",
18
+ "PTBA.JK": "Tambang Batubara Bukit Asam",
19
+ "ANTM.JK": "Aneka Tambang",
20
+ "SMGR.JK": "Semen Indonesia",
21
+ "INTP.JK": "Indocement Tunggal Prakasa",
22
+ "ITMG.JK": "Indo Tambangraya Megah"
23
+ }
24
 
25
+ # Technical indicators configuration
26
+ TECHNICAL_INDICATORS = {
27
+ 'rsi': {
28
+ 'period': 14,
29
+ 'oversold': 30,
30
+ 'overbought': 70
31
+ },
32
+ 'macd': {
33
+ 'fast': 12,
34
+ 'slow': 26,
35
+ 'signal': 9
36
+ },
37
+ 'bollinger': {
38
+ 'period': 20,
39
+ 'std_dev': 2
40
+ },
41
+ 'moving_averages': {
42
+ 'sma_short': 20,
43
+ 'sma_medium': 50,
44
+ 'sma_long': 200,
45
+ 'ema_short': 12,
46
+ 'ema_long': 26
 
47
  }
48
+ }
49
 
50
+ # Prediction model configuration
51
+ PREDICTION_CONFIG = {
52
+ 'model_name': 'amazon/chronos-bolt-base',
53
+ 'context_length': 512,
54
+ 'prediction_length': 30,
55
+ 'temperature': 1.0,
56
+ 'top_k': 50,
57
+ 'top_p': 0.9
58
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ # Chart styling
61
+ CHART_CONFIG = {
62
+ 'template': 'plotly_white',
63
+ 'color_scheme': {
64
+ 'bullish': '#10b981',
65
+ 'bearish': '#ef4444',
66
+ 'neutral': '#6b7280',
67
+ 'accent': '#3b82f6'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  }
69
+ }