Trading account is not authorized, openApiPy, how to solve?
Trading account is not authorized, openApiPy, how to solve?
22 Feb 2022, 11:22
I'm trying to open positions usnig openApiPy, but I get this erorr:
Connected Message received: ctidTraderAccountId: 23606106 errorCode: "INVALID_REQUEST" description: "Trading account is not authorized" API Application authorized Please use setAccount command to set the authorized account before sending any other command, try help for more detail To get account IDs use ProtoOAGetAccountListByAccessTokenReq command Account 23606106 has been authorized This acccount will be used for all future requests You can change the account by using setAccount command Command (ex help):
Command Input Timeout
So, how can I authorize my trading account? I'm currently using demo account
This is the code i'm trying to run:
from ctrader_open_api import Client, Protobuf, TcpProtocol, Auth, EndPoints
from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import *
from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import *
from ctrader_open_api.messages.OpenApiMessages_pb2 import *
from ctrader_open_api.messages.OpenApiModelMessages_pb2 import *
from twisted.internet import reactor
from inputimeout import inputimeout, TimeoutOccurred
import json
import datetime
credentialsFile = open("credentials.json")
credentials = json.load(credentialsFile)
if __name__ == "__main__":
currentAccountId = None
hostType = input("Host (Live/Demo): ")
hostType = hostType.lower()
while hostType != "live" and hostType != "demo":
print(f"{hostType} is not a valid host type.")
hostType = input("Host (Live/Demo): ")
appClientId = credentials["ClientId"]
appClientSecret = credentials["Secret"]
isTokenAvailable = credentials["AccessToken"]
accessToken = None
if isTokenAvailable == False:
appRedirectUri = input("App Redirect URI: ")
auth = Auth(appClientId, appClientSecret, appRedirectUri)
authUri = auth.getAuthUri()
print(f"Please continue the authentication on your browser:\n {authUri}")
webbrowser.open_new(authUri)
print("\nThen enter the auth code that is appended to redirect URI immediatly (the code is after ?code= in URI)")
authCode = input("Auth Code: ")
token = auth.getToken(authCode)
if "accessToken" not in token:
raise KeyError(token)
print("Token: \n", token)
accessToken = token["accessToken"]
else:
accessToken = credentials["AccessToken"]
client = Client(EndPoints.PROTOBUF_LIVE_HOST if hostType.lower() == "live" else EndPoints.PROTOBUF_DEMO_HOST, EndPoints.PROTOBUF_PORT, TcpProtocol)
def setAccount(accountId):
global currentAccountId
if currentAccountId is not None:
sendProtoOAAccountLogoutReq()
currentAccountId = int(accountId)
sendProtoOAAccountAuthReq()
def sendProtoOAAccountAuthReq(clientMsgId = None):
request = ProtoOAAccountAuthReq()
request.ctidTraderAccountId = currentAccountId
request.accessToken = accessToken
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
def connected(client): # Callback for client connection
print("\nConnected")
request = ProtoOAApplicationAuthReq()
request.clientId = appClientId
request.clientSecret = appClientSecret
deferred = client.send(request)
deferred.addErrback(onError)
def disconnected(client, reason): # Callback for client disconnection
print("\nDisconnected: ", reason)
def onMessageReceived(client, message): # Callback for receiving all messages
if message.payloadType in [ProtoOASubscribeSpotsRes().payloadType, ProtoOAAccountLogoutRes().payloadType, ProtoHeartbeatEvent().payloadType]:
return
elif message.payloadType == ProtoOAApplicationAuthRes().payloadType:
print("API Application authorized\n")
print("Please use setAccount command to set the authorized account before sending any other command, try help for more detail\n")
print("To get account IDs use ProtoOAGetAccountListByAccessTokenReq command")
if currentAccountId is not None:
sendProtoOAAccountAuthReq()
return
elif message.payloadType == ProtoOAAccountAuthRes().payloadType:
protoOAAccountAuthRes = Protobuf.extract(message)
print(f"Account {protoOAAccountAuthRes.ctidTraderAccountId} has been authorized\n")
print("This acccount will be used for all future requests\n")
print("You can change the account by using setAccount command")
else:
print("Message received: \n", Protobuf.extract(message))
reactor.callLater(3, callable=executeUserCommand)
def onError(failure): # Call back for errors
print("Message Error: ", failure)
reactor.callLater(3, callable=executeUserCommand)
def executeUserCommand():
try:
print("\n")
userInput = inputimeout("Command (ex help): ", timeout=18)
except TimeoutOccurred:
print("Command Input Timeout")
reactor.callLater(3, callable=executeUserCommand)
return
userInputSplit = userInput.split(" ")
if not userInputSplit:
print("Command split error: ", userInput)
reactor.callLater(3, callable=executeUserCommand)
return
command = userInputSplit[0]
try:
parameters = [parameter if parameter[0] != "*" else parameter[1:] for parameter in userInputSplit[1:]]
except:
print("Invalid parameters: ", userInput)
reactor.callLater(3, callable=executeUserCommand)
if command in commands:
commands[command](*parameters)
else:
print("Invalid Command: ", userInput)
reactor.callLater(3, callable=executeUserCommand)
def sendProtoOAGetAccountListByAccessTokenReq(clientMsgId = None):
request = ProtoOAGetAccountListByAccessTokenReq()
request.accessToken = credentials["AccessToken"]
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
def sendProtoOAAssetListReq(clientMsgId = None):
request = ProtoOAAssetListReq()
request.ctidTraderAccountId = currentAccountId
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
def sendProtoOANewOrderReq(symbolId, orderType, tradeSide, volume, price = None, clientMsgId = None):
request = ProtoOANewOrderReq()
request.ctidTraderAccountId = currentAccountId
request.symbolId = int(symbolId)
request.orderType = ProtoOAOrderType.Value(orderType.upper())
request.tradeSide = ProtoOATradeSide.Value(tradeSide.upper())
request.volume = int(volume) * 100
if request.orderType == ProtoOAOrderType.LIMIT:
request.limitPrice = float(price)
elif request.orderType == ProtoOAOrderType.STOP:
request.stopPrice = float(price)
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
def sendNewMarketOrder(symbolId, tradeSide, volume, clientMsgId = None):
sendProtoOANewOrderReq(symbolId, "MARKET", tradeSide, volume, clientMsgId = clientMsgId)
# Setting optional client callbacks
client.setConnectedCallback(connected)
client.setDisconnectedCallback(disconnected)
client.setMessageReceivedCallback(onMessageReceived)
accountId = credentials["AccountId"]
setAccount(accountId)
symbolId = 22395
tradeSide ="BUY"
orderType = "MARKET"
volume = 1
sendProtoOANewOrderReq(symbolId, orderType, tradeSide, volume, price = None, clientMsgId = None)
# Starting the client service
client.startService()
reactor.run()
Replies
amusleh
23 Feb 2022, 09:15
Hi,
To open a position or send any other request you have to first authorize your trading account on your connection session by sending a ProtoOAAccountAuthReq message.
After your account got authorized and you received the ProtoOAAccountAuthRes response message you can start sending trading requests or getting account related data.
To open a new order you have to send a ProtoOANewOrderReq request, this request is used for both pending and market (position) orders.
Now regarding OpenApiPy package, once you received the ProtoOAAccountAuthRes message via MessageReceivedCallback or your Twisted deferred then you can send a ProtoOANewOrderReq.
In your posted code I see you call the sendProtoOANewOrderReq method before you start the client service and connection, that will not work, because there is no connection between you and API yet let alone the app and account authorization.
Please check my added comments at onMessageReceived method:
from ctrader_open_api import Client, Protobuf, TcpProtocol, Auth, EndPoints
from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import *
from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import *
from ctrader_open_api.messages.OpenApiMessages_pb2 import *
from ctrader_open_api.messages.OpenApiModelMessages_pb2 import *
from twisted.internet import reactor
from inputimeout import inputimeout, TimeoutOccurred
import json
import datetime
credentialsFile = open("credentials.json")
credentials = json.load(credentialsFile)
if __name__ == "__main__":
currentAccountId = None
hostType = input("Host (Live/Demo): ")
hostType = hostType.lower()
while hostType != "live" and hostType != "demo":
print(f"{hostType} is not a valid host type.")
hostType = input("Host (Live/Demo): ")
appClientId = credentials["ClientId"]
appClientSecret = credentials["Secret"]
isTokenAvailable = credentials["AccessToken"]
accessToken = None
if isTokenAvailable == False:
appRedirectUri = input("App Redirect URI: ")
auth = Auth(appClientId, appClientSecret, appRedirectUri)
authUri = auth.getAuthUri()
print(f"Please continue the authentication on your browser:\n {authUri}")
webbrowser.open_new(authUri)
print("\nThen enter the auth code that is appended to redirect URI immediatly (the code is after ?code= in URI)")
authCode = input("Auth Code: ")
token = auth.getToken(authCode)
if "accessToken" not in token:
raise KeyError(token)
print("Token: \n", token)
accessToken = token["accessToken"]
else:
accessToken = credentials["AccessToken"]
client = Client(EndPoints.PROTOBUF_LIVE_HOST if hostType.lower() == "live" else EndPoints.PROTOBUF_DEMO_HOST, EndPoints.PROTOBUF_PORT, TcpProtocol)
def setAccount(accountId):
global currentAccountId
if currentAccountId is not None:
sendProtoOAAccountLogoutReq()
currentAccountId = int(accountId)
sendProtoOAAccountAuthReq()
def sendProtoOAAccountAuthReq(clientMsgId = None):
request = ProtoOAAccountAuthReq()
request.ctidTraderAccountId = currentAccountId
request.accessToken = accessToken
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
def connected(client): # Callback for client connection
print("\nConnected")
request = ProtoOAApplicationAuthReq()
request.clientId = appClientId
request.clientSecret = appClientSecret
deferred = client.send(request)
deferred.addErrback(onError)
def disconnected(client, reason): # Callback for client disconnection
print("\nDisconnected: ", reason)
def onMessageReceived(client, message): # Callback for receiving all messages
if message.payloadType in [ProtoOASubscribeSpotsRes().payloadType, ProtoOAAccountLogoutRes().payloadType, ProtoHeartbeatEvent().payloadType]:
return
elif message.payloadType == ProtoOAApplicationAuthRes().payloadType:
print("API Application authorized\n")
print("Please use setAccount command to set the authorized account before sending any other command, try help for more detail\n")
print("To get account IDs use ProtoOAGetAccountListByAccessTokenReq command")
if currentAccountId is not None:
sendProtoOAAccountAuthReq()
return
elif message.payloadType == ProtoOAAccountAuthRes().payloadType:
protoOAAccountAuthRes = Protobuf.extract(message)
print(f"Account {protoOAAccountAuthRes.ctidTraderAccountId} has been authorized\n")
print("This acccount will be used for all future requests\n")
print("You can change the account by using setAccount command")
# This is where you can send a new order request
# This is the place that your account authorization
# response message is received
else:
print("Message received: \n", Protobuf.extract(message))
reactor.callLater(3, callable=executeUserCommand)
def onError(failure): # Call back for errors
print("Message Error: ", failure)
reactor.callLater(3, callable=executeUserCommand)
def executeUserCommand():
try:
print("\n")
userInput = inputimeout("Command (ex help): ", timeout=18)
except TimeoutOccurred:
print("Command Input Timeout")
reactor.callLater(3, callable=executeUserCommand)
return
userInputSplit = userInput.split(" ")
if not userInputSplit:
print("Command split error: ", userInput)
reactor.callLater(3, callable=executeUserCommand)
return
command = userInputSplit[0]
try:
parameters = [parameter if parameter[0] != "*" else parameter[1:] for parameter in userInputSplit[1:]]
except:
print("Invalid parameters: ", userInput)
reactor.callLater(3, callable=executeUserCommand)
if command in commands:
commands[command](*parameters)
else:
print("Invalid Command: ", userInput)
reactor.callLater(3, callable=executeUserCommand)
def sendProtoOAGetAccountListByAccessTokenReq(clientMsgId = None):
request = ProtoOAGetAccountListByAccessTokenReq()
request.accessToken = credentials["AccessToken"]
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
def sendProtoOAAssetListReq(clientMsgId = None):
request = ProtoOAAssetListReq()
request.ctidTraderAccountId = currentAccountId
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
def sendProtoOANewOrderReq(symbolId, orderType, tradeSide, volume, price = None, clientMsgId = None):
request = ProtoOANewOrderReq()
request.ctidTraderAccountId = currentAccountId
request.symbolId = int(symbolId)
request.orderType = ProtoOAOrderType.Value(orderType.upper())
request.tradeSide = ProtoOATradeSide.Value(tradeSide.upper())
request.volume = int(volume) * 100
if request.orderType == ProtoOAOrderType.LIMIT:
request.limitPrice = float(price)
elif request.orderType == ProtoOAOrderType.STOP:
request.stopPrice = float(price)
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
def sendNewMarketOrder(symbolId, tradeSide, volume, clientMsgId = None):
sendProtoOANewOrderReq(symbolId, "MARKET", tradeSide, volume, clientMsgId = clientMsgId)
# Setting optional client callbacks
client.setConnectedCallback(connected)
client.setDisconnectedCallback(disconnected)
client.setMessageReceivedCallback(onMessageReceived)
# Starting the client service
client.startService()
reactor.run()
@amusleh
william@hallsdesign.co.uk
03 Mar 2022, 18:12
RE: RE:
prenven570 said:
Edit:
i solved the problem of the unauthorized trading account, but the second question remains: How to open a position?
Hi, how did you solve the unauthorised trading account bit? I have this same issue and I am unsure how to solve. ( just changed my accountID to xxxxxxxx ).
Message received:
ctidTraderAccountId: xxxxxxxx
errorCode: "ACCOUNT_NOT_AUTHORIZED"
description: "Account is not authorized"
Any help is greatly appreciated.
@william@hallsdesign.co.uk
amusleh
04 Mar 2022, 07:22
RE: RE: RE:
william@hallsdesign.co.uk said:
prenven570 said:
Edit:
i solved the problem of the unauthorized trading account, but the second question remains: How to open a position?
Hi, how did you solve the unauthorised trading account bit? I have this same issue and I am unsure how to solve. ( just changed my accountID to xxxxxxxx ).
Message received:
ctidTraderAccountId: xxxxxxxx
errorCode: "ACCOUNT_NOT_AUTHORIZED"
description: "Account is not authorized"Any help is greatly appreciated.
Hi,
You have to send a ProtoOAAccountAuthReq before sending any other request for an account.
After you received the ProtoOAAccountAuthRes then you can start sending other types of requests for that account.
Please check console sample setAccount command code.
@amusleh
prenven570
04 Mar 2022, 09:18
RE: RE: RE:
william@hallsdesign.co.uk said:
prenven570 said:
Edit:
i solved the problem of the unauthorized trading account, but the second question remains: How to open a position?
Hi, how did you solve the unauthorised trading account bit? I have this same issue and I am unsure how to solve. ( just changed my accountID to xxxxxxxx ).
Message received:
ctidTraderAccountId: xxxxxxxx
errorCode: "ACCOUNT_NOT_AUTHORIZED"
description: "Account is not authorized"Any help is greatly appreciated.
I solved by using this code:
from ctrader_open_api import Client, Protobuf, TcpProtocol, Auth, EndPoints from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import * from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import * from ctrader_open_api.messages.OpenApiMessages_pb2 import * from ctrader_open_api.messages.OpenApiModelMessages_pb2 import * from twisted.internet import reactor import json import datetime
#you create a .json file with credentials ther's a sample on the github repository (jupyter sample)
credentialsFile = open("credentials-dev.json") credentials = json.load(credentialsFile)
host = EndPoints.PROTOBUF_LIVE_HOST if credentials["HostType"].lower() == "live" else EndPoints.PROTOBUF_DEMO_HOST client = Client(host, EndPoints.PROTOBUF_PORT, TcpProtocol)
def accountAuthResponseCallback(result): print("\nAccount authenticated") request = ProtoOASymbolsListReq() request.ctidTraderAccountId = credentials["AccountId"] request.includeArchivedSymbols = False deferred = client.send(request) def applicationAuthResponseCallback(result): print("\nApplication authenticated") request = ProtoOAAccountAuthReq() request.ctidTraderAccountId = credentials["AccountId"] request.accessToken = credentials["AccessToken"] deferred = client.send(request) deferred.addCallbacks(accountAuthResponseCallback, onError) def onError(client, failure): # Call back for errors print("\nMessage Error: ", failure) def disconnected(client, reason): # Callback for client disconnection print("\nDisconnected: ", reason) def onMessageReceived(client, message): # Callback for receiving all messages if message.payloadType in [ProtoHeartbeatEvent().payloadType, ProtoOAAccountAuthRes().payloadType, ProtoOAApplicationAuthRes().payloadType, ProtoOASymbolsListRes().payloadType, ProtoOAGetTrendbarsRes().payloadType]: return print("\nMessage received: \n", Protobuf.extract(message)) def connected(client): # Callback for client connection print("\nConnected") request = ProtoOAApplicationAuthReq() request.clientId = credentials["ClientId"] request.clientSecret = credentials["Secret"] deferred = client.send(request) deferred.addCallbacks(applicationAuthResponseCallback, onError) # Setting optional client callbacks client.setConnectedCallback(connected) client.setDisconnectedCallback(disconnected) client.setMessageReceivedCallback(onMessageReceived)
# Starting the client service
client.startService()
# Run Twisted reactor, we imported it earlier
reactor.run()
@prenven570
william@hallsdesign.co.uk
10 Mar 2022, 18:28
RE: RE: RE: RE:
Thanks for the help with this, think I have solved it too now. :)
prenven570 said:
william@hallsdesign.co.uk said:
prenven570 said:
Edit:
i solved the problem of the unauthorized trading account, but the second question remains: How to open a position?
Hi, how did you solve the unauthorised trading account bit? I have this same issue and I am unsure how to solve. ( just changed my accountID to xxxxxxxx ).
Message received:
ctidTraderAccountId: xxxxxxxx
errorCode: "ACCOUNT_NOT_AUTHORIZED"
description: "Account is not authorized"Any help is greatly appreciated.
I solved by using this code:
from ctrader_open_api import Client, Protobuf, TcpProtocol, Auth, EndPoints from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import * from ctrader_open_api.messages.OpenApiCommonMessages_pb2 import * from ctrader_open_api.messages.OpenApiMessages_pb2 import * from ctrader_open_api.messages.OpenApiModelMessages_pb2 import * from twisted.internet import reactor import json import datetime#you create a .json file with credentials ther's a sample on the github repository (jupyter sample)
credentialsFile = open("credentials-dev.json") credentials = json.load(credentialsFile)host = EndPoints.PROTOBUF_LIVE_HOST if credentials["HostType"].lower() == "live" else EndPoints.PROTOBUF_DEMO_HOST client = Client(host, EndPoints.PROTOBUF_PORT, TcpProtocol)
def accountAuthResponseCallback(result): print("\nAccount authenticated") request = ProtoOASymbolsListReq() request.ctidTraderAccountId = credentials["AccountId"] request.includeArchivedSymbols = False deferred = client.send(request) def applicationAuthResponseCallback(result): print("\nApplication authenticated") request = ProtoOAAccountAuthReq() request.ctidTraderAccountId = credentials["AccountId"] request.accessToken = credentials["AccessToken"] deferred = client.send(request) deferred.addCallbacks(accountAuthResponseCallback, onError) def onError(client, failure): # Call back for errors print("\nMessage Error: ", failure) def disconnected(client, reason): # Callback for client disconnection print("\nDisconnected: ", reason) def onMessageReceived(client, message): # Callback for receiving all messages if message.payloadType in [ProtoHeartbeatEvent().payloadType, ProtoOAAccountAuthRes().payloadType, ProtoOAApplicationAuthRes().payloadType, ProtoOASymbolsListRes().payloadType, ProtoOAGetTrendbarsRes().payloadType]: return print("\nMessage received: \n", Protobuf.extract(message)) def connected(client): # Callback for client connection print("\nConnected") request = ProtoOAApplicationAuthReq() request.clientId = credentials["ClientId"] request.clientSecret = credentials["Secret"] deferred = client.send(request) deferred.addCallbacks(applicationAuthResponseCallback, onError) # Setting optional client callbacks client.setConnectedCallback(connected) client.setDisconnectedCallback(disconnected) client.setMessageReceivedCallback(onMessageReceived)# Starting the client service
client.startService()
# Run Twisted reactor, we imported it earlier
reactor.run()
@william@hallsdesign.co.uk
prenven570
22 Feb 2022, 12:37 ( Updated at: 22 Feb 2022, 12:44 )
RE:
@prenven570