AWS chalice rest API
AWS chalice rest API
21 Jun 2023, 15:09
Hi,
I am trying to use AWS chalice net server for GET alert sign from Tradingview that is connected with a webhook, the server page reads in JSON (brackets) format and will then POST to a Python script where i am planning to execute orders that will be sent to Ctrader. The problem is
1. Python script for connecting with credentials?
2. Python script that executes orders?
Have someone done any similar to this?
In the example below i use Alpaca as the broker, but looking for a similar layout for Ctrader. SO DOES ANYONE HAVE PYTHON CODES THAT CAN REPLACE THE MARKED IN RED THAT IS FOR ALPACA?
Thanks for any replies.
Replies
daytrayding.andreas
22 Jun 2023, 07:53
RE:
Thanks! i appreciate your reply. I have tried to solve it with the code below, but i have very little experience in coding so i have maybe all i need in my code, but the structure is maybe totally off, i appreciate if you have time to take a look at what i have made and guide me further if possible.
For an understanding of what i am trying to accomplish, i have followed this youtube video for making an AWS chalice server and then used alpaca as broker, but know i am trying to implement ctrader into the app.py script. Link: https://www.youtube.com/watch?v=TKAo_Z-hzQs&t=1872s
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 requests, json
from chalice import Chalice
app = Chalice(app_name='test')
hostType = input("Host (Live/Demo): ")
host = EndPoints.PROTOBUF_LIVE_HOST if hostType.lower() == "live" else EndPoints.PROTOBUF_DEMO_HOST
client = Client(host, EndPoints.PROTOBUF_PORT, TcpProtocol)
def onError(failure): # Call back for errors
print("Message Error: ", failure)
def connected(client): # Callback for client connection
print("\nConnected")
# Now we send a ProtoOAApplicationAuthReq
request = ProtoOAApplicationAuthReq()
request.clientId = "xxxxxxxx"
request.clientSecret = "xxxxxxxxx"
# Client send method returns a Twisted deferred
deferred = client.send(request)
# You can use the returned Twisted deferred to attach callbacks
# for getting message response or error backs for getting error if something went wrong
# deferred.addCallbacks(onProtoOAApplicationAuthRes, onError)
deferred.addErrback(onError)
def disconnected(client, reason): # Callback for client disconnection
print("\nDisconnected: ", reason)
def onMessageReceived(client, message): # Callback for receiving all messages
print("Message received: \n", Protobuf.extract(message))
# Setting optional client callbacks
client.setConnectedCallback(connected)
client.setDisconnectedCallback(disconnected)
client.setMessageReceivedCallback(onMessageReceived)
# Starting the client service
client.startService()
# Run Twisted reactor
reactor.run()
@app.route('/Buy_Stock', methods=['POST'])
def Buy_Stock():
request = app.current_request
webhook_message = request.json_body
data = {
"symbol": webhook_message['ticker'],
"qty": 1,
"side": "buy",
"type": "limit",
"limit_price": webhook_message['close'],
"time_in_force": "gtc",
"order_class": "bracket",
"take_profit": {
"limit_price": webhook_message['close'] * 1.05
},
"stop_loss": {
"stop_price": webhook_message['close'] * 0.98,
}
}
r = requests.post(ORDERS_URL, json=data, headers=HEADERS)
response = json.loads(r.content)
print(response)
print(response.keys())
return {
'message': ' I bought the stock!',
'webhook_message': webhook_message
}
Thanks for any replies
manelfx9530 said:
Follow their code in their github and you will find your answers. I say this as a guy that understand little of coding this type of stuff and was able to do it.
@daytrayding.andreas
manelfx9530
22 Jun 2023, 12:49
( Updated at: 22 Jun 2023, 12:50 )
You are missing these two functions in your code
def accountAuthResponseCallback(result):
print("\nAccount authenticated")
# From here you build your next step
def applicationAuthResponseCallback(result):
print("\nApplication authenticated")
request = ProtoOAAccountAuthReq()
request.ctidTraderAccountId = credentials["AccountId"]
request.accessToken = credentials["AccessToken"]
deferred = client.send(request)
deferred.addCallbacks(accountAuthResponseCallback, onError)
And make this two lines like this:
deferred.addCallbacks(onProtoOAApplicationAuthRes, onError)
# deferred.addErrback(onError)
First of all you need to go to ctrader openapi and create an application to get your credentials, then place the credentials in a file like they do in their github example and if you have done everything right plus modified your code with what i said you should be able to connect, authenticate your application and authorize the account to start trading, from there is a question of try and error and understanding their docs.
@manelfx9530
daytrayding.andreas
23 Jun 2023, 08:23
RE:
Thank you very much! i appreciate all the effort you have put in to help me, i will try to implement your suggestions, and post if it worked.
@daytrayding.andreas
rosland.andreas
26 Jun 2023, 13:19
RE:
Hi, i have tried to implement the lines you sent, but keep getting the errors below on VSC and CMD after i tried to run and post a webhook from Insomnia local host, any idea what causing these errors?
Appreciate any suggestions.
VSC 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 requests, json
from chalice import Chalice
app = Chalice(app_name='test')
hostType = input("Host (Live/Demo): ")
host = EndPoints.PROTOBUF_LIVE_HOST if hostType.lower() == "live" else EndPoints.PROTOBUF_DEMO_HOST
client = Client(host, EndPoints.PROTOBUF_PORT, TcpProtocol)
def onError(failure): # Call back for errors
print("Message Error: ", failure)
def connected(client): # Callback for client connection
print("\nConnected")
# Now we send a ProtoOAApplicationAuthReq
request = ProtoOAApplicationAuthReq()
request.clientId = "XXXXXXXXX"
request.clientSecret = "XXXXXXXX"
# Client send method returns a Twisted deferred
deferred = client.send(request)
# You can use the returned Twisted deferred to attach callbacks
# for getting message response or error backs for getting error if something went wrong
# deferred.addCallbacks(onProtoOAApplicationAuthRes, onError)
deferred.addCallbacks(onProtoOAApplicationAuthRes, onError)
def disconnected(client, reason): # Callback for client disconnection
print("\nDisconnected: ", reason)
def onMessageReceived(client, message): # Callback for receiving all messages
print("Message received: \n", Protobuf.extract(message))
def accountAuthResponseCallback(result):
print("\nAccount authenticated")
# From here you build your next step
def applicationAuthResponseCallback(result):
print("\nApplication authenticated")
request = ProtoOAAccountAuthReq()
request.ctidTraderAccountId = credentials["XXXXXXXXXX"]
request.accessToken = credentials["XXXXX"]
deferred = client.send(request)
deferred.addCallbacks(accountAuthResponseCallback, onError)
# Setting optional client callbacks
client.setConnectedCallback(connected)
client.setDisconnectedCallback(disconnected)
client.setMessageReceivedCallback(onMessageReceived)
# Starting the client service
client.startService()
# Run Twisted reactor
reactor.run()
@app.route('/Buy_Stock', methods=['POST'])
def Buy_Stock():
request = app.current_request
webhook_message = request.json_body
data = {
"symbol": webhook_message['ticker'],
"qty": 1,
"side": "buy",
"type": "limit",
"limit_price": webhook_message['close'],
"time_in_force": "gtc",
"order_class": "bracket",
"take_profit": {
"limit_price": webhook_message['close'] * 1.05
},
"stop_loss": {
"stop_price": webhook_message['close'] * 0.98,
}
}
r = requests.post(ORDERS_URL, json=data, headers=HEADERS)
response = json.loads(r.content)
print(response)
print(response.keys())
return {
'message': ' I bought the stock!',
'webhook_message': webhook_message
}
VSC ERROR:
Connected
Unhandled Error
Traceback (most recent call last):
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\python\log.py", line 101, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\python\log.py", line 85, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\python\context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\python\context.py", line 83, in callWithContext
return func(*args, **kw)
--- <exception caught here> ---
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\selectreactor.py", line 149, in _doReadOrWrite
why = getattr(selectable, method)()
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\tcp.py", line 614, in doConnect
self._connectDone()
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\tcp.py", line 642, in _connectDone
self.protocol.makeConnection(self)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\protocols\tls.py", line 211, in makeConnection
ProtocolWrapper.makeConnection(self, transport)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\protocols\policies.py", line 74, in
makeConnection
self.wrappedProtocol.makeConnection(self)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\protocol.py", line 508, in
makeConnection
self.connectionMade()
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\endpoints.py", line 142, in connectionMade
self._wrappedProtocol.makeConnection(self.transport)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\protocol.py", line 508, in
makeConnection
self.connectionMade()
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\ctrader_open_api\tcpProtocol.py", line 21, in connectionMade
self.factory.connected(self)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\ctrader_open_api\factory.py", line 11, in connected
self.client._connected(protocol)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\ctrader_open_api\client.py", line 32, in _connected
self._connectedCallback(self)
File "c:\Users\roslaan\Documents\Privat\Bot\VSC\API\test\app.py", line 30, in connected
deferred.addCallbacks(onProtoOAApplicationAuthRes, onError)
builtins.NameError: name 'onProtoOAApplicationAuthRes' is not defined
Disconnected: [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionLost'>: Connection to the other side was lost in a non-clean fashion: Connection lost.
]
Unhandled Error
Traceback (most recent call last):
File "c:\Users\roslaan\Documents\Privat\Bot\VSC\API\test\app.py", line 66, in <module>
reactor.run()
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\base.py", line 1318, in run self.mainLoop()
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\base.py", line 1331, in mainLoop
reactorBaseSelf.doIteration(t)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\selectreactor.py", line 143, in doSelect
_logrun(selectable, _drdw, selectable, method)
--- <exception caught here> ---
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\python\log.py", line 101, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\python\log.py", line 85, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\python\context.py", line 118, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\python\context.py", line 83, in callWithContext
return func(*args, **kw)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\selectreactor.py", line 154, in _doReadOrWrite
self._disconnectSelectable(selectable, why, method == "doRead")
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\posixbase.py", line 306, in _disconnectSelectable
selectable.connectionLost(failure.Failure(why))
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\tcp.py", line 507, in connectionLost
self._commonConnection.connectionLost(self, reason)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\tcp.py", line 325, in connectionLost
protocol.connectionLost(reason)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\protocols\tls.py", line 394, in connectionLost
ProtocolWrapper.connectionLost(self, reason)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\protocols\policies.py", line 113, in connectionLost
self.wrappedProtocol.connectionLost(reason)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\internet\endpoints.py", line 161, in connectionLost
return self._wrappedProtocol.connectionLost(reason)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\application\internet.py", line 467,
in connectionLost
self._lostNotification(reason)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\twisted\application\internet.py", line 660,
in <lambda>
self._factory, lambda _: self._clientDisconnected()
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\automat\_methodical.py", line 235, in _clientDisconnected
(outputs, outTracer) = transitioner.transition(self)
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\automat\_core.py", line 157, in transition
outState, outputSymbols = self._automaton.outputForInput(self._state,
File "C:\Users\roslaan\AppData\Local\Programs\Python\Python310\lib\site-packages\automat\_core.py", line 137, in outputForInput
raise NoTransition(state=inState, symbol=inputSymbol)
automat._core.NoTransition: no transition for MethodicalInput(method=<function _ClientMachine._clientDisconnected at 0x000001EB74FCD5A0>) in MethodicalState(method=<function _ClientMachine._connecting at 0x000001EB74FCC940>)
CMD ERROR:
{'code': 40010001, 'message': 'invalid order type'}
dict_keys(['code', 'message'])
127.0.0.1 - - [26/Jun/2023 09:03:53] "POST /Buy_Stock HTTP/1.1" 200 -
@rosland.andreas
daytrayding.andreas
03 Jul 2023, 11:27
RE:
Hi, I am struggling to fix my problem, do you have time to assist with email further? it sounds like you have done something similar with connecting the ctrader API to AWS serverless net server that receives json bracket data from tradingview with webhook. Or if you have other contacts that i can contact for getting the bot up and running, that would also be very helpful. Thanks for any replies@daytrayding.andreas
manelfx9530
21 Jun 2023, 22:44 ( Updated at: 21 Jun 2023, 22:45 )
Follow their code in their github and you will find your answers. I say this as a guy that understand little of coding this type of stuff and was able to do it.
@manelfx9530