How to get the positionId using openApiPy?
How to get the positionId using openApiPy?
23 Feb 2022, 09:19
I need the positionId of the opened position in order to close them with:
sendProtoOAClosePositionReq(positionId, volume, clientMsgId = None)
I tried to print that value doing:
print(request.positionId) inside the sendProtoOAReconcileReq function,
but i get an attribute error. This is part of my code:
#I send a market order
def sendProtoOANewOrderReq(results):
symbolId = 22395
volume = 1
clientMsgId = None
request = ProtoOANewOrderReq()
request.ctidTraderAccountId = currentAccountId
request.symbolId = int(symbolId)
request.orderType = ProtoOAOrderType.MARKET
request.tradeSide = ProtoOATradeSide.BUY
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)
deferred.addCallbacks(sendProtoOAReconcileReq, onError)
#I want to get positionId, but I get an attribute error
def sendProtoOAReconcileReq(result):
clientMsgId = None
request = ProtoOAReconcileReq()
request.ctidTraderAccountId = currentAccountId
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
print(request.positionId)
Replies
prenven570
24 Feb 2022, 09:25
RE:
amusleh said:
Hi,
To get a position ID you can either use ExecutionEvent or Reconcile request.
The reconcile request gives you list of all open account orders with their detail, and ExecutionEvent occurs whenever you perform a trading operation on your account.
In our console sample use setAccount command to authorize a trading account, ex: setAccount account_Id
For example, if I use the console sample, and set account to one of my accounts, and then if I create a new market order I will receive the execution event:
ctidTraderAccountId: 16608956 executionType: ORDER_FILLED position { positionId: 263362553 tradeData { symbolId: 2 volume: 100000 tradeSide: SELL openTimestamp: 1645685625147 guaranteedStopLoss: false } positionStatus: POSITION_STATUS_OPEN swap: 0 price: 1.34984 utcLastUpdateTimestamp: 1645685625147 commission: -4 marginRate: 1.34984 mirroringCommission: 0 guaranteedStopLoss: false usedMargin: 270 moneyDigits: 2 } order { orderId: 399293765 tradeData { symbolId: 2 volume: 100000 tradeSide: SELL openTimestamp: 1645685624943 guaranteedStopLoss: false } orderType: MARKET orderStatus: ORDER_STATUS_FILLED executionPrice: 1.34984 executedVolume: 100000 utcLastUpdateTimestamp: 1645685625147 closingOrder: false clientOrderId: "ctd-df2b5de6032c47609a443bf746b136d0" timeInForce: IMMEDIATE_OR_CANCEL positionId: 263362553 } deal { dealId: 365614484 orderId: 399293765 positionId: 263362553 volume: 100000 filledVolume: 100000 symbolId: 2 createTimestamp: 1645685624943 executionTimestamp: 1645685625147 utcLastUpdateTimestamp: 1645685625147 executionPrice: 1.34984 tradeSide: SELL dealStatus: FILLED marginRate: 1.34984 commission: -4 baseToUsdConversionRate: 1.34984 moneyDigits: 2 } isServerEvent: false
You see in above execution event, the position ID, order ID and all the other details are there.
You have to authorize your connection to an account, then you will receive the execution event, for getting execution events use the general MessageReceivedCallback:
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) client.setMessageReceivedCallback(onMessageReceived)
The above code is part of our console sample.
To get orders data with reconcile request you just have to send a reconcile request after account authorization and you will receive back the response:
def sendProtoOAReconcileReq(clientMsgId = None): request = ProtoOAReconcileReq() request.ctidTraderAccountId = currentAccountId deferred = client.send(request, clientMsgId = clientMsgId) deferred.addErrback(onError)
You can use both the deferred or general message received call back for getting back the response.
Here is an example of reconcile response:
Message received: ctidTraderAccountId: 16608956 position { positionId: 263362553 tradeData { symbolId: 2 volume: 100000 tradeSide: SELL openTimestamp: 1645685625147 guaranteedStopLoss: false } positionStatus: POSITION_STATUS_OPEN swap: 0 price: 1.34984 utcLastUpdateTimestamp: 1645685625147 commission: -4 marginRate: 1.34984 mirroringCommission: 0 guaranteedStopLoss: false usedMargin: 270 moneyDigits: 2 }
Now, regarding your issue, there is no position Id on reconcile request, the request is a message you will send for getting positions/orders data.
Please read the Open API documentation, review the console sample code, and play with it, then you will understand how it works.
Thanks for your answer. I know that I can see the positionId and other information in the output, but I think I need a way to store the positionId number inside a variable, so I can close the opened position. When I open a position, I'm not able to close it, because "positionId" is not defined, this happens even with a reconcile request. So what can I do to close the opened position?
@prenven570
amusleh
24 Feb 2022, 10:22
Hi,
If you can receive the response then getting the position ID or any other field of it is very easy.
Here is an example:
def onMessageReceived(client, message): # Callback for receiving all messages
# execute a trade on your account, to get an execution event
if message.payloadType == ProtoOAExecutionEvent().payloadType:
print("Execution event received")
executionEvent = Protobuf.extract(message)
print(executionEvent.position.positionId)
# send a reconcile request to receive a reconcile response
if message.payloadType == ProtoOAReconcileRes().payloadType:
print("Reconcile response received")
reconcileRes = Protobuf.extract(message)
for position in reconcileRes.position:
print(position.positionId)
for order in reconcileRes.order:
print(order.orderId)
When you receive a message you can check it's payload type, if it's of your interested type then you can serialize the message to that type and access it's data.
In case you used the Twisted deferred for getting a request response you don't have to do the serialization, it will be done automatically and your callback will be called with the request message response, you can't use the Twisted deferreds for events like spot event, execution event, etc... for them you have to use the message received call back.
@amusleh
prenven570
24 Feb 2022, 10:28
RE:
amusleh said:
Hi,
If you can receive the response then getting the position ID or any other field of it is very easy.
Here is an example:
def onMessageReceived(client, message): # Callback for receiving all messages # execute a trade on your account, to get an execution event if message.payloadType == ProtoOAExecutionEvent().payloadType: print("Execution event received") executionEvent = Protobuf.extract(message) print(executionEvent.position.positionId) # send a reconcile request to receive a reconcile response if message.payloadType == ProtoOAReconcileRes().payloadType: print("Reconcile response received") reconcileRes = Protobuf.extract(message) for position in reconcileRes.position: print(position.positionId) for order in reconcileRes.order: print(order.orderId)
When you receive a message you can check it's payload type, if it's of your interested type then you can serialize the message to that type and access it's data.
In case you used the Twisted deferred for getting a request response you don't have to do the serialization, it will be done automatically and your callback will be called with the request message response, you can't use the Twisted deferreds for events like spot event, execution event, etc... for them you have to use the message received call back.
Thanks a lot!!! It worked
@prenven570
tangducbao101
07 Jul 2023, 15:14
RE:
ProtoOAReconcileReq is a good API to check opening positions and orders.
@tangducbao101
amusleh
24 Feb 2022, 09:07
Hi,
To get a position ID you can either use ExecutionEvent or Reconcile request.
The reconcile request gives you list of all open account orders with their detail, and ExecutionEvent occurs whenever you perform a trading operation on your account.
In our console sample use setAccount command to authorize a trading account, ex: setAccount account_Id
For example, if I use the console sample, and set account to one of my accounts, and then if I create a new market order I will receive the execution event:
You see in above execution event, the position ID, order ID and all the other details are there.
You have to authorize your connection to an account, then you will receive the execution event, for getting execution events use the general MessageReceivedCallback:
The above code is part of our console sample.
To get orders data with reconcile request you just have to send a reconcile request after account authorization and you will receive back the response:
You can use both the deferred or general message received call back for getting back the response.
Here is an example of reconcile response:
Now, regarding your issue, there is no position Id on reconcile request, the request is a message you will send for getting positions/orders data.
Please read the Open API documentation, review the console sample code, and play with it, then you will understand how it works.
@amusleh