feat(exec): execute-multistrat --broker ibkr (whole-share) alongside alpaca
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -277,6 +277,8 @@ def execute_multistrat(
|
||||
do_execute: bool = typer.Option(False, "--execute", help="place orders (default: dry-run plan only)"),
|
||||
live: bool = typer.Option(False, "--live", help="allow a non-paper account"),
|
||||
max_gross: float = typer.Option(2.0, help="gross budget (risk-parity multistrat can sit modestly above 1)"),
|
||||
broker_name: str = typer.Option("alpaca", "--broker",
|
||||
help="execution venue: 'alpaca' (fractional) or 'ibkr' (whole-share)"),
|
||||
) -> None:
|
||||
"""Compute the adaptive multi-strat book's CURRENT target weights and rebalance them on ALPACA — the 5
|
||||
pure-equity streams (SPY/IEF/GLD/PDBC/DBMF) as fractional shares. BTC-USD is DROPPED from the fund book
|
||||
@@ -284,7 +286,6 @@ def execute_multistrat(
|
||||
no crypto order. Dry-run by default. Same ExecutionService safety gates + fractional sizing as `execute`."""
|
||||
import datetime as _dt
|
||||
|
||||
from fxhnt.adapters.broker.alpaca import AlpacaBroker
|
||||
from fxhnt.adapters.persistence.forward_nav import ForwardNavRepo
|
||||
from fxhnt.application.multistrat_exec_record import plan_and_record
|
||||
from fxhnt.domain.strategies import multistrat
|
||||
@@ -314,8 +315,18 @@ def execute_multistrat(
|
||||
today = _dt.datetime.now(_dt.UTC).strftime("%Y-%m-%d")
|
||||
at = _dt.datetime.now(_dt.UTC).replace(tzinfo=None)
|
||||
|
||||
broker = AlpacaBroker(settings.alpaca.api_key, settings.alpaca.api_secret,
|
||||
settings.alpaca.base_url, settings.alpaca.timeout)
|
||||
# execution venue: IBKR (whole-share, via ib-gateway) or Alpaca (fractional). Both are the Broker port —
|
||||
# ExecutionService + plan_and_record are broker-agnostic (fractional handling keys off supports_fractional).
|
||||
if broker_name == "ibkr":
|
||||
from fxhnt.adapters.broker.ibkr import IbkrBroker
|
||||
broker: Any = IbkrBroker(settings.ibkr.host, settings.ibkr.port,
|
||||
settings.ibkr.client_id, settings.ibkr.timeout)
|
||||
where = f"IBKR ({settings.ibkr.host}:{settings.ibkr.port})"
|
||||
else:
|
||||
from fxhnt.adapters.broker.alpaca import AlpacaBroker
|
||||
broker = AlpacaBroker(settings.alpaca.api_key, settings.alpaca.api_secret,
|
||||
settings.alpaca.base_url, settings.alpaca.timeout)
|
||||
where = f"Alpaca ({settings.alpaca.base_url})"
|
||||
try:
|
||||
with broker as brk:
|
||||
svc = ExecutionService(data, brk, settings)
|
||||
@@ -325,7 +336,7 @@ def execute_multistrat(
|
||||
today=today, at=at, max_gross=max_gross, execute=do_execute)
|
||||
except Exception as e: # connection / runtime
|
||||
typer.echo(f"broker error: {type(e).__name__}: {str(e)[:100]}")
|
||||
typer.echo(f" reachable? Alpaca ({settings.alpaca.base_url}) — creds set?")
|
||||
typer.echo(f" reachable? {where} — creds/gateway set?")
|
||||
raise typer.Exit(1) from e
|
||||
typer.echo(f"NLV ${plan.nlv:,.0f} | envelope ${envelope:,.0f} (B2a) | orders {len(plan.orders)}")
|
||||
for n in plan.notes:
|
||||
|
||||
Reference in New Issue
Block a user