The Finance Feedback Engine is a Python-based tool designed to provide validation and feedback for financial data processing, particularly for applications interacting with market data APIs like Alpha Vantage.
This project currently offers a set of utility functions for standardizing inputs and validating data quality.
The Finance Feedback Engine 2.0 is a comprehensive AI-powered trading decision tool that uses real-time market data to generate trading signals. It offers a wide array of features including multi-timeframe technical analysis, autonomous trading capabilities, robust ensemble AI integration, and real-time portfolio tracking across multiple platforms.
For a detailed overview of all features, their functionality, architecture, and usage, please refer to the Features Documentation.
The Finance Feedback Engine 2.0 is built with a modular, scalable architecture designed for real-time trading decisions, backtesting, and performance analysis. The system is composed of several key components, each with a specific responsibility.
For a comprehensive overview of the project's architecture, including detailed component breakdowns, class hierarchies, and technical designs, please refer to the Architecture Documentation.
graph TB
subgraph "Entry Points"
CLI[CLI Commands<br/>main.py]
WEB[Web Service<br/>FastAPI + Redis<br/>Optional]
TELEGRAM[Telegram Bot<br/>Approval Integration]
end
subgraph "Core Orchestration"
ENGINE[FinanceFeedbackEngine<br/>core.py]
AGENT[TradingLoopAgent<br/>Autonomous OODA Loop]
end
subgraph "Data Layer"
AV[Alpha Vantage<br/>Market Data]
UDP[UnifiedDataProvider<br/>Multi-Timeframe Pulse]
MRD[MarketRegimeDetector<br/>ADX/ATR Analysis]
end
subgraph "Decision Making"
DE[DecisionEngine<br/>Prompt Builder]
ENS[EnsembleManager<br/>Multi-Provider Voting]
subgraph "AI Providers"
LOCAL[Local/Ollama]
CLI_AI[GitHub Copilot CLI]
CODEX[Codex CLI]
QWEN[Qwen CLI]
GEMINI[Gemini CLI]
end
end
subgraph "Risk & Execution"
RG[RiskGatekeeper<br/>Drawdown/VaR/Correlation]
PF[PlatformFactory]
subgraph "Trading Platforms"
CB[Coinbase Advanced]
OA[Oanda Forex]
MOCK[Mock Platform]
UNI[UnifiedPlatform]
end
CB_BREAKER[CircuitBreaker<br/>Failure Protection]
end
subgraph "Monitoring & Learning"
TM[TradeMonitor<br/>Live Position Tracking]
PME[PortfolioMemoryEngine<br/>ML Feedback Loop]
MCP[MonitoringContextProvider<br/>Pulse Integration]
end
subgraph "Persistence"
DS[DecisionStore<br/>JSON Storage]
TMC[TradeMetricsCollector<br/>Performance Data]
end
CLI -->|analyze/execute/agent| ENGINE
WEB -->|approval request| TELEGRAM
TELEGRAM -->|approval/deny| ENGINE
AGENT -->|continuous loop| ENGINE
ENGINE -->|fetch data| AV
AV -->|OHLCV + sentiment| UDP
UDP -->|6 timeframes| MRD
MRD -->|regime + volatility| DE
ENGINE -->|generate decision| DE
DE -->|ensemble mode| ENS
ENS -.->|weighted voting| LOCAL
ENS -.->|dynamic weights| CLI_AI
ENS -.->|fallback tiers| CODEX
ENS -.->|4-tier strategy| QWEN
ENS -.->|quorum check| GEMINI
DE -->|position sizing| RG
RG -->|risk approved| PF
PF -->|create platform| CB
PF --> OA
PF --> MOCK
PF --> UNI
CB --> CB_BREAKER
CB_BREAKER -->|execute trade| TM
TM -->|detect positions| MCP
MCP -->|inject context| DE
TM -->|track P&L| PME
PME -->|trade outcomes| DE
DE -->|save decision| DS
TM -->|save metrics| TMC
PME -->|experience buffer| ENGINE
style ENGINE fill:#4CAF50,stroke:#2E7D32,color:#fff
style ENS fill:#FF9800,stroke:#E65100,color:#fff
style AGENT fill:#2196F3,stroke:#0D47A1,color:#fff
style TM fill:#9C27B0,stroke:#4A148C,color:#fff
style WEB fill:#f5f5f5,stroke:#999,color:#333,stroke-dasharray: 5 5
Data Flow Summary:
- Analysis Request → CLI/Agent invokes
FinanceFeedbackEngine.analyze_asset() - Data Gathering → Alpha Vantage provides multi-timeframe market data + sentiment
- Regime Detection → ADX/ATR classifies market conditions (trending/ranging/volatile)
- Decision Generation → AI providers analyze context, ensemble aggregates recommendations
- Risk Validation → RiskGatekeeper checks drawdown, VaR, position concentration
- Execution → Platform factory routes to Coinbase/Oanda/Mock with circuit breaker protection
- Monitoring → TradeMonitor detects positions, tracks real-time P&L
- Learning → Completed trades feed PortfolioMemoryEngine for continuous improvement
New in 2.0: Optional web service layer enables mobile approvals via Telegram bot. This is completely optional - all core features work in CLI-only mode. For more details, see the Guides and Quick Starts.
- Python 3.13
- Alpha Vantage API key (premium recommended)
- Trading platform credentials (Coinbase, Oanda, etc.)
Sentiment Source: News sentiment uses Alpha Vantage NEWS_SENTIMENT; no Twitter or on-chain dependencies are required.
- Redis 5.x+ (auto-setup available)
- Telegram bot token (from @BotFather)
- HTTPS domain (production) or ngrok (development)
Note: Web service is optional - CLI mode works independently. See Web Service Migration Guide for details.
git clone https://github.com/Three-Rivers-Tech/finance_feedback_engine-2.0.git
cd finance_feedback_engine-2.0- Runtime:
pip install . - Dev/Test:
pip install ".[dev]" - Data pipeline (optional):
pip install ".[pipeline]"
Note on Technical Indicators (pandas-ta): The multi-timeframe pulse system uses pandas-ta for technical analysis:
- ✅ Pure Python - No compilation required (unlike TA-Lib)
- ✅ Python 3.13 Compatible - Works with latest Python versions
- ✅ No System Dependencies - No need for C libraries or build tools
- ✅ Easy Deployment - Simpler installation on cloud/Docker
pip install . will pull the correct pandas-ta variant for your Python version automatically.
Or install in development mode:
pip install -e .Quick Setup:
./scripts/setup-hooks.shThis installs pre-commit hooks that automatically check code quality, prevent secrets from being committed, and enforce test coverage before each commit.
What's included:
- Code formatting (black, isort)
- Linting (flake8, mypy)
- Security scanning (bandit, secret detection)
- Test coverage enforcement (≥70%)
Manual setup:
pip install pre-commit
pre-commit installFor more details, see Pre-commit Configuration Guide.
Note: This step is optional for users who only want to run the engine, but required for contributors.
Quick Setup (Recommended):
# Copy .env template and fill in your API keys
cp .env.example .env
nano .env # or vim, code, etc.The .env file is now the single source of truth for all configuration. Edit it with your:
Alternative: For advanced users, you can create config/config.local.yaml with environment variable references:
cp config/config.yaml config/config.local.yamlPrecedence: Environment Variables (.env) > config.local.yaml > config/config.yaml (defaults)
flowchart TD
START([Configuration Loading Starts])
DOTENV[Load .env File First]
ENV{Environment Variables Set?}
LOCAL{config.local.yaml Exists?}
BASE[config/config.yaml Base Defaults]
MERGE[Merge Configuration Precedence: ENV > LOCAL > BASE]
VALIDATE[Validate Required Keys API keys, credentials]
RESULT([Final Config Object])
START --> DOTENV
DOTENV --> ENV
LOCAL{config.local.yaml Exists?}
BASE[config/config.yaml Base Defaults]
MERGE[Merge Configuration Precedence: ENV > LOCAL > BASE]
VALIDATE[Validate Required Keys API keys, credentials]
RESULT([Final Config Object])
START --> ENV
ENV -->|Yes| MERGE
ENV -->|No| LOCAL
LOCAL -->|Yes| MERGE
LOCAL -->|No| BASE
BASE --> MERGE
MERGE --> VALIDATE
VALIDATE --> RESULT
subgraph "Environment Variables Highest Priority"
ENV_AV[ALPHA_VANTAGE_API_KEY]
ENV_CB[COINBASE_API_KEY COINBASE_API_SECRET]
ENV_OA[OANDA_API_KEY OANDA_ACCOUNT_ID]
end
The engine analyzes 6 timeframes simultaneously to detect cross-timeframe patterns and confluence:
Timeframes: 1-min, 5-min, 15-min, 1-hour, 4-hour, daily
flowchart LR
subgraph "Data Ingestion"
REQ[Analysis Request BTCUSD]
UDP[UnifiedDataProvider aggregate_all_timeframes]
CACHE{Cache Valid? 5-min expiry}
end
subgraph "Multi-Source Fetching"
AV[Alpha Vantage Premium API]
CB_DATA[Coinbase Real-time]
OA_DATA[Oanda Forex data]
end
subgraph "6 Timeframes"
TF1[1-minute]
TF5[5-minute]
TF15[15-minute]
TF1H[1-hour]
TF4H[4-hour]
TFD[Daily]
end
subgraph "Technical Indicators"
RSI[RSI Overbought/Oversold 70/30]
MACD[MACD Momentum Line, Signal, Histogram]
BB[Bollinger Bands Volatility upper/middle/lower]
ADX[ADX Trend Strength >25 strong]
ATR[ATR Volatility Measure Price Units]
end
CLASSIFY[Trend Classification UPTREND/DOWNTREND/RANGING]
subgraph "Cross-Timeframe Analysis"
CONF[Confluence Score Agreement Count]
STRENGTH[Signal Strength 0-100]
DESC[Natural Language Description]
end
REQ --> UDP
UDP --> CACHE
CACHE -->|Hit| TF1 & TF5 & TF15 & TF1H & TF4H & TFD
CACHE -->|Miss| AV
CACHE -->|Miss| CB_DATA
CACHE -->|Miss| OA_DATA
AV & CB_DATA & OA_DATA --> TF1 & TF5 & TF15 & TF1H & TF4H & TFD
TF1 & TF5 & TF15 & TF1H & TF4H & TFD --> RSI
TF1 & TF5 & TF15 & TF1H & TF4H & TFD --> MACD
TF1 & TF5 & TF15 & TF1H & TF4H & TFD --> BB
TF1 & TF5 & TF15 & TF1H & TF4H & TFD --> ADX
TF1 & TF5 & TF15 & TF1H & TF4H & TFD --> ATR
RSI & MACD & BB & ADX & ATR --> CLASSIFY
CLASSIFY --> CONF & STRENGTH & DESC
style UDP fill:#2196F3,stroke:#0D47A1,color:#fff
style CONF fill:#4CAF50,stroke:#2E7D32,color:#fff
Indicators: RSI, MACD, Bollinger Bands, ADX, ATR (per timeframe)
Features:
- Confluence Detection: Identifies when multiple timeframes agree on direction
- Regime-Aware: Different strategies for trending vs. ranging markets
- Volatility Context: ATR provides risk-adjusted position sizing inputs
- Reduced False Signals: Cross-timeframe validation filters noise
- LLM-Optimized: Natural language summaries for better AI comprehension
Pulse System Benefits:
- Confluence Detection: Identifies when multiple timeframes agree on direction
- Regime-Aware: Different strategies for trending vs. ranging markets
- Volatility Context: ATR provides risk-adjusted position sizing inputs
- Reduced False Signals: Cross-timeframe validation filters noise
- LLM-Optimized: Natural language summaries for better AI comprehension
See MULTI_TIMEFRAME_PULSE_COMPLETE.md for implementation details.
Combine multiple AI providers for more robust decisions with intelligent fallback strategies:
# Analyze with ensemble mode (combines all providers)
python main.py analyze BTCUSD --provider ensemblegraph TD
START([Ensemble Request Initiated])
START --> QUERY[Query All Enabled Providers in Parallel]
subgraph "Providers"
P1[local]
P2[codex]
P3[cli]
P4[qwen]
P5[gemini]
end
QUERY --> P1
QUERY --> P2
QUERY --> P3
QUERY --> P4
QUERY --> P5
P1 --> COLLECT{Collect Responses}
P2 --> COLLECT
P3 --> COLLECT
P4 --> COLLECT
P5 --> COLLECT
COLLECT --> DETECT[Detect Provider Failures]
DETECT --> CALC_WEIGHTS[Dynamic Weight Recalculation\nRenormalize weights of active providers]
subgraph "Example: Weight Adjustment"
direction LR
ORIG[Original Weights\nlocal=0.25, cli=0.25,\ncodex=0.25, qwen=0.25]
FAIL[cli FAILED]
ACTIVE[Active Sum = 0.75\n3/4 providers]
ADJ[Adjusted Weights\nlocal=0.333 from 0.25/0.75\ncodex=0.333\nqwen=0.333]
ORIG --> FAIL
FAIL --> ACTIVE
ACTIVE --> ADJ
end
CALC_WEIGHTS --> T1
subgraph "4-Tier Fallback Strategy"
direction TB
T1{Tier 1: Weighted Voting}
T2{Tier 2: Majority Voting}
T3{Tier 3: Simple Averaging}
T4[Tier 4: Single Best Provider]
T1 -->|Fails or No Weights| T2
T2 -->|No Majority| T3
T3 -->|Fails| T4
end
T1 --> AGG_RESULT
T2 --> AGG_RESULT
T3 --> AGG_RESULT
T4 --> AGG_RESULT
AGG_RESULT{Aggregated Result} --> CONFIDENCE[Confidence Adjustment]
CONFIDENCE --> QUORUM{Local Provider Quorum Met?}
QUORUM -- Yes --> META[Attach Ensemble Metadata]
QUORUM -- No --> PENALTY[Apply 30% Confidence Penalty]
PENALTY --> META
META --> DECISION
DECISION([Final Aggregated Decision])
style T1 fill:#4CAF50,stroke:#2E7D32,color:#fff
style T2 fill:#FFC107,stroke:#F57C00,color:#333
style T3 fill:#FF9800,stroke:#E65100,color:#fff
style T4 fill:#F44336,stroke:#C62828,color:#fff
style CALC_WEIGHTS fill:#2196F3,stroke:#0D47A1,color:#fff
style PENALTY fill:#FF5722,stroke:#BF360C,color:#fff
style ADJ fill:#9C27B0,stroke:#4A148C,color:#fff
Features:
- Intelligent Voting: Combines decisions from multiple AI providers using weighted voting (Tier 1)
- Dynamic Weight Adjustment: Automatically renormalizes weights when providers fail
- 4-Tier Fallback: Progressive degradation (weighted → majority → averaging → single provider)
- Resilient: Continues working even when most providers are unavailable
- Transparent: Full metadata shows which providers succeeded/failed and how weights were adjusted
- Quorum Protection: Requires minimum 3 local providers; applies 30% confidence penalty if not met
Example metadata when one provider fails:
{
"ensemble_metadata": {
"providers_used": ["local", "codex", "qwen"],
"providers_failed": ["gemini"],
"adjusted_weights": {"local": 0.333, "codex": 0.333, "qwen": 0.333},
"fallback_tier": 1,
"quorum_penalty_applied": false
}
}See docs/DYNAMIC_WEIGHT_ADJUSTMENT.md and docs/ENSEMBLE_FALLBACK_SYSTEM.md for complete details.
The engine supports five AI providers:
-
Ensemble (
--provider ensemble): Combines multiple providers with weighted voting 🆕- Automatically handles provider failures
- Configurable weights and voting strategies
- Best for production use with high reliability
-
Codex CLI (
--provider codex): Uses the local Codex CLI tool (no API charges)
- Install:
npm install -g @openai/codexor from https://github.com/openai/codex - Runs locally without token costs
- GitHub Copilot CLI (
--provider cli): Uses GitHub Copilot CLI
- Install: Follow Copilot CLI setup
- Requires GitHub Copilot subscription
-
Qwen CLI (
--provider qwen): Uses free Qwen CLI tool- Install: Requires Node.js v20+ and OAuth authentication
- Command:
qwen - Free to use
-
Gemini CLI (
--provider gemini): Uses free Google Gemini CLI- Install:
npm install -g @google/gemini-cli(requires Node.js v20+) - Authentication: OAuth (60 req/min, 1000 req/day) or API key (100 req/day)
- Free tier with Gemini 2.5 Pro access
- Install:
-
Local (
--provider local): Simple rule-based decisions- No setup required
- Good for testing and fallback
Run the autonomous agent with continuous OODA (Observe-Orient-Decide-Act) loop:
python main.py run-agent --take-profit 0.05 --stop-loss 0.02 --max-daily-trades 5stateDiagram-v2
[*] --> STARTUP
STARTUP --> POSITION_RECOVERY: Initialize Agent
state POSITION_RECOVERY {
[*] --> QueryPlatform
QueryPlatform --> ExtractPositions: get_portfolio_breakdown
ExtractPositions --> GenerateSyntheticDecisions: Found N positions
GenerateSyntheticDecisions --> RebuildMemory: Create decision records
RebuildMemory --> AssociateMonitor: Populate PortfolioMemoryEngine
AssociateMonitor --> [*]: Mark startup_complete
QueryPlatform --> RetryBackoff: Failure
RetryBackoff --> QueryPlatform: Exponential delay
QueryPlatform --> ForceComplete: Max retries
ForceComplete --> [*]: Continue with empty state
}
POSITION_RECOVERY --> IDLE: Recovery Complete
state IDLE {
[*] --> WaitInterval
WaitInterval --> [*]: After analysis_frequency_seconds
}
IDLE --> LEARNING: Timer Expires
state LEARNING {
[*] --> FetchClosedTrades
FetchClosedTrades --> ProcessOutcomes: get_closed_trades
ProcessOutcomes --> RecordMemory: PortfolioMemoryEngine
RecordMemory --> [*]: Update experience
}
LEARNING --> PERCEPTION
state PERCEPTION {
[*] --> FetchPortfolio
FetchPortfolio --> KillSwitchCheck: get_portfolio_breakdown
KillSwitchCheck --> DailyReset: P&L within limits
DailyReset --> [*]: Reset trade count
KillSwitchCheck --> HALT: P&L breached
}
PERCEPTION --> REASONING
state REASONING {
[*] --> LoopAssets
LoopAssets --> AnalyzeAsset: For each asset
AnalyzeAsset --> RetryLogic: generate_decision
RetryLogic --> CheckAction: Success
CheckAction --> NextAsset: HOLD
CheckAction --> [*]: BUY/SELL
RetryLogic --> ExponentialBackoff: Failure
ExponentialBackoff --> AnalyzeAsset: Retry
ExponentialBackoff --> MarkFailure: Max retries
MarkFailure --> NextAsset: Skip
NextAsset --> LoopAssets: More assets
NextAsset --> [*]: All processed
}
REASONING --> RISK_CHECK: Actionable
REASONING --> IDLE: No Action
state RISK_CHECK {
[*] --> GetMonitoringContext
GetMonitoringContext --> ValidateTrade: RiskGatekeeper
ValidateTrade --> [*]: Approved
ValidateTrade --> [*]: Denied
}
RISK_CHECK --> EXECUTION: Approved
RISK_CHECK --> PERCEPTION: Rejected
state EXECUTION {
[*] --> SendOrder
SendOrder --> AssociateDecision: execute_trade
AssociateDecision --> IncrementCounter: TradeMonitor
IncrementCounter --> [*]: daily_trade_count++
SendOrder --> LogFailure: Error
LogFailure --> EXECUTION_FAILED
}
EXECUTION --> LEARNING: Executed
EXECUTION_FAILED --> PERCEPTION: Retry
state HALT {
[*] --> StopAgent
StopAgent --> [*]: is_running = False
}
HALT --> [*]: Agent Stopped
style STARTUP fill:#00BCD4,stroke:#006064,color:#fff
style POSITION_RECOVERY fill:#00BCD4,stroke:#006064,color:#fff
style IDLE fill:#9E9E9E,stroke:#424242,color:#fff
style LEARNING fill:#4CAF50,stroke:#2E7D32,color:#fff
style PERCEPTION fill:#2196F3,stroke:#0D47A1,color:#fff
style REASONING fill:#FF9800,stroke:#E65100,color:#fff
style RISK_CHECK fill:#FFC107,stroke:#F57C00,color:#333
style EXECUTION fill:#9C27B0,stroke:#4A148C,color:#fff
style HALT fill:#F44336,stroke:#C62828,color:#fff
style EXECUTION_FAILED fill:#F44336,stroke:#C62828,color:#fff
Agent Features:
- Position Recovery on Startup: Automatically discovers open positions from platform and rebuilds state
- OODA Loop: Continuous Observe → Orient (Learning) → Decide (Reasoning) → Act (Execution) cycle
- Kill-Switch Protection: Halts trading if portfolio P&L breaches loss threshold
- Retry Logic: Exponential backoff for transient failures (3 attempts per asset)
- Failure Tracking: Per-asset failure counters with time-based decay
- Daily Limits: Configurable max trades per day with automatic midnight reset
- Risk Gatekeeper: Final validation before execution (drawdown, VaR, correlation)
- Memory Integration: Learns from closed trades via PortfolioMemoryEngine
See AGENTIC_LOOP_WORKFLOW.md and agent/trading_loop_agent.py for details.
graph TB
subgraph "Main Thread"
INIT[Initialize TradeMonitor]
DETECT[Detect New Positions poll]
SPAWN[Spawn TradeTrackerThread]
end
subgraph "ThreadPool max 2"
T1[TradeTrackerThread 1]
T2[TradeTrackerThread 2]
PENDING[Pending Queue]
end
subgraph "Tracker Lifecycle"
ENTRY[Position Entry]
MONITOR[Monitor Position P&L]
EXIT[Detect Exit]
CALLBACK[Callback]
end
subgraph "Persistence"
TMC[TradeMetricsCollector]
PME[PortfolioMemoryEngine]
end
INIT --> DETECT
DETECT --> SPAWN
SPAWN --> T1 & T2
T1 & T2 --> PENDING
T1 --> ENTRY
ENTRY --> MONITOR
MONITOR --> EXIT
EXIT --> CALLBACK
CALLBACK --> TMC
TMC --> PME
style T1 fill:#FF9800,stroke:#E65100,color:#fff
style T2 fill:#FF9800,stroke:#E65100,color:#fff
style ENTRY fill:#4CAF50,stroke:#2E7D32,color:#fff
style EXIT fill:#9C27B0,stroke:#4A148C,color:#fff
style PME fill:#00BCD4,stroke:#006064,color:#fff
The Finance Feedback Engine is built with a modular architecture:
finance_feedback_engine/
├── core.py # Main engine orchestrator
├── data_providers/ # Market data providers
│ └── alpha_vantage_provider.py
├── trading_platforms/ # Trading platform integrations
│ ├── base_platform.py # Abstract base class
│ ├── coinbase_platform.py # Coinbase implementation
│ ├── oanda_platform.py # Oanda implementation
│ └── platform_factory.py # Platform factory
├── decision_engine/ # AI-powered decision making
│ └── engine.py
├── persistence/ # Decision storage
│ └── decision_store.py
└── cli/ # Command-line interface
└── main.py
The Finance Feedback Engine uses a factory pattern for platform creation and circuit breaker pattern for resilient API execution.
View platform class hierarchy diagram →
Core classes:
BaseTradingPlatform(abstract) - Base interface for all platformsCoinbaseAdvancedPlatform- Coinbase futures tradingOandaPlatform- Oanda forex tradingUnifiedTradingPlatform- Multi-platform aggregationMockPlatform- Mock trading for testing
stateDiagram-v2
[*] --> CLOSED
state CLOSED {
[*] --> Normal
Normal --> IncrementFailures: execute_trade fails
IncrementFailures --> CheckThreshold: failure_count++
CheckThreshold --> Normal: count < 3
CheckThreshold --> [*]: count >= 3
Normal --> ResetCount: execute_trade succeeds
ResetCount --> Normal: failure_count = 0
}
CLOSED --> OPEN: Threshold Reached 3 failures
state OPEN {
[*] --> BlockCalls
BlockCalls --> CheckTimeout: All calls raise CircuitBreakerError
CheckTimeout --> BlockCalls: elapsed < 60s
CheckTimeout --> [*]: elapsed >= 60s
}
OPEN --> HALF_OPEN: Recovery Timeout Expired
state HALF_OPEN {
[*] --> TestRecovery
TestRecovery --> EvaluateResult: Allow ONE test call
EvaluateResult --> [*]: Success
EvaluateResult --> ReOpen: Failure
ReOpen --> [*]
}
HALF_OPEN --> CLOSED: Test Call Succeeds
HALF_OPEN --> OPEN: Test Call Fails
style CLOSED fill:#4CAF50,stroke:#2E7D32,color:#fff
style OPEN fill:#F44336,stroke:#C62828,color:#fff
style HALF_OPEN fill:#FFC107,stroke:#F57C00,color:#333
Circuit Breaker Configuration:
failure_threshold: Number of failures before opening circuit (default: 3)recovery_timeout: Seconds to wait before testing recovery (default: 60)expected_exception: Exception type to catch (default:aiohttp.ClientError)
Usage Pattern:
- Asset Pair Validation - Flexible asset pair formats
- Oanda Integration - Forex trading setup
- Ensemble System - Multi-provider AI aggregation
- Multi-Timeframe Pulse - Technical analysis system
- Autonomous Agent - OODA loop implementation
execute_trade() is protected by a circuit breaker to prevent cascading failures and ensure resilient API execution.
Lifecycle:
- CLOSED: Normal operation, tracks failures
- OPEN: After 3 failures, blocks all calls for 60 seconds
- HALF_OPEN: After timeout, allows one test call
- Transition: Success returns to CLOSED; failure returns to OPEN
See finance_feedback_engine/trading_platforms/ and utils/circuit_breaker.py for implementation details.
finance_feedback_engine/
├── core.py # Main engine orchestrator
├── data_providers/ # Market data providers
│ ├── alpha_vantage_provider.py
│ ├── unified_data_provider.py # Multi-timeframe aggregation
│ └── timeframe_aggregator.py # Technical indicators
├── trading_platforms/ # Trading platform integrations
│ ├── base_platform.py # Abstract base class
│ ├── coinbase_platform.py # Coinbase implementation
│ ├── oanda_platform.py # Oanda implementation
│ ├── unified_platform.py # Multi-platform aggregation
│ └── platform_factory.py # Platform factory
├── decision_engine/ # AI-powered decision making
│ ├── engine.py # Prompt builder, position sizing
│ └── ensemble_manager.py # Multi-provider voting
├── agent/ # Autonomous trading
│ ├── trading_loop_agent.py # OODA state machine
│ └── config.py # Agent configuration
├── monitoring/ # Live trade tracking
│ ├── trade_monitor.py # Main monitoring orchestrator
│ ├── trade_tracker.py # Per-trade thread
│ ├── metrics_collector.py # Performance data
│ └── monitoring_context_provider.py # Pulse integration
├── memory/ # ML feedback loop
│ └── portfolio_memory.py # Experience buffer
├── risk/ # Risk management
│ └── gatekeeper.py # Validation rules
├── persistence/ # Decision storage
│ └── decision_store.py
├── utils/ # Shared utilities
│ ├── circuit_breaker.py # Resilience pattern
│ ├── validation.py # Asset pair standardization
│ └── market_regime_detector.py # ADX/ATR classification
└── cli/ # Command-line interface
└── main.py
Monitoring Features:
- Automatic Detection: Scans platform for new positions every 30s
- Thread-Safe Tracking: Max 2 concurrent positions with dedicated threads
- Real-Time Updates: Live P&L, peak profit, max drawdown tracking
- Exit Classification: Detects take-profit, stop-loss, or manual exits
- ML Feedback: Completed trades → PortfolioMemoryEngine → DecisionEngine context
- Overflow Handling: Pending queue for positions when slots are full
- Metrics Storage: Persistent JSON records in
data/trade_metrics/ - Position Awareness: MonitoringContextProvider injects active positions into AI prompts
See docs/LIVE_MONITORING_QUICKREF.md for full details.
Agent Features:
- Position Recovery on Startup: Automatically discovers open positions from platform and rebuilds state
- OODA Loop: Continuous Observe → Orient (Learning) → Decide (Reasoning) → Act (Execution) cycle
- Kill-Switch Protection: Halts trading if portfolio P&L breaches loss threshold
- Retry Logic: Exponential backoff for transient failures (3 attempts per asset)
- Failure Tracking: Per-asset failure counters with time-based decay
- Daily Limits: Configurable max trades per day with automatic midnight reset
- Risk Gatekeeper: Final validation before execution (drawdown, VaR, correlation)
- Memory Integration: Learns from closed trades via PortfolioMemoryEngine
See AGENTIC_LOOP_WORKFLOW.md and agent/trading_loop_agent.py for details.
Features:
- Intelligent Voting: Combines decisions from multiple AI providers using weighted voting (Tier 1)
- Dynamic Weight Adjustment: Automatically renormalizes weights when providers fail
- 4-Tier Fallback: Progressive degradation (weighted → majority → averaging → single provider)
- Resilient: Continues working even when most providers are unavailable
- Transparent: Full metadata shows which providers succeeded/failed and how weights were adjusted
- Quorum Protection: Requires minimum 3 local providers; applies 30% confidence penalty if not met
Example metadata when one provider fails:
{
"ensemble_metadata": {
"providers_used": ["local", "codex", "qwen"],
"providers_failed": ["cli"],
"weight_adjustment_applied": true,
"adjusted_weights": {"local": 0.333, "codex": 0.333, "qwen": 0.333},
"fallback_tier": "weighted_voting",
"quorum_penalty_applied": false
}
}See docs/DYNAMIC_WEIGHT_ADJUSTMENT.md and docs/ENSEMBLE_FALLBACK_SYSTEM.md for complete details.
Edit config/config.local.yaml and add your:
- Alpha Vantage API key
- Trading platform credentials
- AI provider settings
Flexible Input Formats - Enter asset pairs in any format you prefer! 🆕
# Using default AI provider (from config)
python main.py analyze BTCUSD # Standard format
python main.py analyze btc-usd # Lowercase with dash
python main.py analyze BTC_USD # Underscore separator
python main.py analyze "BTC/USD" # Slash separator (quotes needed)
# Using specific AI provider
python main.py analyze BTCUSD --provider codex # Codex CLI (local, no API charges)
python main.py analyze btc-usd --provider cli # GitHub Copilot CLI (any format works!)
python main.py analyze eur_usd --provider qwen # Qwen CLI (free, requires Node.js v20+)
# python main.py analyze BTCUSD --provider gemini # Gemini CLI (disabled by default - see AI_PROVIDERS.md for activation)
python main.py analyze ETHUSD --provider local # Local rule-based
python main.py analyze gbp-jpy --provider ensemble # Multi-provider voting 🆕All asset pair formats are automatically standardized to uppercase without separators for API compatibility. See docs/ASSET_PAIR_VALIDATION.md for details.
python main.py balance# Show unified dashboard aggregating all platforms
python main.py dashboardThe dashboard displays:
- Total portfolio value across all platforms
- Asset count and holdings breakdown
- Per-platform allocation percentages
- Real-time data from Coinbase, Oanda, etc.
For detailed dashboard documentation, see docs/LIVE_MONITORING_QUICKREF.md.
python main.py history --limit 20python main.py history --asset EURUSDpython main.py execute <decision_id>python main.py statusRun historical and robustness analyses directly from the CLI.
# AI-driven backtest with defaults from config.advanced_backtesting
python main.py backtest BTCUSD --start 2024-01-01 --end 2024-02-01 \
--initial-balance 10000 --fee-percentage 0.001 --slippage-percentage 0.0001
# Walk-forward analysis (rolling train/test windows with overfitting check)
python main.py walk-forward BTCUSD --start-date 2024-01-01 --end-date 2024-03-01 --train-ratio 0.7
# Monte Carlo simulation with price perturbations
python main.py monte-carlo BTCUSD --start-date 2024-01-01 --end-date 2024-03-01 \
--simulations 500 --noise-std 0.001Notes:
- Backtest accepts overrides for fees, slippage, commission, stop-loss, take-profit, and starting balance; set
trading_platform: mockfor dry runs. - Walk-forward windows auto-derive from the date range; ensure the span is long enough for both train and test windows (≥7-day train recommended).
- Monte Carlo perturbs prices; inspect VaR/percentiles to understand tail risk.
Note: Monitor commands are gated for safety. To use manual CLI commands, set monitoring.manual_cli: true in your config (not recommended for production).
python main.py monitor startMonitor detects and tracks trades automatically:
- Polls for new positions every 30s
- Updates prices and P&L in real-time
- Records metrics when trades close
- Feeds outcomes back to AI for learning
Check monitoring status:
python main.py monitor statusView performance metrics:
python main.py monitor metricsSee docs/LIVE_TRADE_MONITORING.md for full details.
# Alpha Vantage API
alpha_vantage_api_key: "YOUR_API_KEY"
# Trading Platform
trading_platform: "coinbase" # or "oanda"
# Platform Credentials
platform_credentials:
api_key: "YOUR_PLATFORM_API_KEY"
api_secret: "YOUR_PLATFORM_SECRET"
# Decision Engine
decision_engine:
ai_provider: "local" # Options: "local", "cli" (GitHub Copilot), "codex" (Codex CLI)
model_name: "default"
decision_threshold: 0.7
# Persistence
persistence:
storage_path: "data/decisions"
max_decisions: 1000trading_platform: "coinbase"
platform_credentials:
api_key: "YOUR_COINBASE_API_KEY"
api_secret: "YOUR_COINBASE_API_SECRET"
passphrase: "YOUR_PASSPHRASE"trading_platform: "oanda"
platform_credentials:
api_key: "YOUR_OANDA_API_KEY"
account_id: "YOUR_ACCOUNT_ID"
environment: "practice" # or "live"Configure to use local AI models (e.g., Ollama, LLaMA):
decision_engine:
ai_provider: "local"
model_name: "llama2"Use external AI tools via command-line:
decision_engine:
ai_provider: "cli"
model_name: "trading_advisor"The decision engine is designed to be extended. You can add your own AI providers by:
- Implementing the
_query_ai()method indecision_engine/engine.py - Adding provider-specific logic for inference
- Supporting OpenAI, Anthropic, or any other AI service
- Never commit API keys: Use environment variables or local config files
- Use
.gitignore: Config files with credentials should be gitignored - Practice accounts: Start with sandbox/practice accounts
- API key permissions: Use read-only keys when possible
- Secure storage: Store credentials securely (use
.envfiles)
- BTCUSD (Bitcoin)
- ETHUSD (Ethereum)
- Any crypto pair supported by Alpha Vantage
- EURUSD
- GBPUSD
- USDJPY
- Any forex pair supported by Alpha Vantage
- Create a new class inheriting from
BaseTradingPlatform - Implement required methods:
get_balance(),execute_trade(),get_account_info() - Register the platform in
platform_factory.py
Usage Example:
from finance_feedback_engine.utils.validation import standardize_asset_pair
standardize_asset_pair('eur/usd') # Returns 'EURUSD'
standardize_asset_pair('BTC-USD') # Returns 'BTCUSD'
standardize_asset_pair('eth_usd') # Returns 'ETHUSD'### 2. Data Freshness Validation
Function: validate_data_freshness(data_timestamp: str, asset_type: str = "crypto", timeframe: str = "intraday") -> Tuple[bool, str, str]
This function protects against using stale market data by comparing a data point's timestamp against the current time. It uses configurable thresholds based on the asset type and timeframe to determine if the data is fresh enough for trading decisions.
Inputs:
data_timestamp: An ISO 8601 formatted UTC timestamp string (e.g.,'2024-12-08T14:30:00Z').asset_type: The type of asset ("crypto","forex","stocks"). Case-insensitive.timeframe: For stocks only, specifies"daily"or"intraday"data.
Returns:
A tuple (is_fresh, age_str, warning_message):
is_fresh(bool):Falseif data is critically stale,Trueotherwise.age_str(str): A human-readable string describing the data's age (e.g.,"5.2 minutes").warning_message(str): A descriptive warning or critical error message if the data is old.
Freshness Thresholds:
| Asset Type | Timeframe | Warning Threshold | Critical Threshold (is_fresh=False) |
|---|---|---|---|
| Crypto / Forex | N/A | > 5 minutes | >= 15 minutes |
| Stocks | Intraday | > 5 minutes | >= 15 minutes |
| Stocks | Daily | > 24 hours | (No critical threshold) |
Usage Example:
from finance_feedback_engine.utils.validation import validate_data_freshness
# Example with fresh crypto data
fresh_ts = "2024-10-26T12:00:00Z" # Assume current time is 12:02 UTC
is_fresh, age, msg = validate_data_freshness(fresh_ts, asset_type="crypto")
# is_fresh -> True
# age -> "2.0 minutes"
# msg -> ""
# Example with stale stock data
stale_ts = "2024-10-26T11:40:00Z" # Assume current time is 12:02 UTC
is_fresh, age, msg = validate_data_freshness(stale_ts, asset_type="stocks", timeframe="intraday")
# is_fresh -> False
# age -> "22.0 minutes"
# msg -> "CRITICAL: Stock intraday data is 22.0 minutes old..."To use these utilities in your project, ensure the finance_feedback_engine package is in your Python path.
import logging
from finance_feedback_engine.utils import validation
# Configure logging to see warnings and errors
logging.basicConfig(level=logging.INFO)
# Use the functions
pair = validation.standardize_asset_pair(" my-asset_pair/123 ")
print(f"Standardized Pair: {pair}")The Finance Feedback Engine maintains comprehensive test coverage across all subsystems.
# Run all tests
pytest
# Run with coverage report
pytest --cov=finance_feedback_engine --cov-report=html
# Run specific test modules
pytest tests/test_e2e_workflow.py
pytest tests/test_ensemble_fallback.py
pytest tests/test_backtester.py
# Run with verbose output
pytest -v
# Run tests matching a pattern
pytest -k "ensemble"Current Coverage: 70%+ (598 tests passing)
Tested Subsystems:
- ✅ Core Engine: Decision generation, analysis workflow, platform integration
- ✅ Ensemble Manager: Multi-provider voting, fallback tiers, dynamic weight adjustment
- ✅ Data Providers: Alpha Vantage, unified multi-timeframe pulse
- ✅ Trading Platforms: Mock, Coinbase, Oanda, circuit breaker protection
- ✅ Risk Management: VaR calculation, correlation analysis, position validation
- ✅ Memory & Learning: Portfolio memory, feedback analyzer, performance tracking
- ✅ Backtesting: Standard backtester, walk-forward analysis, Monte Carlo simulation
- ✅ Monitoring: Trade detection, P&L tracking, position monitoring
- ✅ CLI: All commands (analyze, execute, backtest, agent, dashboard)
- ✅ End-to-End Workflows: Complete user flows from analysis to execution
Test Categories:
- Unit Tests: Individual component testing with mocked dependencies
- Integration Tests: Multi-component workflows (e.g.,
test_phase1_integration.py) - End-to-End Tests: Full user scenarios with in-memory storage (
test_e2e_workflow.py) - Backtesting Tests: Historical analysis validation with cache management
Tests run automatically on every commit via GitHub Actions. See .github/workflows/ for CI configuration.
The Finance Feedback Engine 2.0 is production-ready with full Docker support, automated CI/CD, and comprehensive monitoring.
Prerequisites:
- Docker 20.10+
- Docker Compose 2.0+
- 4GB RAM minimum, 8GB recommended
- 20GB disk space
1. Initial Setup
# Clone the repository
git clone https://github.com/Three-Rivers-Tech/finance_feedback_engine-2.0.git
cd finance_feedback_engine-2.0
# Create production environment file
cp .env.production.example .env.production
nano .env.production2. Build Docker Images
docker compose --env-file .env.production build3. Deploy Services
docker compose --env-file .env.production up -d4. Access Services
- Frontend (Web UI): http://localhost:80
- Backend API: http://localhost:8000
- API Documentation: http://localhost:8000/docs
- Prometheus Metrics: http://localhost:9090
- Grafana Dashboards: http://localhost:3001 (admin/admin)
The system supports three deployment environments:
| Environment | Purpose | Trading Platform | Logging | Monitoring |
|---|---|---|---|---|
| Development | Local dev with hot reload | Mock (simulated) | DEBUG | Disabled |
| Staging | Testing with sandbox APIs | Sandbox/Practice | DEBUG | Enabled |
| Production | Live trading | Live APIs | INFO | Enabled |
Switch environments:
# Development (hot reload)
docker-compose -f docker-compose.dev.yml up
# Staging/Production (both use docker-compose.yml; swap env file)
docker compose --env-file .env.staging up -d
docker compose --env-file .env.production up -d# Start/stop/restart
docker compose --env-file .env.production up -d
docker compose --env-file .env.production down
docker compose --env-file .env.production restart
# View logs
docker compose --env-file .env.production logs -f
# Check status
docker compose --env-file .env.production ps┌─────────────────────────────────────────────────────────────────┐
│ DOCKER DEPLOYMENT │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Frontend │ │ Backend │ │ Monitoring │ │
│ │ (Nginx) │───│ (FastAPI) │───│ Stack │ │
│ │ │ │ │ │ │ │
│ │ Port: 80 │ │ Port: 8000 │ │ Prometheus │ │
│ │ │ │ │ │ Grafana │ │
│ └──────────────┘ │ - Uvicorn │ └──────────────┘ │
│ │ - SQLite │ │
│ │ - JSON data │ │
│ └──────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ PERSISTENT VOLUMES │ │
│ │ - ffe-data: SQLite DB, JSON decisions, cache │ │
│ │ - ffe-logs: Application logs │ │
│ │ - prometheus-data: Metrics time-series │ │
│ │ - grafana-data: Dashboard configs │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Automated Workflows:
-
CI/CD Pipeline: Comprehensive testing on every push (
ci.yml)- Pre-commit checks (linting, formatting, type checking)
- Unit tests with 70% coverage requirement
- Security scanning (Bandit, secret detection)
-
Staging Environment: Full-stack integration testing (
staging.yml)- Docker Compose-based testing with all services
- Health checks for all components (Backend, Frontend, Ollama, Redis, Prometheus)
- Integration tests in production-like environment
- API endpoint validation
- See Staging Workflow Guide for details
-
Build & Test: Automatically builds Docker images on every push to
mainordevelop -
Security Scanning: Trivy scans for vulnerabilities in all images
-
Multi-Architecture: Builds for
linux/amd64(addlinux/arm64if needed) -
Container Registry: Images pushed to GitHub Container Registry (ghcr.io)
Deployment Pipeline:
- Staging: Auto-deploys on every push to
main(after all checks pass) - Production: Manual approval required via GitHub Actions
Documentation:
- Complete CI/CD documentation: docs/CI_CD_PIPELINE.md
- Staging workflow guide: docs/STAGING_WORKFLOW_QUICKREF.md
Built-in Monitoring:
- Prometheus: Metrics collection at
/metricsendpoint - Grafana: Pre-configured dashboards for trading metrics
- Health Checks: All services have health endpoints
- OpenTelemetry: Distributed tracing support
- Structured Logging: JSON logs for production
Key Metrics Tracked:
- API request rates and response times
- Trading decision latency
- Error rates and circuit breaker status
- Portfolio performance metrics
- System resource utilization
Container Security:
- All containers run as non-root users
- Multi-stage builds minimize attack surface
- Regular security scanning with Trivy
- No secrets in images
API Security:
- Rate limiting (100 requests/60s by default)
- JWT authentication for API endpoints
- CORS configuration for production
- Environment-based secret management
Data Security:
.envfiles excluded from git (600 permissions)- SQLite database with proper file permissions
- Backups encrypted and rotated (7-day retention)
Services won't start:
# Check logs
docker compose --env-file .env.production logs -f
# Verify environment file
cat .env.production
# Rebuild images
docker compose --env-file .env.production build --no-cacheDatabase issues:
# Reset database
rm data/auth.db
touch data/auth.db
docker compose --env-file .env.production restartPerformance issues:
# Check resource usage
docker stats
# View Grafana dashboards
open http://localhost:3001Custom Ports:
Edit .env.production:
BACKEND_PORT=8000
FRONTEND_PORT=80
PROMETHEUS_PORT=9090
GRAFANA_PORT=3001Enable Redis (Optional):
# Start with Redis profile
docker-compose --profile full up -dSSL/TLS Setup:
- Place certificates in
certs/directory - Update
docker/nginx.confwith SSL configuration - Restart frontend service
For comprehensive deployment documentation, troubleshooting guides, and production best practices, see docs/DEPLOYMENT.md.