ejtraderCT
ejtraderCT copied to clipboard
There seems to be an issue with executing orders after they have been successfully executed twice before.
Hi, After executing two consecutive trades using BUY and SELL Market types the next ones cannot be executed the log says it were executed but they aren't.
For example i open a Buy order and then i try to close it using the method close_all() everything works fine. (I use this method because the close position by id doesn't work at all).
After that first successful execution if i try to open another one (in the same session) the new buy order executes correctly but if i try to use again the close_all method the buy order still persists in the market.
Another scenery is: I can open many buy market orders but i cannot close them (using the close all method).
my implementations:
Buy ORDER
if not self.api.isconnected():
raise CTraderDisconnected("CTrader is not connected")
try:
logger.info(f"🕦 Buying ${order.quantity} from {order.symbol}")
price = self.api.quote()
logger.info(f"Quote: {price=}")
price = price[order.symbol]["bid"]
symbol = order.symbol
volume = order.quantity
stop_loss = 0
take_profit = 0
oid = self.api.buy(symbol=symbol, volume=volume, stoploss=stop_loss, takeprofit=take_profit)
logger.info(f"CTrader Position {oid}")
Close all:
positions = self.api.positions()
if len(positions) < 1:
break
logger.info(positions)
self.api.close_all()
time.sleep(5)
Sometimes, the second try produces an unexpected infinite loop with a number of 16 digits.
I have some thoughts on what might be going on, but I need to test and debug those ideas when the market opens with a demo account.
Cheers
First and foremost, my friend, I appreciate your input on the subject of consecutive order placements. I've run into some trouble with Jupyter Notebook and the fix api, however, I plan to run some tests based on your insights. Please know that any PRs are highly encouraged. I apologize for my late response, I've been heavily involved in an AI project aimed at the financial market recently. I intend to perform the tests this week and aim to resolve some bugs. I've observed an issue with the FIX API concerning pauses between successive executions - this hasn't always been the case. I've also noted disparities across different brokers, particularly between demo and real accounts.
Hi, After executing two consecutive trades using BUY and SELL Market types the next ones cannot be executed the log says it were executed but they aren't.
For example i open a Buy order and then i try to close it using the method close_all() everything works fine. (I use this method because the close position by id doesn't work at all).
After that first successful execution if i try to open another one (in the same session) the new buy order executes correctly but if i try to use again the close_all method the buy order still persists in the market.
Another scenery is: I can open many buy market orders but i cannot close them (using the close all method).
my implementations:
Buy ORDER
if not self.api.isconnected(): raise CTraderDisconnected("CTrader is not connected") try: logger.info(f"🕦 Buying ${order.quantity} from {order.symbol}") price = self.api.quote() logger.info(f"Quote: {price=}") price = price[order.symbol]["bid"] symbol = order.symbol volume = order.quantity stop_loss = 0 take_profit = 0 oid = self.api.buy(symbol=symbol, volume=volume, stoploss=stop_loss, takeprofit=take_profit) logger.info(f"CTrader Position {oid}")Close all:
positions = self.api.positions() if len(positions) < 1: break logger.info(positions) self.api.close_all() time.sleep(5)Sometimes, the second try produces an unexpected infinite loop with a number of 16 digits.
I have some thoughts on what might be going on, but I need to test and debug those ideas when the market opens with a demo account.
Cheers
First and foremost, my friend, I appreciate your input on the subject of consecutive order placements. I've run into some trouble with Jupyter Notebook and the fix api, however, I plan to run some tests based on your insights. Please know that any PRs are highly encouraged. I apologize for my late response, I've been heavily involved in an AI project aimed at the financial market recently. I intend to perform the tests this week and aim to resolve some bugs. I've observed an issue with the FIX API concerning pauses between successive executions - this hasn't always been the case. I've also noted disparities across different brokers, particularly between demo and real accounts.
First and foremost, my friend, I appreciate your input on the subject of consecutive order placements. I've run into some trouble with Jupyter Notebook and the fix api, however, I plan to run some tests based on your insights. Please know that any PRs are highly encouraged. I apologize for my late response, I've been heavily involved in an AI project aimed at the financial market recently. I intend to perform the tests this week and aim to resolve some bugs. I've observed an issue with the FIX API concerning pauses between successive executions - this hasn't always been the case. I've also noted disparities across different brokers, particularly between demo and real accounts.
Hi, I'm working on my spare time, and currently, I haven't had any success in trying to fix the problems. I am currently trying to understand how the positions are handled in the position list attribute, and it's good to know that PRs are welcome. Once I fix the positions problem, I'll be creating one.
I'd also like to mention that I have noticed the differences related to demo and real accounts.
btw, Congratulations on your AI project, and I wish you the best!
I have found the problem.
When tag 35="AP" is received from the Broker, the parse_trade_message method searches in the binary data for the end of the FIX message, which in all cases is the checksum tag (tag 10)
match = re.search(rb"10=\d{3}\x01", self.tstream.peek(self.tstream.count()))
However, the FIX message received contains various messages grouped into just one response, as shown in the following example:
b'8=FIX.4.4\x019=162\x0135=AP\x0134=2\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0155=10014\x01710=1\x01721=349730793\x01727=2\x01728=0\x01730=15347.9\x01702=1\x01704=1\x01705=0\x0110=218\x018=FIX.4.4\x019=162\x0135=AP\x0134=3\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0155=10014\x01710=1\x01721=349731225\x01727=2\x01728=0\x01730=15349.8\x01702=1\x01704=1\x01705=0\x0110=211\x018=FIX.4.4\x019=137\x0135=j\x0134=4\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0158=ORDER_NOT_FOUND:no orders found\x01379=1\x01380=0\x0110=078\x01'
If we carefully look into the received response, we can split it into 3 FIX messages:
b'8=FIX.4.4\x019=162\x0135=AP\x0134=2\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0155=10014\x01710=1\x01721=349730793\x01727=2\x01728=0\x01730=15347.9\x01702=1\x01704=1\x01705=0\x0110=218
8=FIX.4.4\x019=162\x0135=AP\x0134=3\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0155=10014\x01710=1\x01721=349731225\x01727=2\x01728=0\x01730=15349.8\x01702=1\x01704=1\x01705=0\x0110=211
18=FIX.4.4\x019=137\x0135=j\x0134=4\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0158=ORDER_NOT_FOUND:no orders found\x01379=1\x01380=0\x0110=078\x01'
Unfortunately, the regex is matching just the first one, resulting in parsing only the first message and causing the position list to contain only ONE position. This is why we can't close the other orders. Furthermore, related to this problem, the position list callback prevents the right execution and filling of the position list. (This is why subsequent orders cannot be closed after closing the first one).
I have completed half of the fix, but I think I will need to refactor the callback for positions.
I have found the problem.
When tag 35="AP" is received from the Broker, the parse_trade_message method searches in the binary data for the end of the FIX message, which in all cases is the checksum tag (tag 10)
match = re.search(rb"10=\d{3}\x01", self.tstream.peek(self.tstream.count()))However, the FIX message received contains various messages grouped into just one response, as shown in the following example:
b'8=FIX.4.4\x019=162\x0135=AP\x0134=2\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0155=10014\x01710=1\x01721=349730793\x01727=2\x01728=0\x01730=15347.9\x01702=1\x01704=1\x01705=0\x0110=218\x018=FIX.4.4\x019=162\x0135=AP\x0134=3\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0155=10014\x01710=1\x01721=349731225\x01727=2\x01728=0\x01730=15349.8\x01702=1\x01704=1\x01705=0\x0110=211\x018=FIX.4.4\x019=137\x0135=j\x0134=4\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0158=ORDER_NOT_FOUND:no orders found\x01379=1\x01380=0\x0110=078\x01'If we carefully look into the received response, we can split it into 3 FIX messages:
b'8=FIX.4.4\x019=162\x0135=AP\x0134=2\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0155=10014\x01710=1\x01721=349730793\x01727=2\x01728=0\x01730=15347.9\x01702=1\x01704=1\x01705=0\x0110=218
8=FIX.4.4\x019=162\x0135=AP\x0134=3\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0155=10014\x01710=1\x01721=349731225\x01727=2\x01728=0\x01730=15349.8\x01702=1\x01704=1\x01705=0\x0110=211
18=FIX.4.4\x019=137\x0135=j\x0134=4\x0149=CSERVER\x0150=TRADE\x0152=20230804-19:55:06.286\x0156=demo.icmarkets.0000000\x0157=TRADE\x0158=ORDER_NOT_FOUND:no orders found\x01379=1\x01380=0\x0110=078\x01'Unfortunately, the regex is matching just the first one, resulting in parsing only the first message and causing the position list to contain only ONE position. This is why we can't close the other orders. Furthermore, related to this problem, the position list callback prevents the right execution and filling of the position list. (This is why subsequent orders cannot be closed after closing the first one).
I have completed half of the fix, but I think I will need to refactor the callback for positions. Good evening, my friend. I apologize for the delay in responding. Lately, I've been extremely busy and haven't had the time to check. I'm hopeful that next week will be less hectic, and I'll definitely review this matter. I'll revisit the document to see if there have been any updates or if it's an initial project bug. Thank you for your cooperation. I intend to return promptly to focus on the projects at EJTrader.
Nice, work. How about an implementation of the same in rust, for latency's sake?
Nice, work. How about an implementation of the same in rust, for latency's sake?
I conducted some tests in Rust and observed no significant change in speed compared to Python. I believe Python is adequately serving our needs in this context.