{"id":31556131,"url":"https://github.com/jongan69/finbert-rust-options-api","last_synced_at":"2025-10-04T22:49:08.333Z","repository":{"id":309272685,"uuid":"1035671047","full_name":"jongan69/finbert-rust-options-api","owner":"jongan69","description":"chat aM I cOOked","archived":false,"fork":false,"pushed_at":"2025-09-16T14:07:25.000Z","size":330,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-16T15:51:14.921Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jongan69.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-10T22:24:32.000Z","updated_at":"2025-09-16T14:07:29.000Z","dependencies_parsed_at":"2025-08-11T00:20:25.933Z","dependency_job_id":"16c71c59-4015-490e-bf23-ad689bfa15fe","html_url":"https://github.com/jongan69/finbert-rust-options-api","commit_stats":null,"previous_names":["jongan69/finbert-rust-options-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jongan69/finbert-rust-options-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jongan69%2Ffinbert-rust-options-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jongan69%2Ffinbert-rust-options-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jongan69%2Ffinbert-rust-options-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jongan69%2Ffinbert-rust-options-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jongan69","download_url":"https://codeload.github.com/jongan69/finbert-rust-options-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jongan69%2Ffinbert-rust-options-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278386118,"owners_count":25978109,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-04T22:49:06.791Z","updated_at":"2025-10-04T22:49:08.325Z","avatar_url":"https://github.com/jongan69.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FinBERT Sentiment Analysis Trading API\n\nA production-ready sentiment analysis API using FinBERT ONNX models for automated options trading signal generation, optimized for Raspberry Pi deployment.\n\n## 🎯 What This API Does\n\nThis API performs real-time financial sentiment analysis and generates options trading signals by:\n\n1. **Fetching Financial News** - Retrieves real-time news from Alpaca Markets API\n2. **Sentiment Analysis** - Uses FinBERT ONNX model to analyze news headlines for sentiment (positive/negative/neutral)\n3. **Options Analysis** - Analyzes options chains for symbols mentioned in news\n4. **Signal Generation** - Creates buy/sell signals for call/put options with risk metrics\n5. **Risk Assessment** - Calculates financial metrics (Sharpe ratio, Kelly criterion, VaR, etc.)\n\n## 🚀 Quick Setup\n\n**One-command setup for Raspberry Pi:**\n\n```bash\ncurl -sSL https://raw.githubusercontent.com/jongan69/finbert-rust-options-api/refs/heads/main/setup-rpi.sh | bash\n```\n\n**Or manual setup:**\n\n```bash\ngit clone https://github.com/jongan69/finbert-rust-options-api\ncd finbert-rust-options-api\nchmod +x setup-rpi.sh\n./setup-rpi.sh\n```\n\n**The setup script automatically:**\n- ✅ **Downloads FinBERT ONNX model** from Hugging Face\n- ✅ **Builds optimized binary** for your architecture\n- ✅ **Creates systemd service** for auto-startup and management\n- ✅ **Sets up configuration** template\n- ✅ **Creates management scripts** for easy control\n\n## 📋 Prerequisites\n\n- Raspberry Pi 3B+ or newer (recommended: Pi 4 with 4GB+ RAM)\n- Raspbian/Raspberry Pi OS (64-bit recommended)\n- Internet connection for downloading dependencies and model\n- [Alpaca API credentials](https://alpaca.markets/) (free paper trading account)\n\n## ⚙️ Configuration\n\n1. **Get Alpaca API credentials** (free at https://alpaca.markets/)\n2. **Edit configuration:**\n   ```bash\n   nano .env\n   ```\n3. **Set your credentials:**\n   ```bash\n   APCA_API_KEY_ID=your_actual_api_key\n   APCA_API_SECRET_KEY=your_actual_secret\n   ```\n\n## 🎮 Management Commands\n\nAfter setup, the API runs automatically. Use these commands to manage it:\n\n```bash\n./start-api.sh    # Start the API service (if stopped)\n./stop-api.sh     # Stop the API service  \n./status-api.sh   # Check service status and health\n./logs-api.sh     # View real-time logs (Ctrl+C to exit)\n```\n\n**Service status after reboot:**\n- ✅ API starts automatically on boot\n- ✅ Check status: `./status-api.sh`\n- ✅ View startup logs: `./logs-api.sh`\n\n## 🌐 API Endpoints\n\nOnce running, access these endpoints:\n\n- **Analysis:** `http://your-pi-ip:3000/analyze` - Complete sentiment analysis and trading signals\n- **Health Check:** `http://your-pi-ip:3000/health` - Service health status and model status\n- **Metrics:** `http://your-pi-ip:3000/metrics` - System configuration and performance metrics\n\n## 🔧 What the Setup Script Does\n\n1. ✅ **Updates system packages**\n2. ✅ **Installs Rust toolchain** \n3. ✅ **Downloads FinBERT ONNX model** from Hugging Face\n4. ✅ **Builds optimized binary** for your Pi's architecture\n5. ✅ **Creates systemd service** for auto-startup\n6. ✅ **Sets up configuration** template\n7. ✅ **Creates management scripts**\n\n## 📊 Performance\n\n**Typical performance on Raspberry Pi 4 (4GB):**\n- Model loading: ~10-15 seconds\n- Inference time: ~200-500ms per request\n- Memory usage: ~600MB\n- Concurrent requests: 5 (configurable)\n\n## 🛠️ Manual Operations\n\n**Build from source:**\n```bash\ncargo build --release\n```\n\n**Run directly:**\n```bash\nAPCA_API_KEY_ID=key APCA_API_SECRET_KEY=secret ./target/release/finbert-rust-options-api\n```\n\n**Check service logs:**\n```bash\nsudo journalctl -u finbert-api.service -f\n```\n\n## 📁 Project Structure\n\n```\nfinbert-rust-options-api/\n├── src/\n│   ├── main.rs            # Main application entry point and HTTP server\n│   ├── alpaca_data.rs     # Alpaca API integration and signal generation\n│   ├── onnx_sentiment.rs  # FinBERT ONNX model integration\n│   └── types.rs           # Data structures and type definitions\n├── finbert-onnx/          # FinBERT ONNX model files (downloaded by setup)\n│   ├── model.onnx         # Pre-trained FinBERT model\n│   ├── tokenizer.json     # Tokenizer configuration\n│   ├── config.json        # Model configuration\n│   └── vocab.txt          # Vocabulary file\n├── target/release/        # Compiled binary (created during build)\n├── setup-rpi.sh           # One-click setup script for Raspberry Pi\n├── run.sh                 # Manual run script\n├── finbert-options-api.service # Systemd service file\n├── .env.example           # Environment configuration template\n├── Cargo.toml             # Rust dependencies and project config\n└── README.md              # This file\n```\n\n### Generated Files (after setup)\n```\n├── .env                   # Your API credentials (create from .env.example)\n├── start-api.sh           # Start service script\n├── stop-api.sh            # Stop service script  \n├── status-api.sh          # Check status script\n└── logs-api.sh            # View logs script\n```\n\n## 📊 API Process Breakdown\n\n### How the Analysis Works\n\nThe `/analyze` endpoint performs the following steps:\n\n1. **News Fetching** - Retrieves latest financial news from Alpaca Markets API\n2. **Symbol Extraction** - Filters news items that contain stock symbols\n3. **Sentiment Analysis** - Uses FinBERT ONNX model to analyze headlines\n4. **Options Data Retrieval** - Fetches options chains for each symbol\n5. **Signal Generation** - Creates trading signals with risk metrics\n6. **Risk Assessment** - Calculates portfolio-level risk metrics\n\n**Response Time:** ~2-5 seconds (depending on market conditions and number of symbols)\n\n### 1. Main Analysis Endpoint\n**`GET /analyze`**\n\nPerforms complete sentiment analysis and generates options trading signals with advanced financial metrics.\n\n**Features:**\n- Real-time news sentiment analysis using FinBERT ONNX\n- Options trading signal generation (BUY_CALL, BUY_PUT, SELL_CALL, SELL_PUT)\n- Risk-adjusted return calculations (Sharpe, Sortino, Calmar ratios)\n- Portfolio risk metrics (VaR, Expected Shortfall)\n- Kelly Criterion position sizing\n- Greeks calculation (Delta, Gamma, Theta, Vega)\n\n**Example Response:**\n```json\n{\n  \"market_summary\": {\n    \"timestamp\": \"2024-01-15T18:12:02.123Z\",\n    \"total_signals\": 15,\n    \"bullish_signals\": 12,\n    \"bearish_signals\": 3,\n    \"high_confidence_signals\": 8,\n    \"market_sentiment\": \"BULLISH\",\n    \"overall_confidence\": 0.78,\n    \"risk_level\": \"MEDIUM\",\n    \"recommended_position_size\": 15.6\n  },\n  \"trading_signals\": [\n    {\n      \"symbol\": \"NVTS\",\n      \"signal_type\": \"BUY_CALL\",\n      \"confidence\": 0.85,\n      \"sentiment_score\": 0.94,\n      \"risk_score\": 0.35,\n      \"expected_return\": 0.75,\n      \"max_loss\": 1.25,\n      \"time_horizon\": \"SHORT_TERM\",\n      \"entry_price\": 1.25,\n      \"strike_price\": 15.0,\n      \"expiration_date\": \"2024-01-19\",\n      \"volume\": 1500,\n      \"open_interest\": 2500,\n      \"implied_volatility\": 0.45,\n      \"delta\": 0.6,\n      \"gamma\": 0.05,\n      \"theta\": -0.02,\n      \"vega\": 0.1,\n      \"financial_metrics\": {\n        \"sharpe_ratio\": 1.25,\n        \"sortino_ratio\": 1.45,\n        \"calmar_ratio\": 2.1,\n        \"max_drawdown\": 0.15,\n        \"volatility\": 0.28,\n        \"composite_score\": 1.6,\n        \"kelly_fraction\": 0.35,\n        \"var_95\": 0.46,\n        \"expected_shortfall\": 0.56\n      },\n      \"reasoning\": [\n        \"Sentiment: call (confidence: 0.94)\",\n        \"High volume\",\n        \"Low cost entry\",\n        \"Strong risk-adjusted returns\"\n      ]\n    }\n  ],\n  \"sentiment_analysis\": [\n    {\n      \"headline\": \"Apple's New AI Feature Boosts Stock\",\n      \"symbols\": [\"AAPL\"],\n      \"sentiment\": \"Positive\",\n      \"confidence\": 0.94\n    }\n  ],\n  \"risk_metrics\": {\n    \"portfolio_var\": 0.12,\n    \"max_portfolio_drawdown\": 0.25,\n    \"correlation_matrix\": [[1.0, 0.3], [0.3, 1.0]],\n    \"diversification_score\": 0.85,\n    \"sector_exposure\": {\n      \"TECH\": 0.3,\n      \"FINANCE\": 0.2,\n      \"HEALTHCARE\": 0.2,\n      \"OTHER\": 0.3\n    },\n    \"volatility_regime\": \"NORMAL\"\n  },\n  \"execution_metadata\": {\n    \"processing_time_ms\": 2450,\n    \"symbols_analyzed\": 42,\n    \"options_analyzed\": 15,\n    \"crypto_symbols_filtered\": 5,\n    \"api_calls_made\": 43,\n    \"cache_hit_rate\": 0.0\n  }\n}\n```\n\n### 2. Health Check\n**`GET /health`**\n\nReturns API health status and version information.\n\n```json\n{\n  \"status\": \"healthy\",\n  \"timestamp\": \"2024-01-15T18:12:02.123Z\",\n  \"version\": \"0.1.0\"\n}\n```\n\n### 3. Metrics\n**`GET /metrics`**\n\nReturns configuration and system metrics.\n\n```json\n{\n  \"config\": {\n    \"max_concurrent_requests\": 10,\n    \"alpaca_base_url\": \"https://paper-api.alpaca.markets\"\n  },\n  \"timestamp\": \"2024-01-15T18:12:02.123Z\"\n}\n```\n\n## 🤖 Trading Bot Integration Guide\n\n### Python Integration Example\n\n```python\nimport requests\nimport json\nfrom typing import Dict, List, Optional\nfrom dataclasses import dataclass\nfrom datetime import datetime\nimport time\n\n@dataclass\nclass TradingSignal:\n    symbol: str\n    signal_type: str  # \"BUY_CALL\", \"BUY_PUT\", \"SELL_CALL\", \"SELL_PUT\"\n    confidence: float\n    sentiment_score: float\n    risk_score: float\n    expected_return: float\n    max_loss: float\n    entry_price: float\n    strike_price: float\n    expiration_date: str\n    volume: int\n    open_interest: int\n    implied_volatility: float\n    delta: float\n    gamma: float\n    theta: float\n    vega: float\n    sharpe_ratio: float\n    sortino_ratio: float\n    calmar_ratio: float\n    kelly_fraction: float\n    reasoning: List[str]\n\nclass FinBERTTradingBot:\n    def __init__(self, api_url: str = \"http://127.0.0.1:3000\"):\n        self.api_url = api_url\n        self.session = requests.Session()\n        \n    def get_trading_signals(self) -\u003e Dict:\n        \"\"\"Fetch trading signals from the API\"\"\"\n        try:\n            response = self.session.get(f\"{self.api_url}/analyze\", timeout=60)\n            response.raise_for_status()\n            return response.json()\n        except requests.exceptions.RequestException as e:\n            print(f\"API request failed: {e}\")\n            return None\n    \n    def filter_high_confidence_signals(self, signals: List[TradingSignal], \n                                     min_confidence: float = 0.8,\n                                     max_risk: float = 0.4) -\u003e List[TradingSignal]:\n        \"\"\"Filter signals based on confidence and risk criteria\"\"\"\n        return [\n            signal for signal in signals\n            if signal.confidence \u003e= min_confidence and signal.risk_score \u003c= max_risk\n        ]\n    \n    def calculate_position_size(self, signal: TradingSignal, \n                              portfolio_value: float,\n                              max_risk_per_trade: float = 0.02) -\u003e float:\n        \"\"\"Calculate position size using Kelly Criterion and risk management\"\"\"\n        # Use Kelly fraction for optimal sizing\n        kelly_size = signal.kelly_fraction * portfolio_value\n        \n        # Apply risk management constraints\n        max_loss_amount = portfolio_value * max_risk_per_trade\n        max_position = max_loss_amount / signal.max_loss if signal.max_loss \u003e 0 else 0\n        \n        return min(kelly_size, max_position)\n    \n    def execute_trade(self, signal: TradingSignal, position_size: float):\n        \"\"\"Execute trade through your broker API\"\"\"\n        # Implement your broker-specific trade execution here\n        print(f\"Executing {signal.signal_type} for {signal.symbol}\")\n        print(f\"Position size: ${position_size:,.2f}\")\n        print(f\"Entry price: ${signal.entry_price}\")\n        print(f\"Expected return: {signal.expected_return:.2%}\")\n        print(f\"Max loss: ${signal.max_loss}\")\n        print(f\"Confidence: {signal.confidence:.2%}\")\n        print(f\"Risk score: {signal.risk_score:.2%}\")\n        print(\"---\")\n    \n    def run_trading_cycle(self, portfolio_value: float = 100000):\n        \"\"\"Main trading cycle\"\"\"\n        print(\"🔄 Starting trading cycle...\")\n        \n        # Get market analysis\n        analysis = self.get_trading_signals()\n        if not analysis:\n            print(\"❌ Failed to get trading signals\")\n            return\n        \n        # Extract market summary\n        market_summary = analysis[\"market_summary\"]\n        print(f\"📊 Market Sentiment: {market_summary['market_sentiment']}\")\n        print(f\"📈 Overall Confidence: {market_summary['overall_confidence']:.2%}\")\n        print(f\"⚠️  Risk Level: {market_summary['risk_level']}\")\n        print(f\"💰 Recommended Position Size: {market_summary['recommended_position_size']:.1f}%\")\n        \n        # Process trading signals\n        signals = []\n        for signal_data in analysis[\"trading_signals\"]:\n            signal = TradingSignal(\n                symbol=signal_data[\"symbol\"],\n                signal_type=signal_data[\"signal_type\"],\n                confidence=signal_data[\"confidence\"],\n                sentiment_score=signal_data[\"sentiment_score\"],\n                risk_score=signal_data[\"risk_score\"],\n                expected_return=signal_data[\"expected_return\"],\n                max_loss=signal_data[\"max_loss\"],\n                entry_price=signal_data[\"entry_price\"],\n                strike_price=signal_data[\"strike_price\"],\n                expiration_date=signal_data[\"expiration_date\"],\n                volume=signal_data[\"volume\"],\n                open_interest=signal_data[\"open_interest\"],\n                implied_volatility=signal_data[\"implied_volatility\"],\n                delta=signal_data[\"delta\"],\n                gamma=signal_data[\"gamma\"],\n                theta=signal_data[\"theta\"],\n                vega=signal_data[\"vega\"],\n                sharpe_ratio=signal_data[\"financial_metrics\"][\"sharpe_ratio\"],\n                sortino_ratio=signal_data[\"financial_metrics\"][\"sortino_ratio\"],\n                calmar_ratio=signal_data[\"financial_metrics\"][\"calmar_ratio\"],\n                kelly_fraction=signal_data[\"financial_metrics\"][\"kelly_fraction\"],\n                reasoning=signal_data[\"reasoning\"]\n            )\n            signals.append(signal)\n        \n        # Filter high-confidence signals\n        high_confidence_signals = self.filter_high_confidence_signals(signals)\n        print(f\"🎯 Found {len(high_confidence_signals)} high-confidence signals\")\n        \n        # Execute trades\n        total_invested = 0\n        for signal in high_confidence_signals:\n            position_size = self.calculate_position_size(signal, portfolio_value)\n            if position_size \u003e 0:\n                self.execute_trade(signal, position_size)\n                total_invested += position_size\n        \n        print(f\"💼 Total invested: ${total_invested:,.2f}\")\n        print(f\"📊 Processing time: {analysis['execution_metadata']['processing_time_ms']}ms\")\n        print(\"✅ Trading cycle completed\")\n\n# Usage example\nif __name__ == \"__main__\":\n    bot = FinBERTTradingBot()\n    \n    # Run single cycle\n    bot.run_trading_cycle(portfolio_value=100000)\n    \n    # Or run continuous monitoring\n    # while True:\n    #     bot.run_trading_cycle(portfolio_value=100000)\n    #     time.sleep(300)  # Wait 5 minutes between cycles\n```\n\n### JavaScript/Node.js Integration\n\n```javascript\nconst axios = require('axios');\n\nclass FinBERTTradingBot {\n    constructor(apiUrl = 'http://127.0.0.1:3000') {\n        this.apiUrl = apiUrl;\n        this.client = axios.create({\n            timeout: 60000,\n            headers: {\n                'Content-Type': 'application/json'\n            }\n        });\n    }\n\n    async getTradingSignals() {\n        try {\n            const response = await this.client.get(`${this.apiUrl}/analyze`);\n            return response.data;\n        } catch (error) {\n            console.error('API request failed:', error.message);\n            return null;\n        }\n    }\n\n    filterSignals(signals, minConfidence = 0.8, maxRisk = 0.4) {\n        return signals.filter(signal =\u003e \n            signal.confidence \u003e= minConfidence \u0026\u0026 signal.risk_score \u003c= maxRisk\n        );\n    }\n\n    calculatePositionSize(signal, portfolioValue, maxRiskPerTrade = 0.02) {\n        const kellySize = signal.financial_metrics.kelly_fraction * portfolioValue;\n        const maxLossAmount = portfolioValue * maxRiskPerTrade;\n        const maxPosition = signal.max_loss \u003e 0 ? maxLossAmount / signal.max_loss : 0;\n        \n        return Math.min(kellySize, maxPosition);\n    }\n\n    async executeTrade(signal, positionSize) {\n        // Implement your broker-specific trade execution here\n        console.log(`Executing ${signal.signal_type} for ${signal.symbol}`);\n        console.log(`Position size: $${positionSize.toLocaleString()}`);\n        console.log(`Entry price: $${signal.entry_price}`);\n        console.log(`Expected return: ${(signal.expected_return * 100).toFixed(2)}%`);\n        console.log(`Confidence: ${(signal.confidence * 100).toFixed(2)}%`);\n        console.log('---');\n    }\n\n    async runTradingCycle(portfolioValue = 100000) {\n        console.log('🔄 Starting trading cycle...');\n\n        const analysis = await this.getTradingSignals();\n        if (!analysis) {\n            console.log('❌ Failed to get trading signals');\n            return;\n        }\n\n        const { market_summary, trading_signals } = analysis;\n\n        console.log(`📊 Market Sentiment: ${market_summary.market_sentiment}`);\n        console.log(`📈 Overall Confidence: ${(market_summary.overall_confidence * 100).toFixed(2)}%`);\n        console.log(`⚠️  Risk Level: ${market_summary.risk_level}`);\n\n        const highConfidenceSignals = this.filterSignals(trading_signals);\n        console.log(`🎯 Found ${highConfidenceSignals.length} high-confidence signals`);\n\n        let totalInvested = 0;\n        for (const signal of highConfidenceSignals) {\n            const positionSize = this.calculatePositionSize(signal, portfolioValue);\n            if (positionSize \u003e 0) {\n                await this.executeTrade(signal, positionSize);\n                totalInvested += positionSize;\n            }\n        }\n\n        console.log(`💼 Total invested: $${totalInvested.toLocaleString()}`);\n        console.log(`📊 Processing time: ${analysis.execution_metadata.processing_time_ms}ms`);\n        console.log('✅ Trading cycle completed');\n    }\n}\n\n// Usage\nconst bot = new FinBERTTradingBot();\nbot.runTradingCycle(100000);\n```\n\n## 📈 Signal Interpretation Guide\n\n### Signal Types\n- **`BUY_CALL`**: Bullish sentiment, buy call options\n- **`BUY_PUT`**: Bearish sentiment, buy put options\n- **`SELL_CALL`**: Bearish sentiment, sell call options (covered calls)\n- **`SELL_PUT`**: Bullish sentiment, sell put options (cash-secured puts)\n\n### Confidence Levels\n- **0.9+**: Very high confidence - Strong signal\n- **0.8-0.9**: High confidence - Good signal\n- **0.7-0.8**: Medium confidence - Moderate signal\n- **\u003c0.7**: Low confidence - Weak signal\n\n### Risk Scores\n- **0.0-0.3**: Low risk\n- **0.3-0.7**: Medium risk\n- **0.7-1.0**: High risk\n\n### Financial Metrics\n- **Sharpe Ratio**: \u003e1.0 = Good risk-adjusted returns\n- **Sortino Ratio**: \u003e1.0 = Good downside risk management\n- **Calmar Ratio**: \u003e1.0 = Good return vs drawdown\n- **Kelly Fraction**: Optimal position sizing (0.0-1.0)\n\n## ⚙️ Configuration\n\n### Environment Variables\n\n**Required:**\n```bash\nAPCA_API_KEY_ID=your_alpaca_api_key\nAPCA_API_SECRET_KEY=your_alpaca_secret_key\n```\n\n**Optional:**\n```bash\n# Alpaca API Configuration\nAPCA_BASE_URL=https://paper-api.alpaca.markets\n\n# Server Configuration\nSERVER_HOST=127.0.0.1                    # Use 0.0.0.0 for external access\nSERVER_PORT=3000                         # Change port here\nREQUEST_TIMEOUT_SECS=60                  # Request timeout in seconds\n\n# Model Configuration\nSENTIMENT_MODEL_PATH=finbert-onnx        # Path to ONNX model directory\nMAX_TEXT_LENGTH=10000                    # Maximum text length for analysis\n\n# Performance Configuration\nMAX_CONCURRENT_REQUESTS=10               # Reduce to 5 for Raspberry Pi\nRUST_LOG=info                            # Logging level (debug, info, warn, error)\n```\n\n### Performance Tuning\n\nThe API is optimized for Raspberry Pi with these default settings:\n- **Memory limit**: 1GB (configurable in systemd service)\n- **Concurrent requests**: 10 (reduce to 5 for Pi 3B+)\n- **Model caching**: 5-minute TTL for sentiment results\n- **Options caching**: 3-minute TTL for options data\n\n## 🔧 Deployment Options\n\n### 1. Automated Setup (Recommended)\nThe `setup-rpi.sh` script handles everything automatically:\n\n```bash\n./setup-rpi.sh\n```\n\nThis creates a systemd service with these features:\n- Auto-start on boot\n- Automatic restart on failure\n- Resource limits optimized for Raspberry Pi\n- Centralized logging via journalctl\n\n### 2. Manual Deployment\n\n#### Build and Run\n```bash\n# Build the application\ncargo build --release\n\n# Run directly (for testing)\n./run.sh\n\n# Or run with environment variables\nAPCA_API_KEY_ID=your_key APCA_API_SECRET_KEY=your_secret ./target/release/finbert-rust-options-api\n```\n\n#### Systemd Service (Manual Setup)\nThe setup script creates this service file at `/etc/systemd/system/finbert-api.service`:\n\n```ini\n[Unit]\nDescription=FinBERT Sentiment Analysis API\nAfter=network.target\n\n[Service]\nType=simple\nUser=$USER\nWorkingDirectory=$(pwd)\nEnvironmentFile=$(pwd)/.env\nExecStart=$(pwd)/target/release/finbert-rust-options-api\nRestart=on-failure\nRestartSec=5\nStandardOutput=journal\nStandardError=journal\n\n# Resource limits for Raspberry Pi\nLimitNOFILE=65536\nMemoryMax=1G\n\n[Install]\nWantedBy=multi-user.target\n```\n\n### 3. Docker Deployment (Optional)\n```dockerfile\nFROM rust:1.70 as builder\nWORKDIR /app\nCOPY . .\nRUN cargo build --release\n\nFROM debian:bullseye-slim\nRUN apt-get update \u0026\u0026 apt-get install -y ca-certificates \u0026\u0026 rm -rf /var/lib/apt/lists/*\nCOPY --from=builder /app/target/release/finbert-rust-options-api /usr/local/bin/\nCOPY --from=builder /app/finbert-onnx /app/finbert-onnx\nEXPOSE 3000\nCMD [\"finbert-rust-options-api\"]\n```\n\n## 📊 Monitoring \u0026 Management\n\n### Health Checks\n```bash\n# Check API health and model status\ncurl http://localhost:3000/health\n\n# View system metrics and configuration\ncurl http://localhost:3000/metrics\n```\n\n### Service Management\nThe setup script creates these management commands:\n\n```bash\n# Start the API service\n./start-api.sh\n\n# Stop the API service  \n./stop-api.sh\n\n# Check service status\n./status-api.sh\n\n# View real-time logs\n./logs-api.sh\n```\n\n### Logging\nThe API provides structured logging via systemd journal:\n- Request processing times\n- Model loading status\n- Error rates and types\n- API call counts and caching statistics\n\n### Performance Metrics\n- **Processing Time**: 2-5 seconds per analysis\n- **Memory Usage**: ~600MB on Raspberry Pi 4\n- **Model Loading**: 10-15 seconds on first startup\n- **Cache Hit Rate**: 70%+ for repeated requests\n\n## 🚨 Risk Management\n\n### Position Sizing\n```python\n# Conservative approach\nposition_size = min(\n    signal.kelly_fraction * portfolio_value,\n    portfolio_value * 0.02 / signal.max_loss  # 2% max risk per trade\n)\n```\n\n### Stop Losses\n```python\n# Set stop loss based on max_loss\nstop_loss = signal.entry_price - signal.max_loss\n```\n\n### Portfolio Limits\n```python\n# Maximum portfolio exposure\nmax_portfolio_exposure = 0.20  # 20% of portfolio\nmax_single_position = 0.05     # 5% per position\n```\n\n## 🔍 Troubleshooting\n\n### Common Issues\n\n1. **Model Loading Slow**\n   - First request takes 10-15 seconds (model initialization)\n   - Subsequent requests are fast (2-5 seconds)\n   - This is normal behavior\n\n2. **API Timeouts**\n   - Default timeout: 60 seconds\n   - Increase `REQUEST_TIMEOUT_SECS` in `.env` if needed\n   - Check Alpaca API status at https://status.alpaca.markets\n\n3. **High Memory Usage**\n   - FinBERT model requires ~600MB RAM on Raspberry Pi\n   - Monitor with: `free -h`\n   - Restart service if memory usage exceeds 1GB\n\n4. **No Trading Signals**\n   - Check if news headlines contain stock symbols\n   - Verify Alpaca API credentials in `.env`\n   - API works 24/7 but news volume varies\n\n5. **Service Won't Start**\n   - Check service status: `./status-api.sh`\n   - View logs: `./logs-api.sh`\n   - Verify `.env` file exists and has correct credentials\n\n### Debug Mode\n```bash\n# Run with debug logging\nRUST_LOG=debug ./target/release/finbert-rust-options-api\n\n# Or check service logs with debug level\nsudo journalctl -u finbert-api.service -f\n```\n\n## 🔒 Security \u0026 Risk Management\n\n### API Security\n- API runs on local network by default (`127.0.0.1`)\n- Configure `SERVER_HOST=0.0.0.0` in `.env` for external access\n- Use reverse proxy (nginx) for production internet exposure\n- API keys stored securely in environment variables\n- Input validation prevents malicious payloads\n- Request size limits (1MB) and timeout protection\n\n### Trading Risk Controls\nThe API includes built-in risk management:\n\n1. **Position Sizing** - Kelly Criterion for optimal sizing\n2. **Risk Filtering** - Filters out high-risk signals (\u003e90% risk score)\n3. **Liquidity Checks** - Prefers high-volume, high open-interest options\n4. **Fundamental Risk Assessment** - Evaluates sector and company-specific risks\n5. **Portfolio Limits** - Calculates diversification and exposure metrics\n\n### Recommended Risk Management\n```python\n# Conservative position sizing\nposition_size = min(\n    signal.kelly_fraction * portfolio_value,\n    portfolio_value * 0.02 / signal.max_loss  # 2% max risk per trade\n)\n\n# Portfolio limits\nmax_portfolio_exposure = 0.20  # 20% of portfolio\nmax_single_position = 0.05     # 5% per position\n```\n\n## 🧠 Technical Architecture\n\n### Core Components\n\n1. **FinBERT ONNX Model** (`src/onnx_sentiment.rs`)\n   - Pre-trained financial sentiment analysis model\n   - Optimized for inference with ONNX Runtime\n   - Supports batch processing for efficiency\n   - Caching layer for repeated headlines\n\n2. **Alpaca Data Integration** (`src/alpaca_data.rs`)\n   - Fetches real-time financial news\n   - Retrieves options chain data\n   - Filters out crypto symbols (no traditional options)\n   - Implements retry logic and caching\n\n3. **Signal Generation Engine** (`src/alpaca_data.rs`)\n   - Analyzes options contracts for high open interest\n   - Calculates financial metrics (Sharpe, Sortino, Calmar ratios)\n   - Applies Kelly Criterion for position sizing\n   - Generates Greeks (Delta, Gamma, Theta, Vega)\n\n4. **Risk Management** (`src/alpaca_data.rs`)\n   - Portfolio-level risk assessment\n   - Value at Risk (VaR) calculations\n   - Expected Shortfall estimation\n   - Sector exposure analysis\n\n### Data Flow\n\n```\nAlpaca News API → Symbol Extraction → Sentiment Analysis → Options Analysis → Signal Generation → Risk Assessment → JSON Response\n```\n\n## 📈 Signal Interpretation Guide\n\n### Signal Types\n- **`BUY_CALL`**: Bullish sentiment, buy call options\n- **`BUY_PUT`**: Bearish sentiment, buy put options\n- **`SELL_CALL`**: Bearish sentiment, sell call options (covered calls)\n- **`SELL_PUT`**: Bullish sentiment, sell put options (cash-secured puts)\n\n### Confidence Levels\n- **0.9+**: Very high confidence - Strong signal\n- **0.8-0.9**: High confidence - Good signal\n- **0.7-0.8**: Medium confidence - Moderate signal\n- **\u003c0.7**: Low confidence - Weak signal\n\n### Risk Scores\n- **0.0-0.3**: Low risk\n- **0.3-0.7**: Medium risk\n- **0.7-1.0**: High risk\n\n### Financial Metrics\n- **Sharpe Ratio**: \u003e1.0 = Good risk-adjusted returns\n- **Sortino Ratio**: \u003e1.0 = Good downside risk management\n- **Calmar Ratio**: \u003e1.0 = Good return vs drawdown\n- **Kelly Fraction**: Optimal position sizing (0.0-1.0)\n\n## 📚 API Response Schema\n\n### Market Summary\n```typescript\ninterface MarketSummary {\n  timestamp: string;\n  total_signals: number;\n  bullish_signals: number;\n  bearish_signals: number;\n  high_confidence_signals: number;\n  market_sentiment: \"BULLISH\" | \"BEARISH\" | \"NEUTRAL\";\n  overall_confidence: number;\n  risk_level: \"LOW\" | \"MEDIUM\" | \"HIGH\";\n  recommended_position_size: number;\n}\n```\n\n### Trading Signal\n```typescript\ninterface TradingSignal {\n  symbol: string;\n  signal_type: \"BUY_CALL\" | \"BUY_PUT\" | \"SELL_CALL\" | \"SELL_PUT\";\n  confidence: number;\n  sentiment_score: number;\n  risk_score: number;\n  expected_return: number;\n  max_loss: number;\n  time_horizon: \"SHORT_TERM\" | \"LEAP\";\n  entry_price: number;\n  strike_price: number;\n  expiration_date: string;\n  volume: number;\n  open_interest: number;\n  implied_volatility: number;\n  delta: number;\n  gamma: number;\n  theta: number;\n  vega: number;\n  financial_metrics: FinancialMetrics;\n  reasoning: string[];\n}\n```\n\n## 🐞 Advanced Troubleshooting\n\n### Build Issues\n**Build fails on Raspberry Pi:**\n- Ensure you have enough RAM (4GB+ recommended)\n- Try: `sudo swapoff -a \u0026\u0026 sudo swapon -a` to clear swap\n- Check: `free -h` for available memory\n\n**Memory issues during build:**\n```bash\n# Increase swap space\nsudo fallocate -l 2G /swapfile\nsudo chmod 600 /swapfile\nsudo mkswap /swapfile\nsudo swapon /swapfile\n```\n\n### Model Issues\n**Model not loading:**\n- Check: `ls -la finbert-onnx/` for model files\n- Verify model files: `model.onnx`, `tokenizer.json`, `config.json`\n- Try: `git clone https://huggingface.co/jonngan/finbert-onnx` manually\n- Ensure Git LFS is installed: `git lfs install`\n\n### Service Issues\n**Service won't start:**\n- Check: `./status-api.sh` for error messages\n- Verify: `.env` file has correct API credentials\n- View: `./logs-api.sh` for detailed error info\n- Check file permissions: `ls -la target/release/finbert-rust-options-api`\n\n**Service won't start after reboot:**\n```bash\n# Check service status\nsudo systemctl status finbert-api\n\n# View logs\nsudo journalctl -u finbert-api -f\n\n# Verify environment variables\nsudo systemctl show finbert-api --property=Environment\n\n# Reload service configuration\nsudo systemctl daemon-reload\nsudo systemctl restart finbert-api\n```\n\n### API Issues\n**API returns errors:**\n```bash\n# Check API health\ncurl http://localhost:3000/health\n\n# View application logs\nsudo journalctl -u finbert-api -n 50\n\n# Test with verbose logging\nRUST_LOG=debug ./target/release/finbert-rust-options-api\n```\n\n**ONNX Runtime issues:**\nIf you see ONNX-related errors:\n```bash\n# Clean build cache\ncargo clean\n\n# Rebuild with fresh dependencies\ncargo build --release\n\n# Check ONNX model integrity\nfile finbert-onnx/model.onnx\n```\n\n## 🔧 Development\n\n### Building from Source\n```bash\ngit clone https://github.com/jongan69/finbert-rust-options-api   \ncd finbert-rust-options-api\ncargo build --release\n```\n\n### Running Tests\n```bash\ncargo test\n```\n\n### Code Quality\n```bash\n# Check code quality\ncargo clippy\n\n# Format code\ncargo fmt\n\n# Security audit\ncargo audit\n```\n\n### Dependencies\nKey dependencies in `Cargo.toml`:\n- **axum** - HTTP server framework\n- **ort** - ONNX Runtime for model inference\n- **tokenizers** - Text tokenization\n- **minreq** - HTTP client for Alpaca API\n- **serde** - JSON serialization/deserialization\n- **tokio** - Async runtime\n- **dashmap** - Concurrent hash maps for caching\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch: `git checkout -b feature-name`\n3. Make your changes\n4. Run tests: `cargo test`\n5. Run clippy: `cargo clippy`\n6. Submit a pull request\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n## ⚠️ Disclaimer\n\n**IMPORTANT:** This software is for educational and research purposes only. Trading involves substantial risk of loss and is not suitable for all investors. Past performance does not guarantee future results. Always consult with a financial advisor before making investment decisions.\n\nThe sentiment analysis and trading signals provided by this API should not be considered as investment advice. Users are responsible for their own trading decisions and any resulting losses.\n\n## 🆘 Support\n\n- **Issues**: Create an issue on GitHub\n- **Documentation**: Check this README and inline code comments  \n- **Updates**: Star the repository to get notified of updates\n\n---\n\n**Happy Trading! 🚀📈**","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjongan69%2Ffinbert-rust-options-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjongan69%2Ffinbert-rust-options-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjongan69%2Ffinbert-rust-options-api/lists"}