- Configure workspace Git repository with comprehensive .gitignore - Add Odoo as submodule for ERP reference code - Include documentation: SETUP.md, GIT-STRUCTURE.md - Add gitignore templates for projects (backend, frontend, database) - Structure supports independent repos per project/subproject level Workspace includes: - core/ - Reusable patterns, modules, orchestration system - projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.) - knowledge-base/ - Reference code and patterns (includes Odoo submodule) - devtools/ - Development tools and templates - customers/ - Client implementations template 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
170 lines
6.5 KiB
Python
170 lines
6.5 KiB
Python
"""
|
|
Configuration for Data Service
|
|
OrbiQuant IA Trading Platform
|
|
"""
|
|
|
|
import os
|
|
from dataclasses import dataclass
|
|
from typing import Optional
|
|
|
|
|
|
@dataclass
|
|
class DatabaseConfig:
|
|
"""PostgreSQL configuration."""
|
|
host: str = "localhost"
|
|
port: int = 5432
|
|
database: str = "orbiquant_trading"
|
|
user: str = "orbiquant_user"
|
|
password: str = "orbiquant_dev_2025"
|
|
min_connections: int = 5
|
|
max_connections: int = 20
|
|
|
|
@property
|
|
def dsn(self) -> str:
|
|
return f"postgresql://{self.user}:{self.password}@{self.host}:{self.port}/{self.database}"
|
|
|
|
|
|
@dataclass
|
|
class PolygonConfig:
|
|
"""Polygon.io / Massive.com API configuration."""
|
|
api_key: str = ""
|
|
base_url: str = "https://api.polygon.io"
|
|
rate_limit_per_min: int = 5 # Basic tier
|
|
subscription_tier: str = "basic" # basic, starter, advanced
|
|
|
|
@classmethod
|
|
def from_env(cls) -> "PolygonConfig":
|
|
return cls(
|
|
api_key=os.getenv("POLYGON_API_KEY", ""),
|
|
base_url=os.getenv("POLYGON_BASE_URL", "https://api.polygon.io"),
|
|
rate_limit_per_min=int(os.getenv("POLYGON_RATE_LIMIT", "5")),
|
|
subscription_tier=os.getenv("POLYGON_TIER", "basic"),
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class MetaAPIConfig:
|
|
"""MetaAPI.cloud configuration for MT4/MT5 access."""
|
|
token: str = ""
|
|
account_id: str = ""
|
|
|
|
@classmethod
|
|
def from_env(cls) -> "MetaAPIConfig":
|
|
return cls(
|
|
token=os.getenv("METAAPI_TOKEN", ""),
|
|
account_id=os.getenv("METAAPI_ACCOUNT_ID", ""),
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class MT4DirectConfig:
|
|
"""Direct MT4 server connection configuration."""
|
|
server: str = ""
|
|
login: int = 0
|
|
password: str = ""
|
|
investor_mode: bool = True # Default to read-only
|
|
|
|
@classmethod
|
|
def from_env(cls) -> "MT4DirectConfig":
|
|
return cls(
|
|
server=os.getenv("MT4_SERVER", ""),
|
|
login=int(os.getenv("MT4_LOGIN", "0")),
|
|
password=os.getenv("MT4_PASSWORD", ""),
|
|
investor_mode=os.getenv("MT4_INVESTOR_MODE", "true").lower() == "true",
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class SpreadConfig:
|
|
"""Spread calculation configuration."""
|
|
# Default spreads by asset type (in price units)
|
|
default_forex_major: float = 0.00010 # 1 pip
|
|
default_forex_minor: float = 0.00020 # 2 pips
|
|
default_forex_exotic: float = 0.00050 # 5 pips
|
|
default_crypto: float = 0.001 # 0.1%
|
|
default_index: float = 0.5 # 0.5 points
|
|
default_commodity: float = 0.05
|
|
|
|
# Session multipliers
|
|
asian_mult: float = 1.3
|
|
london_mult: float = 0.9
|
|
newyork_mult: float = 0.95
|
|
overlap_mult: float = 0.85
|
|
pacific_mult: float = 1.2
|
|
|
|
# Volatility multipliers
|
|
high_vol_mult: float = 1.5
|
|
low_vol_mult: float = 1.0
|
|
|
|
|
|
@dataclass
|
|
class Config:
|
|
"""Main configuration."""
|
|
database: DatabaseConfig
|
|
polygon: PolygonConfig
|
|
metaapi: MetaAPIConfig
|
|
mt4_direct: MT4DirectConfig
|
|
spread: SpreadConfig
|
|
|
|
# Sync settings
|
|
sync_interval_minutes: int = 5
|
|
backfill_days: int = 30
|
|
|
|
@classmethod
|
|
def from_env(cls) -> "Config":
|
|
return cls(
|
|
database=DatabaseConfig(
|
|
host=os.getenv("DB_HOST", "localhost"),
|
|
port=int(os.getenv("DB_PORT", "5432")),
|
|
database=os.getenv("DB_NAME", "orbiquant_trading"),
|
|
user=os.getenv("DB_USER", "orbiquant_user"),
|
|
password=os.getenv("DB_PASSWORD", "orbiquant_dev_2025"),
|
|
),
|
|
polygon=PolygonConfig.from_env(),
|
|
metaapi=MetaAPIConfig.from_env(),
|
|
mt4_direct=MT4DirectConfig.from_env(),
|
|
spread=SpreadConfig(),
|
|
sync_interval_minutes=int(os.getenv("SYNC_INTERVAL_MINUTES", "5")),
|
|
backfill_days=int(os.getenv("BACKFILL_DAYS", "30")),
|
|
)
|
|
|
|
|
|
# Ticker symbol mappings
|
|
TICKER_MAPPINGS = {
|
|
# Forex pairs - Polygon prefix C:
|
|
"EURUSD": {"polygon": "C:EURUSD", "mt4": "EURUSD", "mt4_micro": "EURUSDm", "pip_value": 0.0001},
|
|
"GBPUSD": {"polygon": "C:GBPUSD", "mt4": "GBPUSD", "mt4_micro": "GBPUSDm", "pip_value": 0.0001},
|
|
"USDJPY": {"polygon": "C:USDJPY", "mt4": "USDJPY", "mt4_micro": "USDJPYm", "pip_value": 0.01},
|
|
"USDCAD": {"polygon": "C:USDCAD", "mt4": "USDCAD", "mt4_micro": "USDCADm", "pip_value": 0.0001},
|
|
"AUDUSD": {"polygon": "C:AUDUSD", "mt4": "AUDUSD", "mt4_micro": "AUDUSDm", "pip_value": 0.0001},
|
|
"NZDUSD": {"polygon": "C:NZDUSD", "mt4": "NZDUSD", "mt4_micro": "NZDUSDm", "pip_value": 0.0001},
|
|
"EURGBP": {"polygon": "C:EURGBP", "mt4": "EURGBP", "mt4_micro": "EURGBPm", "pip_value": 0.0001},
|
|
"EURAUD": {"polygon": "C:EURAUD", "mt4": "EURAUD", "mt4_micro": "EURAUDm", "pip_value": 0.0001},
|
|
"EURCHF": {"polygon": "C:EURCHF", "mt4": "EURCHF", "mt4_micro": "EURCHFm", "pip_value": 0.0001},
|
|
"GBPJPY": {"polygon": "C:GBPJPY", "mt4": "GBPJPY", "mt4_micro": "GBPJPYm", "pip_value": 0.01},
|
|
"GBPAUD": {"polygon": "C:GBPAUD", "mt4": "GBPAUD", "mt4_micro": "GBPAUDm", "pip_value": 0.0001},
|
|
"GBPCAD": {"polygon": "C:GBPCAD", "mt4": "GBPCAD", "mt4_micro": "GBPCADm", "pip_value": 0.0001},
|
|
"GBPNZD": {"polygon": "C:GBPNZD", "mt4": "GBPNZD", "mt4_micro": "GBPNZDm", "pip_value": 0.0001},
|
|
"AUDCAD": {"polygon": "C:AUDCAD", "mt4": "AUDCAD", "mt4_micro": "AUDCADm", "pip_value": 0.0001},
|
|
"AUDCHF": {"polygon": "C:AUDCHF", "mt4": "AUDCHF", "mt4_micro": "AUDCHFm", "pip_value": 0.0001},
|
|
"AUDNZD": {"polygon": "C:AUDNZD", "mt4": "AUDNZD", "mt4_micro": "AUDNZDm", "pip_value": 0.0001},
|
|
|
|
# Commodities
|
|
"XAUUSD": {"polygon": "C:XAUUSD", "mt4": "XAUUSD", "mt4_micro": "XAUUSDm", "pip_value": 0.01},
|
|
"XAGUSD": {"polygon": "C:XAGUSD", "mt4": "XAGUSD", "mt4_micro": "XAGUSDm", "pip_value": 0.001},
|
|
|
|
# Crypto - Polygon prefix X:
|
|
"BTCUSD": {"polygon": "X:BTCUSD", "mt4": "BTCUSD", "mt4_micro": "BTCUSDm", "pip_value": 1.0},
|
|
|
|
# Indices - Polygon prefix I:
|
|
"SPX500": {"polygon": "I:SPX", "mt4": "US500", "mt4_micro": "US500m", "pip_value": 0.1},
|
|
"NAS100": {"polygon": "I:NDX", "mt4": "US100", "mt4_micro": "US100m", "pip_value": 0.1},
|
|
"DJI30": {"polygon": "I:DJI", "mt4": "US30", "mt4_micro": "US30m", "pip_value": 0.1},
|
|
"DAX40": {"polygon": "I:DAX", "mt4": "DE40", "mt4_micro": "DE40m", "pip_value": 0.1},
|
|
}
|
|
|
|
# Asset type classification
|
|
FOREX_MAJORS = ["EURUSD", "GBPUSD", "USDJPY", "USDCHF", "AUDUSD", "NZDUSD", "USDCAD"]
|
|
FOREX_MINORS = ["EURGBP", "EURAUD", "EURCHF", "GBPJPY", "GBPAUD", "EURJPY", "AUDJPY"]
|
|
FOREX_CROSSES = ["GBPCAD", "GBPNZD", "AUDCAD", "AUDCHF", "AUDNZD"]
|