cTrader Open API Python quickstart
cTrader Open API in Python: register an app, get a token by OAuth or the Playground, install OpenApiPy and list your accounts on the demo host.
Risk warning: CFDs and spread bets are complex instruments and come with a high risk of losing money rapidly due to leverage. You can lose money on these products, and each provider publishes its own loss figure under FCA rules. You should consider whether you understand how they work and whether you can afford to take the high risk of losing your money. Automated and API trading can amplify losses through bugs, connectivity failures and runaway orders.
Demo accounts only. Credentials are read from environment variables on your own machine. No field on this site asks for a key, a username or a password.
Steps
Register an app
Register at the cTrader Open API Portal (openapi.ctrader.com) with a cTID. Describe your use case in detail and give a valid redirect URL. Spotware reviews new apps and you need its approval before you start coding.
help.ctrader.comchecked
Get a test token from the Playground
Once approved, the Playground button on your Applications page gives an access token for your own cTID, so you can skip building the OAuth flow while you test.
help.ctrader.comchecked
Or run the OAuth flow
Send the user to id.ctrader.com with client_id, redirect_uri, scope and product=web. Ask for scope accounts (view only), not trading. The code lasts one minute; exchange it at openapi.ctrader.com/apps/token for an access token (about 30 days) and a refresh token that does not expire but works once.
Python
import os from ctrader_open_api import Auth # App credentials from openapi.ctrader.com, kept in environment variables auth = Auth(os.environ["CTRADER_CLIENT_ID"], os.environ["CTRADER_CLIENT_SECRET"], os.environ["CTRADER_REDIRECT_URI"]) print("Open this URL and approve the accounts scope:") print(auth.getAuthUri()) # After approval, copy the code from the redirect within one minute, then: # token = auth.getToken(os.environ["CTRADER_AUTH_CODE"]) # Store token values in your own secret store, not in code.JavaScript
// Node 18 or later. Builds the authorisation URL; the user approves in a browser. const params = new URLSearchParams({ client_id: process.env.CTRADER_CLIENT_ID, redirect_uri: process.env.CTRADER_REDIRECT_URI, scope: "accounts", // view only; do not request trading yet product: "web" }); console.log(`https://id.ctrader.com/my/settings/openapi/grantingaccess/?${params}`);curl
# Exchange the one minute authorisation code for tokens (values from env vars) curl -X GET "https://openapi.ctrader.com/apps/token?grant_type=authorization_code&code=$CTRADER_AUTH_CODE&redirect_uri=$CTRADER_REDIRECT_URI&client_id=$CTRADER_CLIENT_ID&client_secret=$CTRADER_CLIENT_SECRET"
help.ctrader.comchecked
Install OpenApiPy
Spotware's Python package is ctrader-open-api on PyPI, version 0.9.2 from 26 Jun 2024, for Python 3.8 or later. It is asynchronous, built on Twisted, and methods return Twisted deferreds. MIT licence.
Python
pip install ctrader-open-api
JavaScript
// The Open API runs over TCP or WebSocket with Protobuf or JSON messages, // not REST. Use the Python tab (OpenApiPy) or Spotware's C# package.
curl
# The Open API is not a REST API, so there is no curl call for this step. # Use the Python tab.
pypi.orgchecked
Connect to demo
Demo is demo.ctraderapi.com and live is live.ctraderapi.com, port 5035 for Protobuf and 5036 for JSON. The environments are fully separated: demo accounts cannot be used on the live host.
help.ctrader.comchecked
First call: list your accounts
Authorise the app with ProtoOAApplicationAuthReq (client ID and secret), then send ProtoOAGetAccountListByAccessTokenReq with the access token. Each account comes back with ctidTraderAccountId, isLive and brokerTitleShort. ProtoOAAccountAuthReq comes next, before any account data.
Python
import os from twisted.internet import reactor from ctrader_open_api import Client, Protobuf, TcpProtocol, EndPoints from ctrader_open_api.messages.OpenApiMessages_pb2 import ( ProtoOAApplicationAuthReq, ProtoOAGetAccountListByAccessTokenReq) # Demo host only. Read only: no order messages in this script. client = Client(EndPoints.PROTOBUF_DEMO_HOST, EndPoints.PROTOBUF_PORT, TcpProtocol) def on_accounts(message): res = Protobuf.extract(message) for acc in res.ctidTraderAccount: print(acc.ctidTraderAccountId, "live" if acc.isLive else "demo", acc.brokerTitleShort) reactor.stop() def on_app_auth(_): req = ProtoOAGetAccountListByAccessTokenReq() req.accessToken = os.environ["CTRADER_ACCESS_TOKEN"] client.send(req).addCallbacks(on_accounts, on_error) def on_error(failure): print("Error:", failure) reactor.stop() def connected(_): req = ProtoOAApplicationAuthReq() req.clientId = os.environ["CTRADER_CLIENT_ID"] req.clientSecret = os.environ["CTRADER_CLIENT_SECRET"] client.send(req).addCallbacks(on_app_auth, on_error) client.setConnectedCallback(connected) client.startService() reactor.run()JavaScript
// The Open API runs over TCP or WebSocket with Protobuf or JSON messages, // not REST. Use the Python tab (OpenApiPy) or Spotware's C# package.
curl
# The Open API is not a REST API, so there is no curl call for this step. # Use the Python tab.
help.ctrader.comchecked
Stay under the limits
Spotware allows 50 requests per second per connection, and 5 per second for historical data. Going over returns REQUEST_FREQUENCY_EXCEEDED (108).
help.ctrader.comchecked
cTrader Open API limits to pace against
| Limit | Value | Scope | Source |
|---|---|---|---|
| Requests a second, not historical data | 50 | Per connection, requests that are not for historical data | help.ctrader.comchecked |
| Requests a second, historical data | 5 | Per connection, historical data requests only | help.ctrader.comchecked |
Sources
- cTrader Open APIchecked
- Creating a new applicationchecked
- Account authenticationchecked
- Proxies and endpointschecked
- Messageschecked
- Model messageschecked
- GitHub: spotware/OpenApiPychecked
- OpenApiPy docschecked
- OpenApiPy docs: authenticationchecked
- PyPI: ctrader-open-apichecked