Edwin Salguero
commited on
Commit
·
aaa6e1c
1
Parent(s):
c1f2fac
feat: prepare for Streamlit Cloud deployment - fix requirements.txt, add deployment config, error handling, and entry point
Browse files- .streamlit/config.toml +17 -0
- STREAMLIT_DEPLOYMENT.md +123 -0
- generate_sample_data.py +45 -0
- packages.txt +4 -0
- requirements.txt +7 -5
- streamlit_app.py +17 -0
- ui/__init__.py +8 -4
- ui/streamlit_app.py +84 -5
.streamlit/config.toml
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[global]
|
2 |
+
developmentMode = false
|
3 |
+
|
4 |
+
[server]
|
5 |
+
headless = true
|
6 |
+
enableCORS = false
|
7 |
+
enableXsrfProtection = false
|
8 |
+
port = 8501
|
9 |
+
|
10 |
+
[browser]
|
11 |
+
gatherUsageStats = false
|
12 |
+
|
13 |
+
[theme]
|
14 |
+
primaryColor = "#1f77b4"
|
15 |
+
backgroundColor = "#ffffff"
|
16 |
+
secondaryBackgroundColor = "#f0f2f6"
|
17 |
+
textColor = "#262730"
|
STREAMLIT_DEPLOYMENT.md
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Streamlit Cloud Deployment Guide
|
2 |
+
|
3 |
+
## Overview
|
4 |
+
This guide will help you deploy your algorithmic trading system to Streamlit Cloud.
|
5 |
+
|
6 |
+
## Files Created for Deployment
|
7 |
+
|
8 |
+
### 1. `streamlit_app.py` (Root Entry Point)
|
9 |
+
- Main entry point for Streamlit Cloud
|
10 |
+
- Imports and runs the UI from the `ui/` directory
|
11 |
+
|
12 |
+
### 2. `.streamlit/config.toml`
|
13 |
+
- Streamlit configuration for deployment
|
14 |
+
- Optimized for cloud deployment
|
15 |
+
|
16 |
+
### 3. `packages.txt`
|
17 |
+
- System dependencies for the deployment environment
|
18 |
+
|
19 |
+
### 4. Updated `requirements.txt`
|
20 |
+
- Fixed dependencies for cloud deployment
|
21 |
+
- Removed problematic packages
|
22 |
+
|
23 |
+
## Deployment Steps
|
24 |
+
|
25 |
+
### 1. Push to GitHub
|
26 |
+
```bash
|
27 |
+
git add .
|
28 |
+
git commit -m "feat: prepare for Streamlit Cloud deployment"
|
29 |
+
git push origin main
|
30 |
+
```
|
31 |
+
|
32 |
+
### 2. Deploy to Streamlit Cloud
|
33 |
+
|
34 |
+
1. Go to [share.streamlit.io](https://share.streamlit.io)
|
35 |
+
2. Sign in with your GitHub account
|
36 |
+
3. Click "New app"
|
37 |
+
4. Configure your app:
|
38 |
+
- **Repository**: `your-username/algorithmic_trading`
|
39 |
+
- **Branch**: `main`
|
40 |
+
- **Main file path**: `streamlit_app.py`
|
41 |
+
- **App URL**: Choose your preferred URL
|
42 |
+
|
43 |
+
### 3. Environment Variables (Optional)
|
44 |
+
If you want to use real API keys, add these in Streamlit Cloud:
|
45 |
+
- `ALPACA_API_KEY`
|
46 |
+
- `ALPACA_SECRET_KEY`
|
47 |
+
- `ALPACA_BASE_URL`
|
48 |
+
|
49 |
+
## Deployment Features
|
50 |
+
|
51 |
+
### ✅ Deployment Mode
|
52 |
+
- The app automatically detects deployment environment
|
53 |
+
- Falls back to demo mode if modules aren't available
|
54 |
+
- Shows sample data and mock trading functionality
|
55 |
+
|
56 |
+
### ✅ Error Handling
|
57 |
+
- Graceful handling of missing dependencies
|
58 |
+
- Informative error messages
|
59 |
+
- Fallback functionality
|
60 |
+
|
61 |
+
### ✅ Performance Optimized
|
62 |
+
- Minimal dependencies
|
63 |
+
- Efficient imports
|
64 |
+
- Cloud-optimized configuration
|
65 |
+
|
66 |
+
## Troubleshooting
|
67 |
+
|
68 |
+
### Common Issues
|
69 |
+
|
70 |
+
1. **Import Errors**
|
71 |
+
- The app now handles missing modules gracefully
|
72 |
+
- Check the browser console for specific error messages
|
73 |
+
|
74 |
+
2. **Dependency Issues**
|
75 |
+
- All dependencies are now properly specified in `requirements.txt`
|
76 |
+
- System packages are included in `packages.txt`
|
77 |
+
|
78 |
+
3. **Configuration Issues**
|
79 |
+
- The app uses a default configuration in deployment mode
|
80 |
+
- No external files are required
|
81 |
+
|
82 |
+
### Debug Mode
|
83 |
+
To debug deployment issues:
|
84 |
+
1. Check the Streamlit Cloud logs
|
85 |
+
2. Look for error messages in the browser console
|
86 |
+
3. Verify all files are properly committed to GitHub
|
87 |
+
|
88 |
+
## Local Testing
|
89 |
+
Test the deployment version locally:
|
90 |
+
```bash
|
91 |
+
streamlit run streamlit_app.py
|
92 |
+
```
|
93 |
+
|
94 |
+
## Features Available in Deployment
|
95 |
+
|
96 |
+
### ✅ Working Features
|
97 |
+
- Configuration loading (demo mode)
|
98 |
+
- Data visualization with sample data
|
99 |
+
- Chart generation
|
100 |
+
- UI navigation
|
101 |
+
- Mock trading interface
|
102 |
+
|
103 |
+
### ⚠️ Limited Features
|
104 |
+
- Real API connections (requires environment variables)
|
105 |
+
- Live trading (demo mode only)
|
106 |
+
- Model training (simulated)
|
107 |
+
|
108 |
+
## Next Steps
|
109 |
+
|
110 |
+
1. **Deploy to Streamlit Cloud** using the steps above
|
111 |
+
2. **Test the deployment** to ensure everything works
|
112 |
+
3. **Add environment variables** for real API access
|
113 |
+
4. **Monitor the deployment** for any issues
|
114 |
+
|
115 |
+
## Support
|
116 |
+
|
117 |
+
If you encounter issues:
|
118 |
+
1. Check the Streamlit Cloud logs
|
119 |
+
2. Verify all files are committed to GitHub
|
120 |
+
3. Test locally with `streamlit run streamlit_app.py`
|
121 |
+
4. Review the error handling in the code
|
122 |
+
|
123 |
+
The deployment is now ready! 🚀
|
generate_sample_data.py
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import numpy as np
|
3 |
+
from datetime import datetime, timedelta
|
4 |
+
|
5 |
+
# Generate more realistic sample data
|
6 |
+
start_date = datetime(2024, 7, 1, 9, 30)
|
7 |
+
dates = [start_date + timedelta(minutes=i) for i in range(1000)] # 1000 data points
|
8 |
+
|
9 |
+
# Generate realistic price movements
|
10 |
+
np.random.seed(42)
|
11 |
+
base_price = 150.0
|
12 |
+
prices = []
|
13 |
+
for i in range(1000):
|
14 |
+
if i == 0:
|
15 |
+
price = base_price
|
16 |
+
else:
|
17 |
+
# Add some trend and volatility
|
18 |
+
change = np.random.normal(0, 0.5) + (0.001 * i) # Small upward trend
|
19 |
+
price = prices[-1] + change
|
20 |
+
prices.append(max(price, 1)) # Ensure price doesn't go negative
|
21 |
+
|
22 |
+
# Create OHLCV data
|
23 |
+
data = []
|
24 |
+
for i, (date, price) in enumerate(zip(dates, prices)):
|
25 |
+
# Generate realistic OHLC from base price
|
26 |
+
volatility = 0.02
|
27 |
+
high = price * (1 + np.random.uniform(0, volatility))
|
28 |
+
low = price * (1 - np.random.uniform(0, volatility))
|
29 |
+
open_price = price * (1 + np.random.uniform(-volatility/2, volatility/2))
|
30 |
+
close_price = price * (1 + np.random.uniform(-volatility/2, volatility/2))
|
31 |
+
volume = int(np.random.uniform(5000, 50000))
|
32 |
+
|
33 |
+
data.append({
|
34 |
+
'timestamp': date,
|
35 |
+
'open': round(open_price, 2),
|
36 |
+
'high': round(high, 2),
|
37 |
+
'low': round(low, 2),
|
38 |
+
'close': round(close_price, 2),
|
39 |
+
'volume': volume
|
40 |
+
})
|
41 |
+
|
42 |
+
df = pd.DataFrame(data)
|
43 |
+
df.to_csv('data/market_data.csv', index=False)
|
44 |
+
print(f'Generated {len(df)} realistic data points from {df.timestamp.min()} to {df.timestamp.max()}')
|
45 |
+
print(f'Price range: ${df.close.min():.2f} - ${df.close.max():.2f}')
|
packages.txt
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# System packages for Streamlit Cloud deployment
|
2 |
+
gcc
|
3 |
+
g++
|
4 |
+
make
|
requirements.txt
CHANGED
@@ -4,7 +4,7 @@ pandas>=1.3.0
|
|
4 |
scikit-learn>=1.0.0
|
5 |
matplotlib>=3.5.0
|
6 |
seaborn>=0.11.0
|
7 |
-
|
8 |
requests>=2.25.0
|
9 |
python-dotenv>=0.19.0
|
10 |
|
@@ -14,7 +14,8 @@ gym>=0.21.0
|
|
14 |
torch>=1.9.0
|
15 |
|
16 |
# Alpaca integration
|
17 |
-
alpaca-
|
|
|
18 |
|
19 |
# Testing
|
20 |
pytest>=6.0.0
|
@@ -37,18 +38,19 @@ dash-daq>=0.5.0
|
|
37 |
rich>=13.0.0
|
38 |
tqdm>=4.64.0
|
39 |
ipywidgets>=8.0.0
|
40 |
-
voila>=0.4.0
|
41 |
jupyter-dash>=0.4.0
|
42 |
|
43 |
# Real-time updates
|
44 |
websockets>=10.0
|
45 |
-
asyncio-mqtt>=0.11.0
|
46 |
|
47 |
# Data visualization
|
48 |
bokeh>=3.0.0
|
49 |
altair>=5.0.0
|
50 |
-
vega-lite>=5.0.0
|
51 |
|
52 |
# Authentication and security
|
53 |
dash-auth>=2.0.0
|
54 |
flask-login>=0.6.0
|
|
|
|
|
|
|
|
|
|
4 |
scikit-learn>=1.0.0
|
5 |
matplotlib>=3.5.0
|
6 |
seaborn>=0.11.0
|
7 |
+
PyYAML>=5.4.0
|
8 |
requests>=2.25.0
|
9 |
python-dotenv>=0.19.0
|
10 |
|
|
|
14 |
torch>=1.9.0
|
15 |
|
16 |
# Alpaca integration
|
17 |
+
alpaca-py>=0.42.0
|
18 |
+
yfinance>=0.2.0
|
19 |
|
20 |
# Testing
|
21 |
pytest>=6.0.0
|
|
|
38 |
rich>=13.0.0
|
39 |
tqdm>=4.64.0
|
40 |
ipywidgets>=8.0.0
|
|
|
41 |
jupyter-dash>=0.4.0
|
42 |
|
43 |
# Real-time updates
|
44 |
websockets>=10.0
|
|
|
45 |
|
46 |
# Data visualization
|
47 |
bokeh>=3.0.0
|
48 |
altair>=5.0.0
|
|
|
49 |
|
50 |
# Authentication and security
|
51 |
dash-auth>=2.0.0
|
52 |
flask-login>=0.6.0
|
53 |
+
|
54 |
+
# WebSocket and async
|
55 |
+
fastapi>=0.116.0
|
56 |
+
uvicorn>=0.35.0
|
streamlit_app.py
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Streamlit Cloud Deployment Entry Point
|
3 |
+
This file serves as the main entry point for Streamlit Cloud deployment
|
4 |
+
"""
|
5 |
+
|
6 |
+
import streamlit as st
|
7 |
+
import sys
|
8 |
+
import os
|
9 |
+
|
10 |
+
# Add the ui directory to the path
|
11 |
+
sys.path.append(os.path.join(os.path.dirname(__file__), 'ui'))
|
12 |
+
|
13 |
+
# Import and run the main Streamlit app
|
14 |
+
from streamlit_app import main
|
15 |
+
|
16 |
+
if __name__ == "__main__":
|
17 |
+
main()
|
ui/__init__.py
CHANGED
@@ -11,14 +11,18 @@ This package provides multiple UI options:
|
|
11 |
__version__ = "1.0.0"
|
12 |
__author__ = "Algorithmic Trading Team"
|
13 |
|
14 |
-
from .streamlit_app import create_streamlit_app
|
15 |
-
from .dash_app import create_dash_app
|
16 |
-
from .jupyter_widgets import create_jupyter_interface
|
17 |
-
from .websocket_server import TradingWebSocketServer
|
18 |
|
19 |
__all__ = [
|
20 |
"create_streamlit_app",
|
21 |
"create_dash_app",
|
22 |
"create_jupyter_interface",
|
|
|
|
|
|
|
|
|
23 |
"TradingWebSocketServer"
|
24 |
]
|
|
|
11 |
__version__ = "1.0.0"
|
12 |
__author__ = "Algorithmic Trading Team"
|
13 |
|
14 |
+
from .streamlit_app import create_streamlit_app, TradingUI
|
15 |
+
from .dash_app import create_dash_app, TradingDashApp
|
16 |
+
from .jupyter_widgets import create_jupyter_interface, TradingJupyterUI
|
17 |
+
from .websocket_server import create_websocket_server, TradingWebSocketServer
|
18 |
|
19 |
__all__ = [
|
20 |
"create_streamlit_app",
|
21 |
"create_dash_app",
|
22 |
"create_jupyter_interface",
|
23 |
+
"create_websocket_server",
|
24 |
+
"TradingUI",
|
25 |
+
"TradingDashApp",
|
26 |
+
"TradingJupyterUI",
|
27 |
"TradingWebSocketServer"
|
28 |
]
|
ui/streamlit_app.py
CHANGED
@@ -26,11 +26,86 @@ import time
|
|
26 |
# Add project root to path
|
27 |
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
from agentic_ai_system.
|
32 |
-
from agentic_ai_system.
|
33 |
-
from agentic_ai_system.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
# Page configuration
|
36 |
st.set_page_config(
|
@@ -675,5 +750,9 @@ def main():
|
|
675 |
ui = TradingUI()
|
676 |
ui.run()
|
677 |
|
|
|
|
|
|
|
|
|
678 |
if __name__ == "__main__":
|
679 |
main()
|
|
|
26 |
# Add project root to path
|
27 |
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
28 |
|
29 |
+
# Import with error handling for deployment
|
30 |
+
try:
|
31 |
+
from agentic_ai_system.main import load_config
|
32 |
+
from agentic_ai_system.data_ingestion import load_data, validate_data, add_technical_indicators
|
33 |
+
from agentic_ai_system.finrl_agent import FinRLAgent, FinRLConfig
|
34 |
+
from agentic_ai_system.alpaca_broker import AlpacaBroker
|
35 |
+
from agentic_ai_system.orchestrator import run_backtest, run_live_trading
|
36 |
+
DEPLOYMENT_MODE = False
|
37 |
+
except ImportError as e:
|
38 |
+
st.warning(f"⚠️ Some modules not available in deployment mode: {e}")
|
39 |
+
DEPLOYMENT_MODE = True
|
40 |
+
|
41 |
+
# Mock functions for deployment
|
42 |
+
def load_config(config_file):
|
43 |
+
return {
|
44 |
+
'trading': {'symbol': 'AAPL', 'capital': 100000, 'timeframe': '1d'},
|
45 |
+
'execution': {'broker_api': 'alpaca_paper'},
|
46 |
+
'finrl': {'algorithm': 'PPO'},
|
47 |
+
'risk': {'max_drawdown': 0.1}
|
48 |
+
}
|
49 |
+
|
50 |
+
def load_data(config):
|
51 |
+
# Generate sample data for deployment
|
52 |
+
dates = pd.date_range(start='2023-01-01', end='2023-12-31', freq='D')
|
53 |
+
np.random.seed(42)
|
54 |
+
prices = 150 + np.cumsum(np.random.randn(len(dates)) * 0.5)
|
55 |
+
|
56 |
+
data = pd.DataFrame({
|
57 |
+
'timestamp': dates,
|
58 |
+
'open': prices * 0.99,
|
59 |
+
'high': prices * 1.02,
|
60 |
+
'low': prices * 0.98,
|
61 |
+
'close': prices,
|
62 |
+
'volume': np.random.randint(1000000, 5000000, len(dates))
|
63 |
+
})
|
64 |
+
return data
|
65 |
+
|
66 |
+
def add_technical_indicators(data):
|
67 |
+
data['sma_20'] = data['close'].rolling(window=20).mean()
|
68 |
+
data['sma_50'] = data['close'].rolling(window=50).mean()
|
69 |
+
return data
|
70 |
+
|
71 |
+
class FinRLAgent:
|
72 |
+
def __init__(self, config):
|
73 |
+
self.config = config
|
74 |
+
|
75 |
+
def train(self, data, config, total_timesteps, use_real_broker=False):
|
76 |
+
return {'success': True, 'message': 'Training completed (demo mode)'}
|
77 |
+
|
78 |
+
class FinRLConfig:
|
79 |
+
def __init__(self, **kwargs):
|
80 |
+
for key, value in kwargs.items():
|
81 |
+
setattr(self, key, value)
|
82 |
+
|
83 |
+
class AlpacaBroker:
|
84 |
+
def __init__(self, config):
|
85 |
+
self.config = config
|
86 |
+
|
87 |
+
def get_account_info(self):
|
88 |
+
return {
|
89 |
+
'portfolio_value': 100000,
|
90 |
+
'equity': 102500,
|
91 |
+
'cash': 50000,
|
92 |
+
'buying_power': 50000
|
93 |
+
}
|
94 |
+
|
95 |
+
def get_positions(self):
|
96 |
+
return []
|
97 |
+
|
98 |
+
def run_backtest(config, data):
|
99 |
+
return {
|
100 |
+
'success': True,
|
101 |
+
'total_return': 0.025,
|
102 |
+
'sharpe_ratio': 1.2,
|
103 |
+
'max_drawdown': 0.05,
|
104 |
+
'total_trades': 15
|
105 |
+
}
|
106 |
+
|
107 |
+
def run_live_trading(config, data):
|
108 |
+
return {'success': True, 'message': 'Live trading started (demo mode)'}
|
109 |
|
110 |
# Page configuration
|
111 |
st.set_page_config(
|
|
|
750 |
ui = TradingUI()
|
751 |
ui.run()
|
752 |
|
753 |
+
def create_streamlit_app():
|
754 |
+
"""Create and return a Streamlit trading application"""
|
755 |
+
return TradingUI()
|
756 |
+
|
757 |
if __name__ == "__main__":
|
758 |
main()
|