|
@@ -10,9 +10,8 @@ from fastmcp import FastMCP
|
|
|
from .models import AccountView
|
|
from .models import AccountView
|
|
|
from . import repo
|
|
from . import repo
|
|
|
from .services_bitstamp import fetch_account_info as fetch_remote_account_info
|
|
from .services_bitstamp import fetch_account_info as fetch_remote_account_info
|
|
|
-from .bitstamp_metadata import METADATA_REFRESH_SECONDS, refresh_metadata
|
|
|
|
|
|
|
+from .bitstamp_metadata import METADATA_REFRESH_SECONDS, refresh_metadata, list_markets as bitstamp_list_markets, list_currencies as bitstamp_list_currencies
|
|
|
from .bitstamp_fx import FX_REFRESH_SECONDS, refresh_eur_usd
|
|
from .bitstamp_fx import FX_REFRESH_SECONDS, refresh_eur_usd
|
|
|
-from .bitstamp_ws import ws_main
|
|
|
|
|
from .bitstamp_private_ws import private_ws_main
|
|
from .bitstamp_private_ws import private_ws_main
|
|
|
from .services_orders import place_order as service_place_order, query_order as service_query_order, cancel_order as service_cancel_order
|
|
from .services_orders import place_order as service_place_order, query_order as service_query_order, cancel_order as service_cancel_order
|
|
|
from .storage import init_db
|
|
from .storage import init_db
|
|
@@ -48,7 +47,6 @@ async def lifespan(_: FastAPI):
|
|
|
stop_event = asyncio.Event()
|
|
stop_event = asyncio.Event()
|
|
|
metadata_task = asyncio.create_task(_metadata_refresh_loop())
|
|
metadata_task = asyncio.create_task(_metadata_refresh_loop())
|
|
|
fx_task = asyncio.create_task(_fx_refresh_loop())
|
|
fx_task = asyncio.create_task(_fx_refresh_loop())
|
|
|
- ws_task = asyncio.create_task(ws_main(stop_event))
|
|
|
|
|
private_ws_task = asyncio.create_task(private_ws_main(stop_event))
|
|
private_ws_task = asyncio.create_task(private_ws_main(stop_event))
|
|
|
try:
|
|
try:
|
|
|
yield
|
|
yield
|
|
@@ -56,7 +54,6 @@ async def lifespan(_: FastAPI):
|
|
|
stop_event.set()
|
|
stop_event.set()
|
|
|
metadata_task.cancel()
|
|
metadata_task.cancel()
|
|
|
fx_task.cancel()
|
|
fx_task.cancel()
|
|
|
- ws_task.cancel()
|
|
|
|
|
private_ws_task.cancel()
|
|
private_ws_task.cancel()
|
|
|
|
|
|
|
|
|
|
|
|
@@ -237,11 +234,28 @@ def http_dashboard_delete_account(account_id: str) -> RedirectResponse:
|
|
|
|
|
|
|
|
@mcp.tool()
|
|
@mcp.tool()
|
|
|
def list_accounts(enabled_only: bool = True, venue: str | None = None) -> list[dict]:
|
|
def list_accounts(enabled_only: bool = True, venue: str | None = None) -> list[dict]:
|
|
|
|
|
+ """List configured accounts.
|
|
|
|
|
+
|
|
|
|
|
+ `enabled_only` defaults to true. If `venue` is omitted, all venues are returned.
|
|
|
|
|
+ """
|
|
|
return repo.list_accounts(venue=venue, enabled_only=enabled_only)
|
|
return repo.list_accounts(venue=venue, enabled_only=enabled_only)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+@mcp.tool()
|
|
|
|
|
+def list_markets() -> list[dict]:
|
|
|
|
|
+ """Return the cached Bitstamp markets metadata."""
|
|
|
|
|
+ return bitstamp_list_markets()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@mcp.tool()
|
|
|
|
|
+def list_currencies() -> list[dict]:
|
|
|
|
|
+ """Return the cached Bitstamp currencies metadata."""
|
|
|
|
|
+ return bitstamp_list_currencies()
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
@mcp.tool()
|
|
@mcp.tool()
|
|
|
def get_account_info(account_id: str) -> dict:
|
|
def get_account_info(account_id: str) -> dict:
|
|
|
|
|
+ """Return account details and live valuation when available."""
|
|
|
account = repo.get_account(account_id)
|
|
account = repo.get_account(account_id)
|
|
|
if account["venue"] == "bitstamp":
|
|
if account["venue"] == "bitstamp":
|
|
|
return fetch_remote_account_info(account_id)
|
|
return fetch_remote_account_info(account_id)
|
|
@@ -250,16 +264,23 @@ def get_account_info(account_id: str) -> dict:
|
|
|
|
|
|
|
|
@mcp.tool()
|
|
@mcp.tool()
|
|
|
def place_order(account_id: str, market: str, side: str, order_type: str, amount, price=None, expire_time: int | None = None, client_order_id: str | None = None) -> dict:
|
|
def place_order(account_id: str, market: str, side: str, order_type: str, amount, price=None, expire_time: int | None = None, client_order_id: str | None = None) -> dict:
|
|
|
|
|
+ """Place a Bitstamp order.
|
|
|
|
|
+
|
|
|
|
|
+ `market` is a Bitstamp symbol like `xrpusd`, `amount` is base units, and
|
|
|
|
|
+ `expire_time` is relative seconds from now.
|
|
|
|
|
+ """
|
|
|
return service_place_order(account_id=account_id, market=market, side=side, order_type=order_type, amount=amount, price=price, expire_time=expire_time, client_order_id=client_order_id)
|
|
return service_place_order(account_id=account_id, market=market, side=side, order_type=order_type, amount=amount, price=price, expire_time=expire_time, client_order_id=client_order_id)
|
|
|
|
|
|
|
|
|
|
|
|
|
@mcp.tool()
|
|
@mcp.tool()
|
|
|
def query_order(account_id: str, order_id, client_order_id: str | None = None, omit_transactions: bool | None = None) -> dict:
|
|
def query_order(account_id: str, order_id, client_order_id: str | None = None, omit_transactions: bool | None = None) -> dict:
|
|
|
|
|
+ """Query a Bitstamp order by order id."""
|
|
|
return service_query_order(account_id=account_id, order_id=order_id, client_order_id=client_order_id, omit_transactions=omit_transactions)
|
|
return service_query_order(account_id=account_id, order_id=order_id, client_order_id=client_order_id, omit_transactions=omit_transactions)
|
|
|
|
|
|
|
|
|
|
|
|
|
@mcp.tool()
|
|
@mcp.tool()
|
|
|
def cancel_order(account_id: str, order_id) -> dict:
|
|
def cancel_order(account_id: str, order_id) -> dict:
|
|
|
|
|
+ """Cancel a Bitstamp order by order id."""
|
|
|
return service_cancel_order(account_id=account_id, order_id=order_id)
|
|
return service_cancel_order(account_id=account_id, order_id=order_id)
|
|
|
|
|
|
|
|
|
|
|