How to use current price inside an if condition? (OpenApiPy)
How to use current price inside an if condition? (OpenApiPy)
27 Feb 2022, 11:52
Hello.
My goal is to set a buy or sell condition inside a function,
using the current price updated.
After I send a ProtoOASubscribeSpotsReq I callback the "buy_sell_condition" function,
but when i run all i get this error: builtins.AttributeError: ask
This is some of my code:
Thanks.
def buy_sell_condition(result):
while True:
price_message = Protobuf.extract(result)
current_price = price_message.ask
if current_price >= #some condition:
#buy
break
def sendProtoOASubscribeSpotsReq(result):
symbolId = 22395
timeInSeconds = 2
subscribeToSpotTimestamp = False
clientMsgId = None
request = ProtoOASubscribeSpotsReq()
request.ctidTraderAccountId = currentAccountId
request.symbolId.append(int(symbolId))
request.subscribeToSpotTimestamp = subscribeToSpotTimestamp if type(subscribeToSpotTimestamp) is bool else bool(subscribeToSpotTimestamp)
deferred = client.send(request, clientMsgId = clientMsgId)
deferred.addErrback(onError)
deferred.addCallbacks(buy_sell_condition, onError)
def onMessageReceived(client, message): # Callback for receiving all messages
if message.payloadType in [ProtoOASpotEvent().payloadType, ProtoHeartbeatEvent().payloadType, ProtoOAAccountAuthRes().payloadType, ProtoOAApplicationAuthRes().payloadType, ProtoOASymbolsListRes().payloadType, ProtoOAGetTrendbarsRes().payloadType]:
return
print("\nMessage received: \n", Protobuf.extract(message))
Replies
prenven570
28 Feb 2022, 09:23
RE:
amusleh said:
Hi,
The way you coded it is not correct.
I see most of your issues are related to your Python skills not to Open API.
If you want to send a new order request based on a condition that uses current price then you have to use the Spot event for getting the price, once you got the price check the condition if it's ok then send a new order request.
ProtoOASpotEvent has the bid/ask properties, and it's not in actual price, you have to transform is to price by dividing it to 100000.
The OpenApiPy uses Twisted and you have to use callbacks, the execution flow is not sequential.
Hello, thanks for the answer. But how can I get the updated price in another function?
I get it inside the onMessageReceived function, but when I use global to use price variable in another function, I don't get the updated price.
But I get only one price: 3928229, 3928229, 3928229...
@prenven570
amusleh
01 Mar 2022, 09:25
( Updated at: 01 Mar 2022, 09:26 )
Hi,
There are lots of ways that you can do that, it depends on what design pattern you follow.
A simple solution will be to create a symbol class, get all symbols from API and transform them to your symbol class instances.
The symbol class should have a bid and ask property, store all those Symbols inside a list or dictionary with their name as key.
The symbols collection should be available on your global scope or the on message received method scope.
Then subscribe to spot event for all those symbols, whenever you receive the bid/ask prices of a symbol update the symbol instance bid/ask properties.
This way you will have access always to latest bid/ask prices of all symbols.
As I said on my previous post, it's not something related to Open API or OpenApiPy, it's related to your Python coding skill.
@amusleh
prenven570
01 Mar 2022, 13:59
RE:
amusleh said:
Hi,
There are lots of ways that you can do that, it depends on what design pattern you follow.
A simple solution will be to create a symbol class, get all symbols from API and transform them to your symbol class instances.
The symbol class should have a bid and ask property, store all those Symbols inside a list or dictionary with their name as key.
The symbols collection should be available on your global scope or the on message received method scope.
Then subscribe to spot event for all those symbols, whenever you receive the bid/ask prices of a symbol update the symbol instance bid/ask properties.
This way you will have access always to latest bid/ask prices of all symbols.
As I said on my previous post, it's not something related to Open API or OpenApiPy, it's related to your Python coding skill.
Hello, yes it's probably related to my coding skills.
It would be nice if there were more concrete examples in the openApiPy repository, in this way people who haven't much experience would be able to code some basic systems.
I think I'm not asking something that hard, only how to set correctly a price condition, it would be very helpful. Please, think about it. Thanks.
@prenven570
amusleh
01 Mar 2022, 14:26
Hi,
You can do it like this:
# this will contain all symbol IDs with their bid/ask prices
symbolsData = dict()
def symbolsResponseCallback(result):
print("\nSymbols received")
symbols = Protobuf.extract(result)
global symbolsData
for symbol in symbols.symbol:
symbolsData.append(symbol.symbolId, (0, 0))
spotRequest = ProtoOASubscribeSpotsReq()
spotRequest.symbolId = symbol.symbolId
spotRequest.ctidTraderAccountId = credentials["AccountId"]
deferred = client.send(request)
deferred.addErrback(onError)
def accountAuthResponseCallback(result):
print("\nAccount authenticated")
request = ProtoOASymbolsListReq()
request.ctidTraderAccountId = credentials["AccountId"]
request.includeArchivedSymbols = False
deferred = client.send(request)
deferred.addCallbacks(symbolsResponseCallback, onError)
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
elif message.payloadType == ProtoOASpotEvent().payloadType:
global symbolsData
spotEvent = Protobuf.extract(message)
symbolsData[spotEvent.symbolId] = (spotEvent.bid / 100000, spotEvent.ask / 100000)
# now you have the symbol prices, do anything you want to here or by using
# the symbolsData dictionary
#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)
My code might have some issues as I haven't tested it but it will give you an idea.
@amusleh
prenven570
01 Mar 2022, 15:31
RE:
amusleh said:
Hi,
You can do it like this:
# this will contain all symbol IDs with their bid/ask prices symbolsData = dict() def symbolsResponseCallback(result): print("\nSymbols received") symbols = Protobuf.extract(result) global symbolsData for symbol in symbols.symbol: symbolsData.append(symbol.symbolId, (0, 0)) spotRequest = ProtoOASubscribeSpotsReq() spotRequest.symbolId = symbol.symbolId spotRequest.ctidTraderAccountId = credentials["AccountId"] deferred = client.send(request) deferred.addErrback(onError) def accountAuthResponseCallback(result): print("\nAccount authenticated") request = ProtoOASymbolsListReq() request.ctidTraderAccountId = credentials["AccountId"] request.includeArchivedSymbols = False deferred = client.send(request) deferred.addCallbacks(symbolsResponseCallback, onError) 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 elif message.payloadType == ProtoOASpotEvent().payloadType: global symbolsData spotEvent = Protobuf.extract(message) symbolsData[spotEvent.symbolId] = (spotEvent.bid / 100000, spotEvent.ask / 100000) # now you have the symbol prices, do anything you want to here or by using # the symbolsData dictionary #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)
My code might have some issues as I haven't tested it but it will give you an idea.
Thank you a lot for the example.
yes, there's an error on line 25:
AttributeError: 'dict' object has no attribute 'append'
@prenven570
crazzy.dev.freelance
06 Feb 2023, 19:42
Implementation of all this stuff is far away from user-friendly and far far away from client-oriented one, too. Hope in the feature it will be reworked and fit into "python-ic" way of doing things.
amusleh said:
Hi,
You can change the append call to adding by key: symbolsData[symbol.symbolId] = (0, 0)
@crazzy.dev.freelance
crazzy.dev.freelance
06 Feb 2023, 19:46
Re:
amusleh said:
Hi,
You can change the append call to adding by key: symbolsData[symbol.symbolId] = (0, 0)
Implementation of all this stuff is far away from user-friendly and far far away from client-oriented one, too.
Hope in the feature it will be reworked and fit into "python-ic" way of doing things.
Will give one straight example - why the hack, creating a MARKET order wont allow to set StopLoss and TakeProfit - while it uses actual symbol entry price and same time you can create LIMIT order using StopLoss and TakeProfit - but this time - you can not use current symbol price without indicating it explicitly?
You need to code some additional modules and callbacks and a lot of stuff just to get the simple stuff to work.
@crazzy.dev.freelance
amusleh
28 Feb 2022, 09:02
Hi,
The way you coded it is not correct.
I see most of your issues are related to your Python skills not to Open API.
If you want to send a new order request based on a condition that uses current price then you have to use the Spot event for getting the price, once you got the price check the condition if it's ok then send a new order request.
ProtoOASpotEvent has the bid/ask properties, and it's not in actual price, you have to transform is to price by dividing it to 100000.
The OpenApiPy uses Twisted and you have to use callbacks, the execution flow is not sequential.
@amusleh