AWS chalice rest API

Created at 21 Jun 2023, 15:09
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
DA

daytrayding.andreas

Joined 19.05.2022

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. 


@daytrayding.andreas
Replies

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

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