Tonic commited on
Commit
fe5cebb
·
1 Parent(s): 748d5c6

solves bug in inference pipeline

Browse files
Files changed (3) hide show
  1. README.md +66 -35
  2. app.py +154 -66
  3. requirements.txt +4 -3
README.md CHANGED
@@ -11,65 +11,96 @@ license: mit
11
  short_description: Use Amazon Chronos To Predict Stock Prices
12
  ---
13
 
14
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
15
 
16
-
17
- # Stock Price Prediction with Amazon Chronos
18
-
19
- A neural network application that uses Amazon's Chronos model for time series forecasting to predict stock prices.
20
 
21
  ## Features
22
 
23
- - Real-time stock price predictions using Amazon Chronos
24
- - Interactive visualization of predictions with confidence intervals
25
- - Support for multiple timeframes (daily, hourly, 15-minute)
26
- - User-friendly Gradio interface
27
- - Free stock data using yfinance API
28
 
29
- ## Hugging Face Spaces Deployment
 
 
 
 
30
 
31
- This application is configured to run on Hugging Face Spaces. To deploy:
 
 
 
32
 
33
- 1. Create a new Space on Hugging Face
34
- 2. Choose "Docker" as the SDK
35
- 3. Upload all the files to your Space
 
 
36
 
37
- ## Local Development
38
 
39
- To run locally:
 
 
 
 
40
 
 
41
  ```bash
42
- # Create and activate virtual environment
43
  python -m venv .venv
44
  source .venv/bin/activate # On Windows: .venv\Scripts\activate
 
45
 
46
- # Install dependencies
 
47
  pip install -r requirements.txt
 
 
 
48
 
49
- # Run the application
 
50
  python app.py
51
  ```
52
 
53
- ## Model Details
54
 
55
- The application uses Amazon's Chronos model for time series forecasting. The model is configured to:
 
 
 
56
 
57
- - Make predictions for stock prices
58
- - Calculate confidence intervals
59
- - Generate interactive visualizations
60
- - Support multiple prediction horizons
61
 
62
- ## Usage
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
- 1. Enter a stock symbol (e.g., AAPL, GOOGL, MSFT)
65
- 2. Select the desired timeframe (1d, 1h, 15m)
66
- 3. Choose the number of days to predict (1-30)
67
- 4. Click "Make Prediction" to generate forecasts
68
 
69
- The application will display:
70
- - A plot showing historical prices and predictions
71
- - Confidence intervals for the predictions
72
- - A separate plot showing prediction uncertainty
73
 
74
  ## License
75
 
 
11
  short_description: Use Amazon Chronos To Predict Stock Prices
12
  ---
13
 
14
+ # Stock Analysis and Prediction Demo
15
 
16
+ A comprehensive stock analysis and prediction tool built with Gradio, featuring multiple prediction strategies and technical analysis indicators.
 
 
 
17
 
18
  ## Features
19
 
20
+ - **Multiple Prediction Strategies**:
21
+ - Chronos ML-based prediction
22
+ - Technical analysis-based prediction
 
 
23
 
24
+ - **Technical Indicators**:
25
+ - RSI (Relative Strength Index)
26
+ - MACD (Moving Average Convergence Divergence)
27
+ - Bollinger Bands
28
+ - Simple Moving Averages (20 and 50-day)
29
 
30
+ - **Trading Signals**:
31
+ - Buy/Sell recommendations based on multiple indicators
32
+ - Overall trading signal combining all indicators
33
+ - Confidence intervals for predictions
34
 
35
+ - **Interactive Visualizations**:
36
+ - Price prediction with confidence intervals
37
+ - Technical indicators overlay
38
+ - Volume analysis
39
+ - Historical price trends
40
 
41
+ ## Installation
42
 
43
+ 1. Clone the repository:
44
+ ```bash
45
+ git clone <repository-url>
46
+ cd stock-prediction
47
+ ```
48
 
49
+ 2. Create and activate a virtual environment:
50
  ```bash
 
51
  python -m venv .venv
52
  source .venv/bin/activate # On Windows: .venv\Scripts\activate
53
+ ```
54
 
55
+ 3. Install dependencies:
56
+ ```bash
57
  pip install -r requirements.txt
58
+ ```
59
+
60
+ ## Usage
61
 
62
+ 1. Start the Gradio demo:
63
+ ```bash
64
  python app.py
65
  ```
66
 
67
+ 2. Open your web browser and navigate to the URL shown in the terminal (typically http://localhost:7860)
68
 
69
+ 3. Enter a stock symbol (e.g., AAPL, GOOGL, MSFT) and select your desired parameters:
70
+ - Timeframe (1d, 1h, 15m)
71
+ - Number of days to predict
72
+ - Prediction strategy (Chronos or Technical)
73
 
74
+ 4. Click "Analyze Stock" to get predictions and trading signals
 
 
 
75
 
76
+ ## Prediction Strategies
77
+
78
+ ### Chronos Strategy
79
+ Uses Amazon's Chronos model for ML-based price prediction. This strategy:
80
+ - Analyzes historical price patterns
81
+ - Generates probabilistic forecasts
82
+ - Provides confidence intervals
83
+
84
+ ### Technical Strategy
85
+ Uses traditional technical analysis indicators to generate predictions:
86
+ - RSI for overbought/oversold conditions
87
+ - MACD for trend direction
88
+ - Bollinger Bands for volatility
89
+ - Moving Averages for trend confirmation
90
+
91
+ ## Trading Signals
92
+
93
+ The demo provides trading signals based on multiple technical indicators:
94
+ - RSI: Oversold (<30), Overbought (>70), Neutral
95
+ - MACD: Buy (MACD > Signal), Sell (MACD < Signal)
96
+ - Bollinger Bands: Buy (price < lower band), Sell (price > upper band)
97
+ - SMA: Buy (20-day > 50-day), Sell (20-day < 50-day)
98
+
99
+ An overall trading signal is calculated by combining all individual signals.
100
 
101
+ ## Contributing
 
 
 
102
 
103
+ Contributions are welcome! Please feel free to submit a Pull Request.
 
 
 
104
 
105
  ## License
106
 
app.py CHANGED
@@ -7,34 +7,39 @@ import torch
7
  from chronos import BaseChronosPipeline
8
  import plotly.graph_objects as go
9
  from plotly.subplots import make_subplots
10
- import spaces
 
 
 
11
 
12
- # Initialize Chronos pipeline
13
  pipeline = None
 
 
14
 
15
- @spaces.GPU
16
  def load_pipeline():
17
- """Load the Chronos model with GPU configuration"""
18
  global pipeline
19
  if pipeline is None:
20
  pipeline = BaseChronosPipeline.from_pretrained(
21
  "amazon/chronos-bolt-base",
22
- device_map="auto", # Let the model use GPU if available
23
- torch_dtype=torch.float16 # Use float16 for better GPU performance
24
  )
25
  pipeline.model = pipeline.model.eval()
26
  return pipeline
27
 
28
- def get_historical_data(symbol: str, timeframe: str = "1d") -> np.ndarray:
29
  """
30
  Fetch historical data using yfinance.
31
 
32
  Args:
33
  symbol (str): The stock symbol (e.g., 'AAPL')
34
  timeframe (str): The timeframe for data ('1d', '1h', '15m')
 
35
 
36
  Returns:
37
- np.ndarray: Array of historical prices for Chronos model
38
  """
39
  try:
40
  # Map timeframe to yfinance interval
@@ -47,83 +52,118 @@ def get_historical_data(symbol: str, timeframe: str = "1d") -> np.ndarray:
47
 
48
  # Calculate date range
49
  end_date = datetime.now()
50
- if timeframe == "1d":
51
- start_date = end_date - timedelta(days=365) # 1 year of daily data
52
- elif timeframe == "1h":
53
- start_date = end_date - timedelta(days=30) # 30 days of hourly data
54
- else: # 15m
55
- start_date = end_date - timedelta(days=7) # 7 days of 15-min data
56
 
57
  # Fetch data using yfinance
58
  ticker = yf.Ticker(symbol)
59
  df = ticker.history(start=start_date, end=end_date, interval=interval)
60
 
61
- # Calculate returns
62
- df['returns'] = df['Close'].pct_change()
 
 
 
 
 
 
 
 
63
 
64
  # Drop NaN values
65
  df = df.dropna()
66
 
67
- # Normalize the data
68
- returns = df['returns'].values
69
- normalized_returns = (returns - returns.mean()) / returns.std()
70
-
71
- # Convert to the format expected by Chronos
72
- return normalized_returns.reshape(-1, 1)
73
 
74
  except Exception as e:
75
  raise Exception(f"Error fetching historical data for {symbol}: {str(e)}")
76
 
77
- @spaces.GPU
78
- def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  """
80
- Make prediction using Chronos model.
81
 
82
  Args:
83
  symbol (str): Stock symbol
84
  timeframe (str): Data timeframe
85
  prediction_days (int): Number of days to predict
 
86
 
87
  Returns:
88
  dict: Prediction results and visualization
89
  """
90
  try:
91
- # Load pipeline
92
- pipe = load_pipeline()
93
-
94
  # Get historical data
95
- historical_data = get_historical_data(symbol, timeframe)
96
-
97
- # Convert to tensor and move to GPU
98
- context = torch.tensor(historical_data, dtype=torch.float32).to(pipe.model.device)
99
-
100
- # Make prediction
101
- with torch.inference_mode():
102
- prediction = pipe.predict(
103
- context=context,
104
- prediction_length=prediction_days,
105
- num_samples=100
106
- ).detach().cpu().numpy()
107
 
108
- # Get actual historical prices for plotting
109
- ticker = yf.Ticker(symbol)
110
- hist_data = ticker.history(period="1mo")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
  # Create prediction dates
113
- last_date = hist_data.index[-1]
114
  pred_dates = pd.date_range(start=last_date + timedelta(days=1), periods=prediction_days)
115
 
116
- # Calculate prediction statistics
117
- mean_pred = prediction.mean(axis=0)
118
- std_pred = prediction.std(axis=0)
119
-
120
  # Create visualization
121
- fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
122
- vertical_spacing=0.03, subplot_titles=('Price Prediction', 'Confidence Interval'))
 
 
123
 
124
- # Add historical data
125
  fig.add_trace(
126
- go.Scatter(x=hist_data.index, y=hist_data['Close'], name='Historical Price',
127
  line=dict(color='blue')),
128
  row=1, col=1
129
  )
@@ -149,38 +189,81 @@ def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5
149
  row=1, col=1
150
  )
151
 
152
- # Add confidence interval plot
153
  fig.add_trace(
154
- go.Scatter(x=pred_dates, y=std_pred, name='Prediction Uncertainty',
 
 
 
 
 
 
 
 
 
 
155
  line=dict(color='green')),
156
  row=2, col=1
157
  )
158
 
 
 
 
 
 
 
 
159
  # Update layout
160
  fig.update_layout(
161
- title=f'{symbol} Price Prediction',
162
  xaxis_title='Date',
163
  yaxis_title='Price',
164
- height=800,
165
  showlegend=True
166
  )
167
 
 
 
 
168
  return {
169
  "symbol": symbol,
170
  "prediction": mean_pred.tolist(),
171
  "confidence": std_pred.tolist(),
172
  "dates": pred_dates.strftime('%Y-%m-%d').tolist(),
173
- "plot": fig
 
174
  }
175
 
176
  except Exception as e:
177
  raise Exception(f"Prediction error: {str(e)}")
178
 
179
- # Create Gradio interface
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  def create_interface():
181
- with gr.Blocks(title="Stock Price Prediction with Amazon Chronos") as demo:
182
- gr.Markdown("# Stock Price Prediction with Amazon Chronos")
183
- gr.Markdown("Enter a stock symbol and select prediction parameters to get price forecasts.")
 
184
 
185
  with gr.Row():
186
  with gr.Column():
@@ -197,16 +280,21 @@ def create_interface():
197
  step=1,
198
  label="Days to Predict"
199
  )
200
- predict_btn = gr.Button("Make Prediction")
 
 
 
 
 
201
 
202
  with gr.Column():
203
- plot = gr.Plot(label="Prediction Visualization")
204
- results = gr.JSON(label="Prediction Results")
205
 
206
  predict_btn.click(
207
  fn=make_prediction,
208
- inputs=[symbol, timeframe, prediction_days],
209
- outputs=[results, plot]
210
  )
211
 
212
  return demo
 
7
  from chronos import BaseChronosPipeline
8
  import plotly.graph_objects as go
9
  from plotly.subplots import make_subplots
10
+ from sklearn.preprocessing import MinMaxScaler
11
+ import plotly.express as px
12
+ from typing import Dict, List, Tuple, Optional
13
+ import json
14
 
15
+ # Initialize global variables
16
  pipeline = None
17
+ scaler = MinMaxScaler(feature_range=(-1, 1))
18
+ scaler.fit_transform([[-1, 1]])
19
 
 
20
  def load_pipeline():
21
+ """Load the Chronos model with CPU configuration"""
22
  global pipeline
23
  if pipeline is None:
24
  pipeline = BaseChronosPipeline.from_pretrained(
25
  "amazon/chronos-bolt-base",
26
+ device_map="cpu",
27
+ torch_dtype=torch.float32
28
  )
29
  pipeline.model = pipeline.model.eval()
30
  return pipeline
31
 
32
+ def get_historical_data(symbol: str, timeframe: str = "1d", lookback_days: int = 365) -> pd.DataFrame:
33
  """
34
  Fetch historical data using yfinance.
35
 
36
  Args:
37
  symbol (str): The stock symbol (e.g., 'AAPL')
38
  timeframe (str): The timeframe for data ('1d', '1h', '15m')
39
+ lookback_days (int): Number of days to look back
40
 
41
  Returns:
42
+ pd.DataFrame: Historical data with OHLCV and technical indicators
43
  """
44
  try:
45
  # Map timeframe to yfinance interval
 
52
 
53
  # Calculate date range
54
  end_date = datetime.now()
55
+ start_date = end_date - timedelta(days=lookback_days)
 
 
 
 
 
56
 
57
  # Fetch data using yfinance
58
  ticker = yf.Ticker(symbol)
59
  df = ticker.history(start=start_date, end=end_date, interval=interval)
60
 
61
+ # Calculate technical indicators
62
+ df['SMA_20'] = df['Close'].rolling(window=20).mean()
63
+ df['SMA_50'] = df['Close'].rolling(window=50).mean()
64
+ df['RSI'] = calculate_rsi(df['Close'])
65
+ df['MACD'], df['MACD_Signal'] = calculate_macd(df['Close'])
66
+ df['BB_Upper'], df['BB_Middle'], df['BB_Lower'] = calculate_bollinger_bands(df['Close'])
67
+
68
+ # Calculate returns and volatility
69
+ df['Returns'] = df['Close'].pct_change()
70
+ df['Volatility'] = df['Returns'].rolling(window=20).std()
71
 
72
  # Drop NaN values
73
  df = df.dropna()
74
 
75
+ return df
 
 
 
 
 
76
 
77
  except Exception as e:
78
  raise Exception(f"Error fetching historical data for {symbol}: {str(e)}")
79
 
80
+ def calculate_rsi(prices: pd.Series, period: int = 14) -> pd.Series:
81
+ """Calculate Relative Strength Index"""
82
+ delta = prices.diff()
83
+ gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
84
+ loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
85
+ rs = gain / loss
86
+ return 100 - (100 / (1 + rs))
87
+
88
+ def calculate_macd(prices: pd.Series, fast: int = 12, slow: int = 26, signal: int = 9) -> Tuple[pd.Series, pd.Series]:
89
+ """Calculate MACD and Signal line"""
90
+ exp1 = prices.ewm(span=fast, adjust=False).mean()
91
+ exp2 = prices.ewm(span=slow, adjust=False).mean()
92
+ macd = exp1 - exp2
93
+ signal_line = macd.ewm(span=signal, adjust=False).mean()
94
+ return macd, signal_line
95
+
96
+ def calculate_bollinger_bands(prices: pd.Series, period: int = 20, std_dev: int = 2) -> Tuple[pd.Series, pd.Series, pd.Series]:
97
+ """Calculate Bollinger Bands"""
98
+ middle_band = prices.rolling(window=period).mean()
99
+ std = prices.rolling(window=period).std()
100
+ upper_band = middle_band + (std * std_dev)
101
+ lower_band = middle_band - (std * std_dev)
102
+ return upper_band, middle_band, lower_band
103
+
104
+ def make_prediction(symbol: str, timeframe: str = "1d", prediction_days: int = 5, strategy: str = "chronos") -> Dict:
105
  """
106
+ Make prediction using selected strategy.
107
 
108
  Args:
109
  symbol (str): Stock symbol
110
  timeframe (str): Data timeframe
111
  prediction_days (int): Number of days to predict
112
+ strategy (str): Prediction strategy to use
113
 
114
  Returns:
115
  dict: Prediction results and visualization
116
  """
117
  try:
 
 
 
118
  # Get historical data
119
+ df = get_historical_data(symbol, timeframe)
 
 
 
 
 
 
 
 
 
 
 
120
 
121
+ if strategy == "chronos":
122
+ # Prepare data for Chronos
123
+ returns = df['Returns'].values
124
+ normalized_returns = (returns - returns.mean()) / returns.std()
125
+ context = torch.tensor(normalized_returns.reshape(-1, 1), dtype=torch.float32)
126
+
127
+ # Make prediction
128
+ pipe = load_pipeline()
129
+ with torch.inference_mode():
130
+ prediction = pipe.predict(
131
+ context=context,
132
+ prediction_length=prediction_days
133
+ ).detach().cpu().numpy()
134
+
135
+ # Reshape prediction to get mean and std
136
+ mean_pred = prediction.mean(axis=0)
137
+ std_pred = prediction.std(axis=0)
138
+
139
+ elif strategy == "technical":
140
+ # Technical analysis based prediction
141
+ last_price = df['Close'].iloc[-1]
142
+ rsi = df['RSI'].iloc[-1]
143
+ macd = df['MACD'].iloc[-1]
144
+ macd_signal = df['MACD_Signal'].iloc[-1]
145
+
146
+ # Simple prediction based on technical indicators
147
+ trend = 1 if (rsi > 50 and macd > macd_signal) else -1
148
+ volatility = df['Volatility'].iloc[-1]
149
+
150
+ # Generate predictions
151
+ mean_pred = np.array([last_price * (1 + trend * volatility * i) for i in range(1, prediction_days + 1)])
152
+ std_pred = np.array([volatility * last_price * i for i in range(1, prediction_days + 1)])
153
 
154
  # Create prediction dates
155
+ last_date = df.index[-1]
156
  pred_dates = pd.date_range(start=last_date + timedelta(days=1), periods=prediction_days)
157
 
 
 
 
 
158
  # Create visualization
159
+ fig = make_subplots(rows=3, cols=1,
160
+ shared_xaxes=True,
161
+ vertical_spacing=0.05,
162
+ subplot_titles=('Price Prediction', 'Technical Indicators', 'Volume'))
163
 
164
+ # Add historical price
165
  fig.add_trace(
166
+ go.Scatter(x=df.index, y=df['Close'], name='Historical Price',
167
  line=dict(color='blue')),
168
  row=1, col=1
169
  )
 
189
  row=1, col=1
190
  )
191
 
192
+ # Add technical indicators
193
  fig.add_trace(
194
+ go.Scatter(x=df.index, y=df['RSI'], name='RSI',
195
+ line=dict(color='purple')),
196
+ row=2, col=1
197
+ )
198
+ fig.add_trace(
199
+ go.Scatter(x=df.index, y=df['MACD'], name='MACD',
200
+ line=dict(color='orange')),
201
+ row=2, col=1
202
+ )
203
+ fig.add_trace(
204
+ go.Scatter(x=df.index, y=df['MACD_Signal'], name='MACD Signal',
205
  line=dict(color='green')),
206
  row=2, col=1
207
  )
208
 
209
+ # Add volume
210
+ fig.add_trace(
211
+ go.Bar(x=df.index, y=df['Volume'], name='Volume',
212
+ marker_color='gray'),
213
+ row=3, col=1
214
+ )
215
+
216
  # Update layout
217
  fig.update_layout(
218
+ title=f'{symbol} Analysis and Prediction',
219
  xaxis_title='Date',
220
  yaxis_title='Price',
221
+ height=1000,
222
  showlegend=True
223
  )
224
 
225
+ # Calculate trading signals
226
+ signals = calculate_trading_signals(df)
227
+
228
  return {
229
  "symbol": symbol,
230
  "prediction": mean_pred.tolist(),
231
  "confidence": std_pred.tolist(),
232
  "dates": pred_dates.strftime('%Y-%m-%d').tolist(),
233
+ "plot": fig,
234
+ "signals": signals
235
  }
236
 
237
  except Exception as e:
238
  raise Exception(f"Prediction error: {str(e)}")
239
 
240
+ def calculate_trading_signals(df: pd.DataFrame) -> Dict:
241
+ """Calculate trading signals based on technical indicators"""
242
+ signals = {
243
+ "RSI": "Oversold" if df['RSI'].iloc[-1] < 30 else "Overbought" if df['RSI'].iloc[-1] > 70 else "Neutral",
244
+ "MACD": "Buy" if df['MACD'].iloc[-1] > df['MACD_Signal'].iloc[-1] else "Sell",
245
+ "Bollinger": "Buy" if df['Close'].iloc[-1] < df['BB_Lower'].iloc[-1] else "Sell" if df['Close'].iloc[-1] > df['BB_Upper'].iloc[-1] else "Hold",
246
+ "SMA": "Buy" if df['SMA_20'].iloc[-1] > df['SMA_50'].iloc[-1] else "Sell"
247
+ }
248
+
249
+ # Calculate overall signal
250
+ buy_signals = sum(1 for signal in signals.values() if signal == "Buy")
251
+ sell_signals = sum(1 for signal in signals.values() if signal == "Sell")
252
+
253
+ if buy_signals > sell_signals:
254
+ signals["Overall"] = "Buy"
255
+ elif sell_signals > buy_signals:
256
+ signals["Overall"] = "Sell"
257
+ else:
258
+ signals["Overall"] = "Hold"
259
+
260
+ return signals
261
+
262
  def create_interface():
263
+ """Create the Gradio interface"""
264
+ with gr.Blocks(title="Stock Analysis and Prediction") as demo:
265
+ gr.Markdown("# Stock Analysis and Prediction")
266
+ gr.Markdown("Enter a stock symbol and select parameters to get price forecasts and trading signals.")
267
 
268
  with gr.Row():
269
  with gr.Column():
 
280
  step=1,
281
  label="Days to Predict"
282
  )
283
+ strategy = gr.Dropdown(
284
+ choices=["chronos", "technical"],
285
+ label="Prediction Strategy",
286
+ value="chronos"
287
+ )
288
+ predict_btn = gr.Button("Analyze Stock")
289
 
290
  with gr.Column():
291
+ plot = gr.Plot(label="Analysis and Prediction")
292
+ signals = gr.JSON(label="Trading Signals")
293
 
294
  predict_btn.click(
295
  fn=make_prediction,
296
+ inputs=[symbol, timeframe, prediction_days, strategy],
297
+ outputs=[signals, plot]
298
  )
299
 
300
  return demo
requirements.txt CHANGED
@@ -67,7 +67,7 @@ certifi
67
  patsy
68
  regex
69
  cachetools>=5.3.0
70
- python-dateutil
71
  cmaes
72
  alembic
73
  colorlog
@@ -104,7 +104,7 @@ gunicorn
104
  uvicorn
105
  # git+https://github.com/amazon-science/chronos-forecasting.git
106
  chronos-forecasting
107
- scikit-learn
108
 
109
  python-binance
110
  typer
@@ -116,4 +116,5 @@ numpy>=1.24.0
116
  torch>=2.0.0
117
  yfinance>=0.2.0
118
  plotly>=5.0.0
119
- chronos>=0.1.0
 
 
67
  patsy
68
  regex
69
  cachetools>=5.3.0
70
+ python-dateutil>=2.8.2
71
  cmaes
72
  alembic
73
  colorlog
 
104
  uvicorn
105
  # git+https://github.com/amazon-science/chronos-forecasting.git
106
  chronos-forecasting
107
+ scikit-learn>=1.0.0
108
 
109
  python-binance
110
  typer
 
116
  torch>=2.0.0
117
  yfinance>=0.2.0
118
  plotly>=5.0.0
119
+ chronos>=0.1.0
120
+ chronos-pytorch>=0.1.0