summaryrefslogtreecommitdiff
path: root/shared/src
diff options
context:
space:
mode:
Diffstat (limited to 'shared/src')
-rw-r--r--shared/src/shared/config.py2
-rw-r--r--shared/src/shared/exchange.py51
2 files changed, 53 insertions, 0 deletions
diff --git a/shared/src/shared/config.py b/shared/src/shared/config.py
index 7b34d78..867702b 100644
--- a/shared/src/shared/config.py
+++ b/shared/src/shared/config.py
@@ -8,6 +8,8 @@ class Settings(BaseSettings):
binance_api_secret: str
redis_url: str = "redis://localhost:6379"
database_url: str = "postgresql://trading:trading@localhost:5432/trading"
+ exchange_id: str = "binance" # Any ccxt exchange ID
+ exchange_sandbox: bool = False # Use sandbox/testnet mode
log_level: str = "INFO"
risk_max_position_size: float = 0.1
risk_stop_loss_pct: float = 5.0
diff --git a/shared/src/shared/exchange.py b/shared/src/shared/exchange.py
new file mode 100644
index 0000000..482bfda
--- /dev/null
+++ b/shared/src/shared/exchange.py
@@ -0,0 +1,51 @@
+"""Exchange factory using ccxt."""
+
+import ccxt.async_support as ccxt
+
+
+def create_exchange(
+ exchange_id: str,
+ api_key: str,
+ api_secret: str,
+ sandbox: bool = False,
+) -> ccxt.Exchange:
+ """Create a ccxt async exchange instance by ID.
+
+ Args:
+ exchange_id: ccxt exchange ID (e.g. 'binance', 'bybit', 'okx', 'kraken')
+ api_key: API key
+ api_secret: API secret
+ sandbox: Use sandbox/testnet mode
+
+ Returns:
+ Configured ccxt async exchange instance
+
+ Raises:
+ ValueError: If exchange_id is not supported by ccxt
+ """
+ if not hasattr(ccxt, exchange_id):
+ available = [
+ x
+ for x in dir(ccxt)
+ if not x.startswith("_")
+ and isinstance(getattr(ccxt, x, None), type)
+ and issubclass(getattr(ccxt, x), ccxt.Exchange)
+ ]
+ raise ValueError(
+ f"Unknown exchange '{exchange_id}'. "
+ f"Available: {', '.join(sorted(available)[:20])}..."
+ )
+
+ exchange_cls = getattr(ccxt, exchange_id)
+ exchange = exchange_cls(
+ {
+ "apiKey": api_key,
+ "secret": api_secret,
+ "enableRateLimit": True,
+ }
+ )
+
+ if sandbox:
+ exchange.set_sandbox_mode(True)
+
+ return exchange