MQL4 OrderSend Failed Error 130 - why even with no SL?
MQL4 OrderSend Failed Error 130 - why even with no SL?
Loading saved threads...
ah1917 · External communityPost link
External question — Stack Overflow Stack Exchange
Author: ah1917
Original post: https://stackoverflow.com/questions/79565306
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
I'm trying to create a simple EA tool in MT4 so that I can drag and drop two lines on the chart, and based on input parameters it calculates lot size, and then when I press execute, it enters a limit order with the entry price and stop loss price.
As you can see I'm consistently getting the error 130 which suggests from MQL4 documentation that the SL is incorrect in someway. This makes no sense as I've logged the brokers rules and they expect 0.0 SL? I've also checked and tested the limit order being a multitude of distances away from current price and still no help.
I've tested several different ways, and have logged several different things in an attempt to narrow down the issue. I thought maybe it was a decimal issue but I see it is sending the correct .xx price based on the broker and market (US100.cash) I'm trying to trade.
#property strict
#property indicator_chart_window
input double RiskPerTradeUSD = 100.0; // Amount to risk per trade in USD
input int Slippage = 3;
string entryLine = "ENTRY_LINE";
string stopLine = "STOP_LINE";
string executeButton = "EXECUTE_TRADE";
bool tradeExecuted = false;
//+------------------------------------------------------------------+
int OnInit()
{
int mSLS = (int)MarketInfo(Symbol(), MODE_STOPLEVEL);
Print("[BROKER] Minimum StopLevel (points): ", mSLS);
CreateLines();
CreateExecuteButton();
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
ObjectDelete(entryLine);
ObjectDelete(stopLine);
ObjectDelete(executeButton);
Comment("");
}
void OnTick()
{
if (tradeExecuted) return;
double entry = ObjectGet(entryLine, OBJPROP_PRICE1);
double stop = ObjectGet(stopLine, OBJPROP_PRICE1);
double pointRisk = MathAbs(entry - stop);
double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
if (pointRisk == 0 || tickValue == 0) return;
double rawLot = (RiskPerTradeUSD / pointRisk) / (tickValue * 100);
double lotSize = NormalizeDouble(MathFloor(rawLot / lotStep) * lotStep, 2);
Comment("Entry: ", DoubleToString(entry, 2),
"\nStop: ", DoubleToString(stop, 2),
"\nLot Size: ", DoubleToString(lotSize, 2),
"\nRisk (USD): ", RiskPerTradeUSD);
}
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
if (id == CHARTEVENT_OBJECT_CLICK && sparam == executeButton)
{
Print("[EXECUTE] Button clicked");
double entry = ObjectGet(entryLine, OBJPROP_PRICE1);
double stop = ObjectGet(stopLine, OBJPROP_PRICE1);
double pointRisk = MathAbs(entry - stop);
double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
if (pointRisk == 0 || tickValue == 0) return;
double rawLot = (RiskPerTradeUSD / pointRisk) / (tickValue * 100);
double lotSize = NormalizeDouble(MathFloor(rawLot / lotStep) * lotStep, 2);
int type = (entry > stop) ? OP_SELLLIMIT : OP_BUYLIMIT;
int digits = (int)MarketInfo(Symbol(), MODE_DIGITS);
double price = NormalizeDouble(entry, digits);
double sl = NormalizeDouble(stop, digits);
Print("[CALC] Entry=", DoubleToString(entry, 2), ", Stop=", DoubleToString(stop, 2), ", PointRisk=", DoubleToString(pointRisk, 2));
Print("[CALC] TickValue=", tickValue, ", RawLot=", rawLot, ", FinalLot=", lotSize, ", RiskPerTradeUSD=", RiskPerTradeUSD);
Print("[ORDER] Sending Limit Order: Symbol=", Symbol(), ", Type=", type, ", Lot=", lotSize, ", Price=", DoubleToString(price, digits), ", SL=", DoubleToString(sl, digits));
int stopLevelPoints = (int)MarketInfo(Symbol(), MODE_STOPLEVEL);
double stopLevelPriceDistance = stopLevelPoints * Point;
double currentPrice = (type == OP_BUYLIMIT) ? Ask : Bid;
double priceDiff = MathAbs(price - currentPrice);
if (priceDiff < stopLevelPriceDistance)
{
Print("[WARNING] Entry price too close to market. Required distance: ", DoubleToString(stopLevelPriceDistance, digits));
Print("[FIX] Adjusting price to be valid by broker rules...");
price = (type == OP_BUYLIMIT) ? currentPrice + stopLevelPriceDistance : currentPrice - stopLevelPriceDistance;
price = NormalizeDouble(price, digits);
}
Print("[BROKER] StopLevel (points): ", stopLevelPoints);
Print("[BROKER] CurrentPrice=", DoubleToString(currentPrice, digits), ", EntryPrice=", DoubleToString(price, digits), ", Distance=", DoubleToString(priceDiff, digits), ", Required Min=", DoubleToString(stopLevelPriceDistance, digits));
int ticket = OrderSend(Symbol(), type, lotSize, price, Slippage, 0, 0, "DragDropTrade", 0, 0, clrGreen);
if (ticket > 0) {
Print("Trade placed successfully! Ticket = ", ticket);
// Attempt to modify order after placement (ECN-safe SL attachment)
bool modified = OrderModify(ticket, price, sl, 0, 0, clrRed);
if (!modified)
Print("OrderModify failed! Error = ", GetLastError());
else
Print("Stop loss added post-order with OrderModify().");
}
if (ticket < 0)
Print("OrderSend failed! Error = ", GetLastError());
tradeExecuted = true;
}
}
void CreateLines()
{
double price = SymbolInfoDouble(Symbol(), SYMBOL_ASK);
ObjectCreate(entryLine, OBJ_HLINE, 0, 0, price);
ObjectSetInteger(0, entryLine, OBJPROP_COLOR, clrDeepSkyBlue);
ObjectSetInteger(0, entryLine, OBJPROP_STYLE, STYLE_SOLID);
ObjectSetInteger(0, entryLine, OBJPROP_WIDTH, 2);
ObjectSetInteger(0, entryLine, OBJPROP_SELECTABLE, true);
ObjectSetInteger(0, entryLine, OBJPROP_SELECTED, true);
ObjectCreate(stopLine, OBJ_HLINE, 0, 0, price - 50 * Point);
ObjectSetInteger(0, stopLine, OBJPROP_COLOR, clrRed);
ObjectSetInteger(0, stopLine, OBJPROP_STYLE, STYLE_DASH);
ObjectSetInteger(0, stopLine, OBJPROP_WIDTH, 2);
ObjectSetInteger(0, stopLine, OBJPROP_SELECTABLE, true);
ObjectSetInteger(0, stopLine, OBJPROP_SELECTED, true);
}
void CreateExecuteButton()
{
ObjectCreate(0, executeButton, OBJ_BUTTON, 0, 0, 0);
ObjectSetInteger(0, executeButton, OBJPROP_CORNER, CORNER_LEFT_LOWER);
ObjectSetInteger(0, executeButton, OBJPROP_XDISTANCE, 20);
ObjectSetInteger(0, executeButton, OBJPROP_YDISTANCE, 40);
ObjectSetInteger(0, executeButton, OBJPROP_XSIZE, 100);
ObjectSetInteger(0, executeButton, OBJPROP_YSIZE, 24);
ObjectSetString(0, executeButton, OBJPROP_TEXT, "EXECUTE");
ObjectSetString(0, executeButton, OBJPROP_FONT, "Arial");
ObjectSetInteger(0, executeButton, OBJPROP_FONTSIZE, 12);
ObjectSetInteger(0, executeButton, OBJPROP_COLOR, clrWhite);
ObjectSetInteger(0, executeButton, OBJPROP_BGCOLOR, clrGreen);
ObjectSetInteger(0, executeButton, OBJPROP_BORDER_COLOR, clrBlack);
ObjectSetInteger(0, executeButton, OBJPROP_BACK, false);
ObjectSetInteger(0, executeButton, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, executeButton, OBJPROP_SELECTED, false);
ObjectSetInteger(0, executeButton, OBJPROP_HIDDEN, false);
ObjectSetInteger(0, executeButton, OBJPROP_ZORDER, 0);
}
Below are my most recent logged errors.
2025.04.09 21:40:22.924 EntryTool US100.cash,M1: OrderSend failed! Error = 130
2025.04.09 21:40:22.924 EntryTool US100.cash,M1: [BROKER] CurrentPrice=19162.51, EntryPrice=19209.67, Distance=47.16, Required Min=0.00
2025.04.09 21:40:22.924 EntryTool US100.cash,M1: [BROKER] StopLevel (points): 0
2025.04.09 21:40:22.924 EntryTool US100.cash,M1: [ORDER] Sending Limit Order: Symbol=US100.cash, Type=2, Lot=1.53, Price=19209.67, SL=19274.91
2025.04.09 21:40:22.924 EntryTool US100.cash,M1: [CALC] TickValue=0.01, RawLot=1.532652758926088, FinalLot=1.53, RiskPerTradeUSD=100.0
2025.04.09 21:40:22.924 EntryTool US100.cash,M1: [CALC] Entry=19209.67, Stop=19274.91, PointRisk=65.25
2025.04.09 21:40:22.924 EntryTool US100.cash,M1: [EXECUTE] Button clicked
Quote
Report
Forex Coder · External communityPost link
External answer — Stack Overflow Stack Exchange
Author: Forex Coder
Original post: https://stackoverflow.com/a/79645871
License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/
Adaptation: HTML converted to plain text; contact email addresses removed.
maybe add this for checking the stop level points
int stopLevelPoints = (int)MarketInfo(Symbol(), MODE_STOPLEVEL);
if(stopLevelPoints==0){
stopLevelPoints=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
}
Quote
Report
Post Reply
Quoted from Forex.com.bd-Editorial External answer — Stack Overflow Stack Exchange Author: Forex Coder Source score (net votes, not local likes): 0 Original post: https://stackoverflow.com/a/79645871 License: CC BY-SA 4.0 — https://creativecommons.org/licenses/by-sa/4.0/ Adaptation: HTML converted to plain text; contact email addresses removed. maybe add this for checking the stop level points int stopLevelPoints = (int)MarketInfo(Symbol(), MODE_STOPLEVEL); if(stopLevelPoints==0){ stopLevelPoints=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL); }
Checking account access…