LiveExecutor
Live order executor for the LIVE/act scenario (managed JIT,
application/x-dotnet-dll), built on
virtufin-execution-devkit.
Routes orders to Binance's real Spot trading API.
⚠ Before deploying this against real capital
This worker has not been tested against Binance's real API or
testnet. It was written from Binance's published REST API
documentation with no network access available to verify signing or
response parsing against the live service. Before pointing this at
act:
- Set
BINANCE_BASE_URL=https://testnet.binance.visionand run it against Binance's testnet with testnet API keys first. - Independently verify
BinanceSigning.Sign's output against a request you've manually signed and confirmed Binance accepts. - Check whether the symbol(s) you intend to trade have unusual
LOT_SIZE/PRICE_FILTERprecision requirements (GET /api/v3/exchangeInfo) -- this worker sends quantities/prices as plain decimals without querying or rounding to a symbol's actual step size, so orders on some symbols may be rejected. - Review error handling: a failed/rejected order currently throws,
which
WorkerBase.ProcessAsync's outer try/catch converts into an error response -- confirm that's the behavior you want for a production trading path.
Behaviour
Subscribes to sc.LIVE.trading.order.submitted -- a live executor only
ever serves the reserved LIVE scenario (see the pubsub-topics spec's
Topic Patterns requirement); routing real capital under anything but
the reserved production scenario id would be a bug.
- Buy/Sell orders route to
POST /api/v3/order(market if no limit price,GTClimit otherwise). Other action types throw. - The response's
fills[]are collapsed into oneTradeEvent.FillReceived(quantity-weighted average price, summed commission). Partial fills across multiple Binance responses aren't handled -- this worker treats the firstPOST /api/v3/orderresponse as final.
Configuration
Environment variables (process-level, not per-worker
CreateWorkerRequest.config -- exchange credentials are the same
class of secret VIRTUFIN_REGISTRY_TOKEN is, and per-worker config is
stamped onto every triggering CloudEvent, which would leak credentials
into the event stream):
| Variable | Required | Meaning |
|---|---|---|
BINANCE_API_KEY |
yes | Binance API key. |
BINANCE_API_SECRET |
yes | Binance API secret. |
BINANCE_BASE_URL |
no (default https://api.binance.com) |
Override for testnet or a proxy. |
Deploy
cd LiveExecutor
python3 scripts/build_managed.py --csproj src/Virtufin.Worker.LiveExecutor/Virtufin.Worker.LiveExecutor.csproj
python3 scripts/publish.py --worker-nupkg /tmp/worker-out/Virtufin.Worker.LiveExecutor.nupkg
python3 scripts/create_worker.py --api-client-host localhost --api-client-port 5002
config/config.json's topics already defaults to
sc.LIVE.trading.order.submitted. Make sure
BINANCE_API_KEY/BINANCE_API_SECRET are set in the WorkManager
process's own environment before creating this worker -- not
something these scripts set for you. Go through the pre-deployment
checklist above first.
Package
Virtufin.Worker.LiveExecutor on the private Gitea NuGet feed;
CI publishes via .github/workflows/liveexecutor-nuget.yaml.