A Laravel-based algorithmic trading system for foreign exchange (FX) markets. This application provides automated decision-making capabilities for forex trading using technical analysis and economic calendar data.
This is a quantitative trading platform that:
- Analyzes market data from multiple timeframes (5-minute and 30-minute candles)
- Monitors economic calendar events to avoid trading during high-impact announcements
- Calculates technical indicators (EMA, ATR, ADX, support/resistance levels)
- Makes trading decisions based on configurable rule sets
- Manages risk through position sizing, daily stop-losses, and cooldown periods
- Estimates spreads for accurate cost calculations
- Provides CLI tools for previewing decisions and contexts
- PHP: 8.4+
- Laravel: 12.x
- Database: PostgreSQL (SQLite for development)
- Node.js: For frontend asset compilation
- External APIs:
- TwelveData (price data)
- IG Markets API (spreads and execution)
app/
โโโ Application/ # Application services and use cases
โ โโโ Calendar/ # Economic calendar management
โ โโโ Candles/ # Price data synchronization
โ โโโ ContextBuilder # Aggregates all data for decision making
โโโ Domain/ # Core business logic
โ โโโ Decision/ # Trading decision engine
โ โโโ Execution/ # Position management contracts
โ โโโ Features/ # Technical analysis engine
โ โโโ FX/ # Forex-specific calculations
โ โโโ Market/ # Market data structures
โ โโโ Risk/ # Risk management
โ โโโ Rules/ # Trading rules configuration
โโโ Infrastructure/ # External service integrations
โ โโโ Prices/ # Price data providers
โโโ Services/ # External API clients
โ โโโ Economic/ # Economic calendar APIs
โ โโโ IG/ # IG Markets integration
โ โโโ Prices/ # Price data APIs
โโโ Models/ # Eloquent models
The heart of the system that evaluates trading opportunities:
- Input: Market context (prices, features, calendar)
- Processing: Applies configurable gates and rules
- Output: Trading decision (buy/sell/hold) with confidence and reasoning
Key Gates:
- Market status validation (TRADEABLE required)
- Data freshness checks (max age limits)
- Calendar blackout periods (avoid high-impact events)
- Technical volatility filters (ADX minimum, EMA-Z stretch limits)
- Spread requirements (cost control)
- Daily loss stops and cooldown periods
Aggregates all necessary data for decision making:
- Market Data: Current prices, spreads, trading status
- Technical Features: EMA, ATR, ADX, trend analysis, support/resistance
- Economic Calendar: Upcoming high-impact events and blackout periods
- Position Information: Current exposure and recent trade outcomes
Calculates technical indicators from price data:
- EMA (Exponential Moving Average): Trend following
- ATR (Average True Range): Volatility measurement
- ADX (Average Directional Index): Trend strength
- EMA-Z Score: Price deviation from mean
- Support/Resistance: Key price levels
- Trend Classification: 30-minute trend direction
Economic event monitoring and blackout logic:
- Event Import: CSV import from multiple formats
- Impact Classification: High/Medium/Low event importance
- Blackout Periods: Avoid trading around high-impact events
- Multi-currency Support: Currency-specific event filtering
markets: Trading instruments (EUR/USD, GBP/USD, etc.)orders: Trade execution recordscalendar_events: Economic calendar events with impact ratings
// Market Context Structure
[
'meta' => [
'pair_norm' => 'EURUSD',
'data_age_sec' => 10,
'sleeve_balance' => 10000.0
],
'market' => [
'status' => 'TRADEABLE',
'last_price' => 1.1000,
'atr5m_pips' => 10,
'spread_estimate_pips' => 0.5,
'sentiment' => ['long_pct' => 60.0, 'short_pct' => 40.0]
],
'features' => [
'ema20' => 1.0950,
'ema20_z' => 0.5,
'adx5m' => 25.0,
'trend30m' => 'up'
],
'calendar' => [
'within_blackout' => false
]
]The system uses YAML configuration for trading rules:
gates:
market_required_status: ["TRADEABLE"]
max_data_age_sec: 600
spread_required: true
adx_min: 20
z_abs_max: 1.0
daily_loss_stop_pct: 3.0
confluence: {}
risk:
per_trade_pct:
default: 1.0
medium_strong: 1.5
execution:
sl_atr_mult: 2.0 # Stop loss = 2x ATR
tp_atr_mult: 4.0 # Take profit = 4x ATR
cooldowns:
after_loss_minutes: 20
after_win_minutes: 5config/pricing.php: Price data provider settingsconfig/decision.php: Decision engine parameters
# Clone repository
git clone <repository-url>
cd hedgefund
# Install dependencies
composer install
npm install
# Environment setup
cp .env.example .env
php artisan key:generate
# Database setup
php artisan migrate
php artisan db:seed
# Build assets
npm run buildSet up your .env file with:
# Database
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=hedgefund
DB_USERNAME=your_user
DB_PASSWORD=your_password
# Price Data
PRICE_DRIVER=twelvedata
TWELVEDATA_API_KEY=your_api_key
# IG Markets (for spreads and execution)
IG_API_KEY=your_api_key
IG_IDENTIFIER=your_username
IG_PASSWORD=your_password# Start development server with all services
composer run dev
# This runs concurrently:
# - Laravel development server
# - Queue worker
# - Log monitoring (Pail)
# - Vite asset compilation# Get decision for EUR/USD
php artisan decision:preview EUR/USD
# Force refresh all data sources
php artisan decision:preview EUR/USD --force-sentiment
# Strict mode (non-zero exit on hold)
php artisan decision:preview EUR/USD --strict# Show full context data
php artisan context:preview EUR/USD
# Historical context (specific time)
php artisan context:preview EUR/USD --now="2025-09-14 14:30:00"
# Force data refresh
php artisan context:preview EUR/USD --force-calendar# Refresh price data
php artisan candles:refresh EUR/USD --days=30
# Import economic calendar
php artisan calendar:import-csv /path/to/events.csv
# Reload trading rules
php artisan rules:reloadThe application includes a Livewire-powered web interface with:
- Dashboard: System status and recent decisions
- Settings: User preferences and appearance
- Health Endpoints:
/candles/health/{pair}for monitoring
The system integrates with multiple external APIs:
- TwelveData: Historical and real-time price data
- IG Client Sentiment: Crowd positioning data for major markets
- IG Markets: Live spreads and trade execution
- Economic Calendar: High-impact event schedules
The project uses Pest for testing with comprehensive coverage:
# Run all tests
php artisan test
# Run specific test suites
php artisan test --filter=DecisionEngine
php artisan test --filter=CalendarCsv
php artisan test --filter=ContextBuilder
# Test with coverage
php artisan test --coverage- Unit Tests: Domain logic (decision engine, feature calculation)
- Feature Tests: Application workflows (context building, data import)
- Integration Tests: External API interactions
Key test files:
DecisionEngine*Test.php: Trading logic validationContextBuilder*Test.php: Data aggregation testingCalendarCsv*Test.php: Calendar import functionality
- Daily Loss Limits: Configurable percentage-based stops
- Position Sizing: ATR-based risk calculation
- Cooldown Periods: Post-trade waiting periods
- Data Freshness: Reject stale market data
- Spread Monitoring: Cost-aware execution
- Calendar Blackouts: Avoid high-volatility periods
risk:
per_trade_pct:
default: 1.0 # 1% risk per trade
high_confidence: 1.5
gates:
daily_loss_stop_pct: 3.0 # Stop trading at -3% daily
max_positions: 3
max_pair_exposure_pct: 20.0
cooldowns:
after_loss_minutes: 30
after_win_minutes: 10- Extend
FeatureEnginewith new calculations - Update
FeatureSetclass structure - Add indicator logic to decision rules
- Write comprehensive tests
- Implement
SentimentProviderinterface - Register the provider binding in
AppServiceProvider - Configure cache or data source specifics as needed
- Add provider-specific tests
Edit the YAML rules configuration to adjust:
- Entry/exit criteria
- Risk parameters
- Gate conditions
- Confluence requirements
# Check candle data health
curl http://localhost:8000/candles/health/EUR/USD
# Monitor logs in real-time
php artisan pail
# Check queue status
php artisan queue:monitorThe system logs extensively for debugging and analysis:
- Decision reasoning and blocked trades
- Data refresh operations
- External API interactions
- Error conditions and fallbacks
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Test your changes (
php artisan test) - Format code (
vendor/bin/pint) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Create a Pull Request
- Follow Laravel conventions and patterns
- Write comprehensive tests for new features
- Use type hints and return types
- Document complex business logic
- Run Pint for code formatting
- Maintain backward compatibility
This project is licensed under the MIT License - see the LICENSE file for details.
For questions and support:
- Check the tests/ directory for usage examples
- Review config/ files for configuration options
- Examine app/Console/Commands/ for CLI usage
- Read the source code - it's well-documented!
Potential areas for expansion:
- Machine learning integration for prediction models
- Multi-broker execution support
- Advanced portfolio optimization
- Real-time streaming data integration
- Mobile application development
- Advanced backtesting capabilities