darwinex / dwx-zeromq-connector

Wrapper library for algorithmic trading in Python 3, providing DMA/STP access to Darwinex liquidity via a ZeroMQ-enabled MetaTrader Bridge EA.
https://blog.darwinex.com/zeromq-interface-python-r-metatrader4/
BSD 3-Clause "New" or "Revised" License
344 stars 228 forks source link

[OO-SCOPE] Error 129: Invalid Price (MetaTrader 4) #3

Closed LungstaTheProgrammer closed 5 years ago

LungstaTheProgrammer commented 5 years ago

Good day

I don't mean to be a nuisance, I'm just following along with the video tutorial and I just run into issues as usual, when I'm programming. Usually I do my best to resolve these by myself. But this seems like it could be resolved quicker if i just ask.

I'm getting the following error when i try to place a trade using _price: '0.0' as per the instruction in the tut.. Can you please tell me why its saying im using an invalid price.

_Zmq._generate_default_order_dict() Out[15]: {'_action': 'OPEN', '_type': 0, '_symbol': 'EURUSD', '_price': 0.0, '_SL': 500, '_TP': 500, '_comment': 'DWX_Python_to_MT', '_lots': 0.01, '_magic': 123456, '_ticket': 0}

_Zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_response': '129', 'response_value': 'invalid price'}

integracore2 commented 5 years ago

Hi @LungstaTheProgrammer ,

Error 129 is a MetaTrader 4 error, which means that a trade is attempted to be executed at a price that is no longer valid.

See here for details on this and other error codes: https://book.mql4.com/appendix/errors

Are you using a Darwinex MetaTrader 4 Terminal?

Here is my output using the exact same code from here in the GitHub repo:

_zmq = DWX_ZeroMQ_Connector(_verbose=True)
[INIT] Ready to send commands to METATRADER (PUSH): 32768
[INIT] Listening for responses from METATRADER (PULL): 32769

_zmq._generate_default_order_dict()
Out[3]: 
{'_action': 'OPEN',
 '_type': 0,
 '_symbol': 'EURUSD',
 '_price': 0.0,
 '_SL': 500,
 '_TP': 500,
 '_comment': 'DWX_Python_to_MT',
 '_lots': 0.01,
 '_magic': 123456,
 '_ticket': 0}

_zmq._DWX_MTX_NEW_TRADE_()
{'_action': 'EXECUTION', '_magic': 123456, '_ticket': 87936880, '_open_time': '2019.04.09 14:10:21', 
'_open_price': 1.12784, '_sl': 500.0, '_tp': 500.0}
LungstaTheProgrammer commented 5 years ago

Oh ok

Uhm, no I am actually using FXCM MT4 platform.

No thank you, I will figure out a way to make it work then.

LungstaTheProgrammer commented 5 years ago

Good day

I actually downloaded the Darwinex MT4 and I'm still getting the error:

_zmq._generate_default_order_dict() Out[5]: {'_action': 'OPEN', '_type': 0, '_symbol': 'EURUSD', '_price': 0.0, '_SL': 500, '_TP': 500, '_comment': 'DWX_Python_to_MT', '_lots': 0.01, '_magic': 123456, '_ticket': 0}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_response': '129', 'response_value': 'invalid price'}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_response': '129', 'response_value': 'invalid price'}

But I am connected to my current broker's demo server so I don't know if that might be the problem.

LungstaTheProgrammer commented 5 years ago

I ended up modifying the code in the MQL part of the EA

MqlTick _trade_current_price;

if (_type == 0) {
//_price = _trade_open_price.ask; if(_symbol == "NULL") { double _trade_open_price = SymbolInfoDouble(Symbol(), SYMBOL_ASK); Comment("Order is buy: ", _trade_open_price); ticket = OrderSend(Symbol(), _type, _lots, _trade_open_price, MaximumSlippage, sl, tp, _comment, _magic); } else { double _trade_open_price = SymbolInfoDouble(_symbol, SYMBOL_ASK); Comment("Order is buy: ", _trade_open_price); ticket = OrderSend(_symbol, _type, _lots, _trade_open_price, MaximumSlippage, sl, tp, _comment, _magic); } } else if (_type == 1) {
//_price = _trade_open_price.bid; if(_symbol == "NULL") { double _trade_open_price = SymbolInfoDouble(Symbol(), SYMBOL_BID); Comment("Order is sell: ", _trade_open_price); ticket = OrderSend(Symbol(), _type, _lots, _trade_open_price, MaximumSlippage, sl, tp, _comment, _magic); } else { double _trade_open_price = SymbolInfoDouble(_symbol, SYMBOL_BID); Comment("Order is sell: ", _trade_open_price); ticket = OrderSend(_symbol, _type, _lots, _trade_open_price, MaximumSlippage, sl, tp, _comment, _magic); } } else { if(_symbol == "NULL") { ticket = OrderSend(Symbol(), _type, _lots, _price, MaximumSlippage, sl, tp, _comment, _magic); } else { ticket = OrderSend(_symbol, _type, _lots, _price, MaximumSlippage, sl, tp, _comment, _magic); } }

These are the results I get. Please note that when I tried it multiple times, before the mods, it didn't work at all:

C:\Users\Lungile Madi\Anaconda3\lib\site-packages\ipykernel\parentpoller.py:116: UserWarning: Parent poll failed. If the frontend dies, the kernel may be left running. Please let us know about your system (bitness, Python, etc.) at ipython-dev@scipy.org ipython-dev@scipy.org""")

runfile('C:/Users/Lungile Madi/Documents/project1/dwx-zeromq-connector-master/v2.0.1/python/api/DWX_ZeroMQ_Connector_v2_0_1_RC8.py', wdir='C:/Users/Lungile Madi/Documents/project1/dwx-zeromq-connector-master/v2.0.1/python/api')

_zmq = DWX_ZeroMQ_Connector() [INIT] Ready to send commands to METATRADER (PUSH): 32768 [INIT] Listening for responses from METATRADER (PULL): 32769

_zmq._DWX_MTX_GET_ALL_OPENTRADES() {'_action': 'OPEN_TRADES', '_trades': {}}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_magic': 123456, '_ticket': 155483640, '_open_time': '2019.04.11 17:02:45', '_open_price': 1.12704, '_sl': 500.0, '_tp': 500.0}

_zmq._DWX_MTX_CLOSE_TRADES_BYMAGIC(123456) {'_action': 'CLOSE_ALL_MAGIC', '_magic': 123456, '_responses': {155483640: {'_symbol': 'EURUSD', '_close_price': 1.12701, '_close_lots': 0.01, '_response': 'CLOSE_MARKET'}}, '_response_value': 'SUCCESS'}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_response': '129', 'response_value': 'invalid price'}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_response': '129', 'response_value': 'invalid price'}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_response': '136', 'response_value': 'off quotes'}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_magic': 123456, '_ticket': 155483856, '_open_time': '2019.04.11 17:06:26', '_open_price': 1.12688, '_sl': 500.0, '_tp': 500.0}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_response': '129', 'response_value': 'invalid price'}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_magic': 123456, '_ticket': 155483877, '_open_time': '2019.04.11 17:06:39', '_open_price': 1.12678, '_sl': 500.0, '_tp': 500.0}

_zmq._DWX_MTX_CLOSE_TRADES_BYMAGIC(123456) {'_action': 'CLOSE_ALL_MAGIC', '_magic': 123456, '_responses': {155483877: {'_symbol': 'EURUSD', '_close_price': 1.12675, '_close_lots': 0.01, '_response': 'CLOSE_MARKET'}, 155483856: {'_symbol': 'EURUSD', '_close_price': 1.12676, '_close_lots': 0.01, '_response': 'CLOSE_MARKET'}}, '_response_value': 'SUCCESS'}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_magic': 123456, '_ticket': 155483920, '_open_time': '2019.04.11 17:07:22', '_open_price': 1.12694, '_sl': 500.0, '_tp': 500.0}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_magic': 123456, '_ticket': 155483922, '_open_time': '2019.04.11 17:07:25', '_open_price': 1.12694, '_sl': 500.0, '_tp': 500.0}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_magic': 123456, '_ticket': 155483926, '_open_time': '2019.04.11 17:07:28', '_open_price': 1.12698, '_sl': 500.0, '_tp': 500.0}

_zmq._DWX_MTX_CLOSE_TRADES_BYMAGIC(123456) {'_action': 'CLOSE_ALL_MAGIC', '_magic': 123456, '_responses': {155483926: {'_symbol': 'EURUSD', '_close_price': 1.12685, '_close_lots': 0.01, '_response': 'CLOSE_MARKET'}, 155483922: {'_symbol': 'EURUSD', '_close_price': 1.12685, '_close_lots': 0.01, '_response': 'CLOSE_MARKET'}, 155483920: {'_symbol': 'EURUSD', '_close_price': 1.12685, '_close_lots': 0.01, '_response': 'CLOSE_MARKET'}}, '_response_value': 'SUCCESS'}

_zmq._DWX_MTX_NEWTRADE() {'_action': 'EXECUTION', '_response': '136', 'response_value': 'off quotes'}

LungstaTheProgrammer commented 5 years ago

I think it might be a problem with the broker. Because I know from experience with other parts of my software that my broker has bad software and I think they have an incompetent tech team, welll atleast that's my opinion.

So maybe add code for it to attempt to place the order multiple times and maybe report a 'failure to place order' error after a couple of automated attempts.

WildZes commented 4 years ago

Hi, @LungstaTheProgrammer, had the same problem. Didn't understand your solution, because don't know, what exact file or files you mean, when saying

I ended up modifying the code in the MQL part of the EA MqlTick _trade_current_price;

Tried to find, something like MqlTick in DWX_ZeroMQ_Server_v2.0.1_RC8.mq4, but useless. So decided to look for solution by myself. Found this link. It's about mql4 programming and algorithmic trading and it's in russian. There I found, that price can't be equal to 0.0. And in default _DWX_MTX_CLOSE_ALLTRADES function variable _price equal to 0.0. Elsemore I found this: if(type==OP_BUY) price=ASK: if(type==OP_SELL) price=BID, so I modified DWX_ZeroMQ_Server_v2.0.1_RC8.mq4 and repleced 295-297 lines of code with: if (StrToInteger (compArray[2]) == 0) { ticket = DWX_OpenOrder(compArray[3], StrToInteger(compArray[2]), StrToDouble(compArray[8]), Ask, StrToInteger(compArray[5]), StrToInteger(compArray[6]), compArray[7], StrToInteger(compArray[9]), zmq_ret); }

else if (StrToInteger (compArray[2]) == 1) { ticket = DWX_OpenOrder(compArray[3], StrToInteger(compArray[2]), StrToDouble(compArray[8]), Bid, StrToInteger(compArray[5]), StrToInteger(compArray[6]), compArray[7], StrToInteger(compArray[9]), zmq_ret); }

else { ticket = DWX_OpenOrder(compArray[3], StrToInteger(compArray[2]), StrToDouble(compArray[8]), StrToDouble(compArray[4]), StrToInteger(compArray[5]), StrToInteger(compArray[6]), compArray[7], StrToInteger(compArray[9]), zmq_ret); } Variable ticket form last else is equal to 295-297 lines of original code, but I think, that better to know error, than skip that else. So, for now everything is working for me.

tayyab123 commented 4 years ago

I ended up modifying the code in the MQL DWX_ZeroMQ_Server_v2.0.1_RC8.mq4

new order

if (_type == 0 && _price== 0.0) {
_price = SymbolInfoDouble(Symbol(), SYMBOL_ASK); Print("Order is buy: ", _price); } if (_type == 1 && _price== 0.0) { _price = SymbolInfoDouble(Symbol(), SYMBOL_BID); Print("Order is sell: ", _price);
}

bampi11 commented 3 years ago

I had the same problem as mentioned above, but I changed in mql4 in DWX_OpenOrder:

` int DWX_OpenOrder(string _symbol, int _type, double _lots, double _price, double _SL, double _TP, string _comment, int _magic, string &zmq_ret) {

int ticket, error;

zmq_ret = zmq_ret + "'_action': 'EXECUTION'";

if(_lots > MaximumLotSize) { zmq_ret = zmq_ret + ", " + "'_response': 'LOT_SIZE_ERROR', 'response_value': 'MAX_LOT_SIZE_EXCEEDED'"; return(-1); }

double sl = _SL; double tp = _TP;

// Else //if(DMA_MODE) { // sl = 0.0; // tp = 0.0; //}

if (_symbol == "NULL") { error = 4106; zmq_ret = zmq_ret + ", " + "'_response': '" + IntegerToString(error) + "', 'response_value': '" + ErrorDescription(error) + "'"; return(-1*error); } else { double vpoints = MarketInfo(_symbol, MODE_POINT); int vdigits = (int)MarketInfo(_symbol, MODE_DIGITS); double price_bid = MarketInfo(_symbol, MODE_BID); double price_ask = MarketInfo(_symbol, MODE_ASK);

  switch (_type)
  {
   case 0:
     sl = NormalizeDouble(price_bid-_SL*vpoints,vdigits);
     tp = NormalizeDouble(price_bid+_TP*vpoints,vdigits);
     Print("SL: ", sl);
     Print("TP: ", tp);
     ticket = OrderSend(_symbol, _type, _lots, price_ask, MaximumSlippage, sl, tp, _comment, _magic);
     break;
   case 1:
     sl = NormalizeDouble(price_ask+_SL*vpoints,vdigits);
     tp = NormalizeDouble(price_ask-_TP*vpoints,vdigits);
     ticket = OrderSend(_symbol, _type, _lots, price_bid, MaximumSlippage, sl, tp, _comment, _magic);
     break;
   case 2:
     sl = NormalizeDouble(_price-_SL*vpoints,vdigits);
     tp = NormalizeDouble(_price+_TP*vpoints,vdigits);
     ticket = OrderSend(_symbol, _type, _lots, _price, MaximumSlippage, sl, tp, _comment, _magic);
     break;
   case 3:
     sl = NormalizeDouble(_price+_SL*vpoints,vdigits);
     tp = NormalizeDouble(_price-_TP*vpoints,vdigits);
     ticket = OrderSend(_symbol, _type, _lots, _price, MaximumSlippage, sl, tp, _comment, _magic);
     break;
   case 4:
     sl = NormalizeDouble(_price-_SL*vpoints,vdigits);
     tp = NormalizeDouble(_price+_TP*vpoints,vdigits);
     ticket = OrderSend(_symbol, _type, _lots, _price, MaximumSlippage, sl, tp, _comment, _magic);
     break;
   case 5:
     sl = NormalizeDouble(_price+_SL*vpoints,vdigits);
     tp = NormalizeDouble(_price-_TP*vpoints,vdigits);
     ticket = OrderSend(_symbol, _type, _lots, _price, MaximumSlippage, sl, tp, _comment, _magic);
     break;
   default:   ticket = -1;
  } 

}

//if(_symbol == "NULL") { // ticket = OrderSend(Symbol(), _type, _lots, _price, MaximumSlippage, sl, tp, _comment, _magic); //} else { // ticket = OrderSend(_symbol, _type, _lots, _price, MaximumSlippage, sl, tp, _comment, _magic); //}

if(ticket < 0) { // Failure error = GetLastError(); zmq_ret = zmq_ret + ", " + "'_response': '" + IntegerToString(error) + "', 'response_value': '" + ErrorDescription(error) + "'"; return(-1*error); }

int tmpRet = OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES);

zmq_ret = zmq_ret + ", " + "'_magic': " + IntegerToString(_magic) + ", '_ticket': " + IntegerToString(OrderTicket()) + ", '_open_time': '" + TimeToStr(OrderOpenTime(),TIME_DATE|TIME_SECONDS) + "', '_open_price': " + DoubleToString(OrderOpenPrice());

if(DMA_MODE) {

  int retries = 3;
  while(true) {
     retries--;
     if(retries < 0) return(0);

     if((_SL == 0 && _TP == 0) || (OrderStopLoss() == _SL && OrderTakeProfit() == _TP)) {
        return(ticket);
     }

     if(DWX_IsTradeAllowed(30, zmq_ret) == 1) {
        if(DWX_SetSLTP(ticket, _SL, _TP, _magic, _type, _price, _symbol, retries, zmq_ret)) {
           return(ticket);
        }
        if(retries == 0) {
           zmq_ret = zmq_ret + ", '_response': 'ERROR_SETTING_SL_TP'";
           return(-11111);
        }
     }

     Sleep(MILLISECOND_TIMER);
  }

  zmq_ret = zmq_ret + ", '_response': 'ERROR_SETTING_SL_TP'";
  zmq_ret = zmq_ret + "}";
  return(-1);

}

// Send zmq_ret to Python Client
zmq_ret = zmq_ret + "}";

return(ticket); } `

The result: ` _zmq = DWX_ZeroMQ_Connector(_verbose=True) [INIT] Ready to send commands to METATRADER (PUSH): 32768 [INIT] Listening for responses from METATRADER (PULL): 32769 [INIT] Listening for market data from METATRADER (SUB): 32770

_trade_new = _zmq._generate_default_order_dict()

_zmq._DWX_MTX_NEWTRADE(_order=_trade_new) {'_action': 'EXECUTION', '_magic': 123456, '_ticket': 16084321, '_open_time': '2020.12.22 21:05:34', '_open_price': 1.2165, '_sl': 50.0, '_tp': 50.0}

_zmq._DWX_MTX_CLOSE_TRADES_BYMAGIC(123456) {'_action': 'CLOSE_ALL_MAGIC', '_magic': 123456, '_responses': {16084321: {'_symbol': 'EURUSD', '_close_price': 1.2162, '_close_lots': 0.1, '_response': 'CLOSE_MARKET'}}, '_response_value': 'SUCCESS'} `