ejtraderLabs / ejtraderCT

The best Python Ctrader FIX API Perfect for HFT
MIT License
59 stars 20 forks source link

Issue while creating market order with limit(take profit) and stoploss #8

Closed monsterlady closed 1 year ago

monsterlady commented 1 year ago
import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "78.129.190.32"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8673704"
PASSWORD = "XXBP6072"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)
symbol = "EURUSD"
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)
takeprofit = quote['ask'] + limits * 0.0001
api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=takeprofit)

The order can be created, but without takeprofit... Did I do something wrong? Thanks for your effort and looking forward to hearing from you:)

traderpedroso commented 1 year ago
import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "78.129.190.32"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8673704"
PASSWORD = "XXBP6072"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)
symbol = "EURUSD"
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)
takeprofit = quote['ask'] + limits * 0.0001
api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=takeprofit)

The order can be created, but without takeprofit... Did I do something wrong? Thanks for your effort and looking forward to hearing from you:)

The stop loss and take profit are not showing on the chart it's a ctrader fix limitation, but you can test with short TP AND SL

monsterlady commented 1 year ago
import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "78.129.190.32"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8673704"
PASSWORD = "XXBP6072"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)
symbol = "EURUSD"
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)
takeprofit = quote['ask'] + limits * 0.0001
api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=takeprofit)

The order can be created, but without takeprofit... Did I do something wrong? Thanks for your effort and looking forward to hearing from you:)

The stop loss and take profit are not showing on the chart it's a ctrader fix limitation, but you can test with short TP AND SL

Hey, Thanks for you swift response! Could you give a short example of short TP and SL? I don't get you meaning

traderpedroso commented 1 year ago

Hey, Thanks for you swift response! Could you give a short example of short TP and SL? I don't get you meaning

You are doing it correctly, what I meant is that cTrader doesn't display the executed stop loss or take profit through the FIX API, so they are active. That's why I suggested testing with a short stop loss and a short take profit.

monsterlady commented 1 year ago

Hey, Thanks for you swift response! Could you give a short example of short TP and SL? I don't get you meaning

You are doing it correctly, what I meant is that cTrader doesn't display the executed stop loss or take profit through the FIX API, so they are active. That's why I suggested testing with a short stop loss and a short take profit.

Sorry for my poor programming knowledge, for now I set the TP as 5 pips, and I expected that in cTrader displaying the TP, but now, the TP seems not set at all. Here's the Screenshot image As you can see, the position is not closed, and there's no TP. How am I supposed to do to set TP correctly? I think 5 pips is short enough...

traderpedroso commented 1 year ago

Hey, Thanks for you swift response! Could you give a short example of short TP and SL? I don't get you meaning

You are doing it correctly, what I meant is that cTrader doesn't display the executed stop loss or take profit through the FIX API, so they are active. That's why I suggested testing with a short stop loss and a short take profit.

Sorry for my poor programming knowledge, for now I set the TP as 5 pips, and I expected that in cTrader displaying the TP, but now, the TP seems not set at all. Here's the Screenshot image As you can see, the position is not closed, and there's no TP. How am I supposed to do to set TP correctly? I think 5 pips is short enough...

I'm not sure because it's been a long time since I used the API, whether the difference is between hedge accounts and netting accounts. Ill check and let you know you! you need to setup TP and SL both check your code where

takeprofit = quote['ask'] + limits * 0.0001
stoplosst = quote['ask'] - limits * 0.0001
print(takeprofit)
print(type(takeprofit) 

needs to be float type

traderpedroso commented 1 year ago

you can try to modify position

import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "78.129.190.32"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8673704"
PASSWORD = "XXBP6072"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)
symbol = "EURUSD"
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)

api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=None)

time.sleep(1)
positions = api.positions()
for position in positions:
     takeprofit = quote['ask'] + limits * 0.0001
     stoploss = quote['bid'] - limits * 0.0001
     id = position['pos_id']
     api.positionModify(id, stoploss, takeprofit)
monsterlady commented 1 year ago

you can try to modify position

import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "78.129.190.32"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8673704"
PASSWORD = "XXBP6072"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)
symbol = "EURUSD"
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)

api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=None)

time.sleep(1)
positions = api.positions()
for position in positions:
     takeprofit = quote['ask'] + limits * 0.0001
     stoploss = quote['ask'] - limits * 0.0001
     id = position['pos_id']
     stoploss = "stop loss price""
     takeprofit "stop gain price"
     api.positionModify(id, stoploss, takeprofit)

error occurred while call positionModify, here's the log:


INFO:root:Trade logged on - client_id 1
INFO:root:Quote logged on - client_id 1
ERROR:root:ORDER_NOT_FOUND:no orders found
INFO:root:Action: OPEN, Symbol: EURUSD, Lots: 10, Ticket: 1680020648345662199070
INFO:root:Command: buy EURUSD 1000000 1680020648345662199070 - client_id: 1
{'time': 1680020647967, 'bid': 1.08412, 'ask': 1.08413}
8=FIX.4.4|9=176|35=D|49=demo.icmarkets.8673704|50=TRADE|56=CSERVER|57=TRADE|34=5|52=20230328-16:24:08|11=1680020648345662199070|55=1|54=1|60=20230328-16:24:08|38=1000000.0|40=1|494=test label|10=155|
ERROR:root:ORDER_NOT_FOUND:no orders found
INFO:root:Action: MODIFY, Symbol: , Lots: 0, Ticket: 326586128
Traceback (most recent call last):
File "F:\Python_projects\ig\main.py", line 32, in <module>
api.positionModify(id, stoploss, takeprofit)
File "E:\Anaconda\content\envs\ig\lib\site-packages\ejtraderCT\api\ctrader.py", line 186, in positionModify
return self.trade("", "MODIFY", 0, "", 0, stoploss, takeprofit, 0, 5, id)
File "E:\Anaconda\content\envs\ig\lib\site-packages\ejtraderCT\api\ctrader.py", line 82, in trade
ticket = self.getPositionIdByOriginId(v_ticket, client_id)
TypeError: getPositionIdByOriginId() takes 2 positional arguments but 3 were given
traderpedroso commented 1 year ago

I'll set up the API in my environment here and will get back to you with a response soon.

monsterlady commented 1 year ago

I'll set up the API in my environment here and will get back to you with a response soon.

Appreciate!!!

traderpedroso commented 1 year ago

I'll set up the API in my environment here and will get back to you with a response soon.

Appreciate!!!

The use of SL (Stop Loss) and TP (Take Profit) is only possible in netting accounts. For instance, if you buy one lot, you need to sell one to exit the trade, but this is not supported in hedge accounts. You can test this by following my instructions.

import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "78.129.190.32"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8673704"
PASSWORD = "XXBP6072"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)
symbol = "EURUSD"
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)

id = api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=None)

takeprofit = quote['ask'] + limits * 0.0001
stoploss = quote['ask'] - limits * 0.0001
id = position['pos_id']
api.positionModify(id, stoploss, takeprofit)
monsterlady commented 1 year ago

I'll set up the API in my environment here and will get back to you with a response soon.

Appreciate!!!

The use of SL (Stop Loss) and TP (Take Profit) is only possible in netting accounts. For instance, if you buy one lot, you need to sell one to exit the trade, but this is not supported in hedge accounts. You can test this by following my instructions.

import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "78.129.190.32"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8673704"
PASSWORD = "XXBP6072"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)
symbol = "EURUSD"
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)

id = api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=None)

takeprofit = quote['ask'] + limits * 0.0001
stoploss = quote['ask'] - limits * 0.0001
id = position['pos_id']
api.positionModify(id, stoploss, takeprofit)

You are right, I checked my account type in cTrader, turned out my demo account type is hedging, that might be the reason. I've sent an email to request the support team to change the type to netting, and I'll get back to you after testing the netting account with the same code. Again, thanks for your help :)

monsterlady commented 1 year ago

I'll set up the API in my environment here and will get back to you with a response soon.

Appreciate!!!

The use of SL (Stop Loss) and TP (Take Profit) is only possible in netting accounts. For instance, if you buy one lot, you need to sell one to exit the trade, but this is not supported in hedge accounts. You can test this by following my instructions.

import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "78.129.190.32"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8673704"
PASSWORD = "XXBP6072"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)
symbol = "EURUSD"
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)

id = api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=None)

takeprofit = quote['ask'] + limits * 0.0001
stoploss = quote['ask'] - limits * 0.0001
id = position['pos_id']
api.positionModify(id, stoploss, takeprofit)
import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "176.58.118.184"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8680256"
PASSWORD = "********"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)
symbol = "EURUSD"
volume = 10  # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)
takeprofit = quote['ask'] + limits * 0.0001
stoploss = quote['ask'] - limits * 0.0001
id = api.buy(symbol, volume, stoploss, takeprofit)
print(id)

Well even with netting account, still can not open positions with TP/SL

traderpedroso commented 1 year ago

Sorry, just update the code now it's now on 1.0.7, de ID come from id = api.buy of course

pip install ejtraderCT -U

import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "78.129.190.32"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8673704"
PASSWORD = "XXBP6072"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)

symbol = "EURUSD"
time.sleep(3)
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)

id = api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=None)

takeprofit = quote['ask'] + limits * 0.0001
stoploss = quote['ask'] - limits * 0.0001
api.positionModify(id, stoploss, takeprofit)
monsterlady commented 1 year ago

SERVER = "176.58.118.184" # Host name BROKER = "demo.icmarkets" LOGIN = "8680256" PASSWORD = "*****" CURRENCY = "EUR"

Still not work for me,

import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "176.58.118.184"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8680256"
PASSWORD = "********"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)

symbol = "EURUSD"
# time.sleep(3)
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)

id = api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=None)
print(id)
takeprofit = quote['ask'] + limits * 0.0001
print(takeprofit)
order_id = api.sellLimit(symbol, volume, None, None, price=takeprofit)
print(order_id)

so now my solution is to open a long postion and then open a sellLimit order to be the TP. After reading the source code, I don't think the method positionModify() could add TP/SL to existing open position, as it seems like just cancelling the existed positions and place a new one instead

traderpedroso commented 1 year ago

SERVER = "176.58.118.184" # Host name BROKER = "demo.icmarkets" LOGIN = "8680256" PASSWORD = "RPXO6342" CURRENCY = "EUR"

Still not work for me,

import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "176.58.118.184"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8680256"
PASSWORD = "RPXO6342"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)

symbol = "EURUSD"
# time.sleep(3)
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)

id = api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=None)
print(id)
takeprofit = quote['ask'] + limits * 0.0001
print(takeprofit)
order_id = api.sellLimit(symbol, volume, None, None, price=takeprofit)
print(order_id)

so now my solution is to open a long postion and then open a sellLimit order to be the TP. After reading the source code, I don't think the method positionModify() could add TP/SL to existing open position, as it seems like just cancelling the existed positions and place a new one instead

Actually, the FIX API was developed for high-frequency trading, so algorithms open and close orders manually, controlling profit and loss. positionModify() works, and you can even test it on pending orders, but the FIX API certainly has several limitations. This library was made to provide stable and easy trading without the need to run multiple applications, but if you want something more complete, you can use ejtraderMT for Metatrader 5 in microseconds action.

traderpedroso commented 1 year ago

SERVER = "176.58.118.184" # Host name BROKER = "demo.icmarkets" LOGIN = "8680256" PASSWORD = "*****" CURRENCY = "EUR"

Still not work for me,

import logging
import time

from ejtraderCT import Ctrader

logging.getLogger().setLevel(logging.INFO)

SERVER = "176.58.118.184"  # Host name
BROKER = "demo.icmarkets"
LOGIN = "8680256"
PASSWORD = "********"
CURRENCY = "EUR"

api = Ctrader(server=SERVER, broker=BROKER, login=LOGIN, password=PASSWORD, currency=CURRENCY)

symbol = "EURUSD"
# time.sleep(3)
volume = 10 # position size
limits = 5
api.subscribe(symbol)
time.sleep(3)
# Buy position
quote = api.quote(symbol)
print(quote)

id = api.buy(symbol=symbol, volume= volume, stoploss=None, takeprofit=None)
print(id)
takeprofit = quote['ask'] + limits * 0.0001
print(takeprofit)
order_id = api.sellLimit(symbol, volume, None, None, price=takeprofit)
print(order_id)

so now my solution is to open a long postion and then open a sellLimit order to be the TP. After reading the source code, I don't think the method positionModify() could add TP/SL to existing open position, as it seems like just cancelling the existed positions and place a new one instead

take profit and stoploss add from 1.1.13 check the readme