From 3b9692cd5fff6b5a048634bdd10b6cbf692985b0 Mon Sep 17 00:00:00 2001 From: cwasicki <126617870+cwasicki@users.noreply.github.com> Date: Mon, 3 Feb 2025 21:04:55 +0100 Subject: [PATCH 1/3] Rename print_trade to print_public_trade in CLI tool To distinguish between Trade and PublicTrade data in upcoming changes. Signed-off-by: cwasicki <126617870+cwasicki@users.noreply.github.com> --- .../client/electricity_trading/cli/etrading.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/frequenz/client/electricity_trading/cli/etrading.py b/src/frequenz/client/electricity_trading/cli/etrading.py index f6369633..5cbfba1e 100644 --- a/src/frequenz/client/electricity_trading/cli/etrading.py +++ b/src/frequenz/client/electricity_trading/cli/etrading.py @@ -54,7 +54,7 @@ async def list_trades(url: str, key: str, *, delivery_start: datetime) -> None: """ client = Client(server_url=url, auth_key=key) - print_trade_header() + print_public_trade_header() delivery_period = None # If delivery period is selected, list historical trades also @@ -67,14 +67,14 @@ async def list_trades(url: str, key: str, *, delivery_start: datetime) -> None: lst = client.list_public_trades(delivery_period=delivery_period) async for trade in lst: - print_trade(trade) + print_public_trade(trade) if delivery_start <= datetime.now(timezone.utc): return stream = await client.stream_public_trades(delivery_period=delivery_period) async for trade in stream: - print_trade(trade) + print_public_trade(trade) async def list_orders( @@ -197,7 +197,7 @@ async def cancel_order( await client.cancel_gridpool_order(gridpool_id, order_id) -def print_trade_header() -> None: +def print_public_trade_header() -> None: """Print trade header in CSV format.""" header = ( "public_trade_id," @@ -216,7 +216,7 @@ def print_trade_header() -> None: print(header) -def print_trade(trade: PublicTrade) -> None: +def print_public_trade(trade: PublicTrade) -> None: """Print trade details to stdout in CSV format.""" values = ( trade.public_trade_id, From 028f20dea0b741c0f503d10fff267c20cc87045f Mon Sep 17 00:00:00 2001 From: cwasicki <126617870+cwasicki@users.noreply.github.com> Date: Mon, 3 Feb 2025 21:13:28 +0100 Subject: [PATCH 2/3] Add receive-gridpool-trades command to CLI tool Similarly to list-gridpool-orders this list trades for a given gridpool ID and optionally contract delivery start. Signed-off-by: cwasicki <126617870+cwasicki@users.noreply.github.com> --- .../electricity_trading/cli/__main__.py | 15 ++++ .../electricity_trading/cli/etrading.py | 77 +++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/src/frequenz/client/electricity_trading/cli/__main__.py b/src/frequenz/client/electricity_trading/cli/__main__.py index 310ef49a..075a094c 100644 --- a/src/frequenz/client/electricity_trading/cli/__main__.py +++ b/src/frequenz/client/electricity_trading/cli/__main__.py @@ -16,6 +16,9 @@ from frequenz.client.electricity_trading.cli.etrading import ( create_order as run_create_order, ) +from frequenz.client.electricity_trading.cli.etrading import ( + list_gridpool_trades as run_list_gridpool_trades, +) from frequenz.client.electricity_trading.cli.etrading import ( list_orders as run_list_orders, ) @@ -50,6 +53,18 @@ def receive_trades(url: str, key: str, *, start: datetime) -> None: asyncio.run(run_list_trades(url=url, key=key, delivery_start=start)) +@cli.command() +@click.option("--url", required=True, type=str) +@click.option("--key", required=True, type=str) +@click.option("--gid", required=True, type=int) +@click.option("--start", default=None, type=iso) +def receive_gridpool_trades(url: str, key: str, gid: int, *, start: datetime) -> None: + """List and/or stream orders.""" + asyncio.run( + run_list_gridpool_trades(url=url, key=key, gid=gid, delivery_start=start) + ) + + @cli.command() @click.option("--url", required=True, type=str) @click.option("--key", required=True, type=str) diff --git a/src/frequenz/client/electricity_trading/cli/etrading.py b/src/frequenz/client/electricity_trading/cli/etrading.py index 5cbfba1e..147686e1 100644 --- a/src/frequenz/client/electricity_trading/cli/etrading.py +++ b/src/frequenz/client/electricity_trading/cli/etrading.py @@ -21,6 +21,7 @@ Power, Price, PublicTrade, + Trade, ) @@ -77,6 +78,44 @@ async def list_trades(url: str, key: str, *, delivery_start: datetime) -> None: print_public_trade(trade) +async def list_gridpool_trades( + url: str, key: str, gid: int, *, delivery_start: datetime +) -> None: + """List gridpool trades and stream new gridpool trades. + + Optionally a delivery_start can be provided to filter the trades by delivery period. + + Args: + url: URL of the trading API. + key: API key. + gid: Gridpool ID. + delivery_start: Start of the delivery period or None. + """ + client = Client(server_url=url, auth_key=key) + + print_trade_header() + + delivery_period = None + # If delivery period is selected, list historical trades also + if delivery_start is not None: + check_delivery_start(delivery_start) + delivery_period = DeliveryPeriod( + start=delivery_start, + duration=timedelta(minutes=15), + ) + lst = client.list_gridpool_trades(gid, delivery_period=delivery_period) + + async for trade in lst: + print_trade(trade) + + if delivery_start and delivery_start <= datetime.now(timezone.utc): + return + + stream = await client.stream_gridpool_trades(gid, delivery_period=delivery_period) + async for trade in stream: + print_trade(trade) + + async def list_orders( url: str, key: str, *, delivery_start: datetime, gid: int ) -> None: @@ -235,6 +274,44 @@ def print_public_trade(trade: PublicTrade) -> None: print(",".join(v.name if isinstance(v, Enum) else str(v) for v in values)) +def print_trade_header() -> None: + """Print trade header in CSV format.""" + header = ( + "trade_id," + "order_id," + "execution_time," + "delivery_period_start," + "delivery_period_duration," + "delivery_area_code," + "delivery_area_code_type," + "side," + "quantity_mw," + "currency," + "price," + "state " + ) + print(header) + + +def print_trade(trade: Trade) -> None: + """Print trade details to stdout in CSV format.""" + values = ( + trade.id, + trade.order_id, + trade.execution_time.isoformat(), + trade.delivery_period.start.isoformat(), + trade.delivery_period.duration, + trade.delivery_area.code, + trade.delivery_area.code_type, + trade.side, + trade.quantity.mw, + trade.price.currency, + trade.price.amount, + trade.state, + ) + print(",".join(v.name if isinstance(v, Enum) else str(v) for v in values)) + + def print_order_header() -> None: """Print order header in CSV format.""" header = ( From 17250a1c6cc851f8c66d605a96471c678c85b0f3 Mon Sep 17 00:00:00 2001 From: cwasicki <126617870+cwasicki@users.noreply.github.com> Date: Mon, 3 Feb 2025 21:21:25 +0100 Subject: [PATCH 3/3] Update release notes Signed-off-by: cwasicki <126617870+cwasicki@users.noreply.github.com> --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 8f07c228..e1b70e3d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -11,6 +11,7 @@ ## New Features * Add helper function to support creating quantities that conform to the API expectations. +* Add `receive-gridpool-trades` command to CLI tool.