cTrader Commander
Use when the user wants to place trades, check positions or balance, get live prices, fetch candles, or manage orders on a cTrader account.
All calls go to http://localhost:9009 — credentials live in .env on the server, never passed by callers.
Proxy repo: https://github.com/LogicalSapien/ctrader-openapi-proxy Clone it, add your
.env, and runmake runto start the proxy before using this skill.
Full reference: {baseDir}/endpoints.md
Check proxy is running
curl -s "http://localhost:9009/get-data?command=ProtoOAVersionReq"
If it fails, start the proxy: cd ~/ctrader-openapi-proxy && make run
Find symbol IDs (do this first)
Symbol IDs are broker-specific — look them up before placing orders or fetching data:
curl -s "http://localhost:9009/get-data?command=ProtoOASymbolsListReq"
Returns symbol[] with symbolId and symbolName. Note the ID for your instrument.
Place a market order
curl -s -X POST http://localhost:9009/api/market-order \
-H "Content-Type: application/json" \
-d '{"symbolId": 158, "orderType": "MARKET", "tradeSide": "BUY", "volume": 1000}'
Volume is in units: 1000 = 0.01 lot · 10000 = 0.1 lot · 100000 = 1 lot.
Add "relativeStopLoss": 200, "relativeTakeProfit": 350 (pips, market orders only).
Place a limit or stop order
curl -s -X POST http://localhost:9009/api/market-order \
-H "Content-Type: application/json" \
-d '{"symbolId": 158, "orderType": "LIMIT", "tradeSide": "BUY", "volume": 1000, "price": 0.62500}'
orderType: MARKET · LIMIT · STOP — tradeSide: BUY · SELL
Get OHLC candles
NOW_MS=$(python3 -c "import time; print(int(time.time()*1000))")
FROM_MS=$(python3 -c "import time; print(int(time.time()*1000) - 3600000)")
curl -s -X POST http://localhost:9009/api/trendbars \
-H "Content-Type: application/json" \
-d "{\"fromTimestamp\": $FROM_MS, \"toTimestamp\": $NOW_MS, \"period\": \"M5\", \"symbolId\": 158}"
Periods: M1 M2 M3 M4 M5 M10 M15 M30 H1 H4 H12 D1 W1 MN1
Get live quote (tick data)
curl -s -X POST http://localhost:9009/api/live-quote \
-H "Content-Type: application/json" \
-d '{"symbolId": 158, "quoteType": "BID", "timeDeltaInSeconds": 60}'
quoteType: BID or ASK
Open positions and pending orders
curl -s "http://localhost:9009/get-data?command=ProtoOAReconcileReq"
Close a position
curl -s "http://localhost:9009/get-data?command=ClosePosition%20123456%201000"
# ClosePosition <positionId> <volumeInUnits>
Cancel a pending order
curl -s "http://localhost:9009/get-data?command=CancelOrder%20789"
Amend SL/TP on an open position
curl -s -X POST http://localhost:9009/api/amend-position \
-H "Content-Type: application/json" \
-d '{"positionId": 123456, "stopLoss": 1.08500, "takeProfit": 1.09500}'
Omit stopLoss or takeProfit to leave them unchanged. Use "trailingStopLoss": true to enable trailing stop.
Amend a pending limit or stop order
curl -s -X POST http://localhost:9009/api/amend-order \
-H "Content-Type: application/json" \
-d '{"orderId": 789, "limitPrice": 1.08200}'
Use limitPrice for LIMIT orders, stopPrice for STOP orders. Add volume (units) to change size.
Deal / trade history (closed trades)
NOW_MS=$(python3 -c "import time; print(int(time.time()*1000))")
FROM_MS=$(python3 -c "import time; print(int(time.time()*1000) - 604800000)")
curl -s "http://localhost:9009/get-data?command=ProtoOADealListReq%20${FROM_MS}%20${NOW_MS}"
Returns deal[] — each entry has dealId, positionId, symbolId, tradeSide, volume, executionPrice, commission, dealStatus, and closePositionDetail for closing deals. Adjust the FROM_MS offset (ms) to change the lookback period.
Account info (balance, equity, leverage)
curl -s "http://localhost:9009/get-data?command=ProtoOATraderReq"
First trade workflow
- Find symbol ID:
curl -s "http://localhost:9009/get-data?command=ProtoOASymbolsListReq" | python3 -c " import sys, json data = json.load(sys.stdin) [print(s['symbolId'], s['symbolName']) for s in data.get('symbol', []) if 'EURUSD' in s['symbolName']] " - Check your account details:
curl -s "http://localhost:9009/get-data?command=ProtoOATraderReq" - Place a market buy:
curl -s -X POST http://localhost:9009/api/market-order \ -H "Content-Type: application/json" \ -d '{"symbolId": 1, "orderType": "MARKET", "tradeSide": "BUY", "volume": 1000}' - Check open positions:
curl -s "http://localhost:9009/get-data?command=ProtoOAReconcileReq"