I'm trying to modify an Order, but I always get Error #1.
From my research, I have discovered that error 1 means I have input parameter in a wrong way. How can I fix my OrderModify() function?
stoploss = NormalizeDouble(Ask - Point * TrailingStop,Digits);
int ticket;
takeprofit = NormalizeDouble(Ask + Point * TrailingStopTP,Digits);
double minstoplevel = MarketInfo( Symbol(), MODE_STOPLEVEL );
if(stoploss > NormalizeDouble(Ask - Point*minstoplevel,Digits)) {
stoploss = NormalizeDouble(Ask - Point*minstoplevel,Digits);
}
if(takeprofit < NormalizeDouble( Ask + Point*minstoplevel2, Digits )) {
takeprofit = NormalizeDouble( Ask + Point*minstoplevel2, Digits );
}
if(AccountFreeMarginCheck(Symbol(),OP_SELL,lotsize)>0) {
ticket=OrderSend(Symbol(),OP_BUY,lotsize,Ask, 0, 0.0, 0.0, "comment", MagicNumber, 0, Lime);
if(ticket<0) {
Print("Order send failed with error #",GetLastError());
} else {
Print("Order send sucesso!! Ticket#", ticket);
res=OrderModify(ticket,OrderOpenPrice(),stoploss,takeprofit,0,Blue);
if(res==false) {
Print("Error modifying order!, error#",GetLastError());
} else {
Print("Order modified successfully, res#", res);
}
}
} else {
Print("Sem dinheiro na conta D=");
}
}
Not exactly "wrong", OrderModify() legally sets _LastError == 1
There might be a bit surprise, but OrderModify() has an obligation to signal _LastError == 1 in case, the call was both syntactically and semantically correct, however, the values supplied for modification(s) were actually the very same, as the identified ticket# has already had in database.
This means, there was nothing to modify, as all the attributes already had the "quasi-new" target value(s).
One may pre-check all fields for a potential identity, which might allow our code to skip the OrderModify() call in this very case of an identity-of-{ current | target } values.
ERR_NO_RESULT == 1 // No error returned, but the result is unknown
GetLastError() - returns a last generated error-code. The same value is available via a system variable named _LastError. It's value can be reset before a critical activity to zero by calling ResetLastError().
Error codes are defined in stderror.mqh.
To print the error description you can use the ErrorDescription() function, defined in stdlib.mqh file
#include <stderror.mqh>
#include <stdlib.mqh>
The problem is that even though the entry price, stoploss, and take profit parameters to the OrderModify() call appear to be the same, they likely differ by a fraction of a unit ( smaller than "Digits" ).
To fix this,simply normalize the parameters to make sure they are a maximum of Digits decimal places long.
double entryPrice = NormalizeDouble( entryPrice, Digits );
double stoploss = NormalizeDouble( stoploss, Digits );
double target = NormalizeDouble( target, Digits );
Then pass them into the OrderModify() call.
Related
I am trying to get the output as below:
The problem is from URI-1098 Sequence IJ 4.
My Code is:
void main() {
double x = 0;
double y = 1;
for(double i = x; i<=2; i+= .2){
for(double j=y; j <= y + 2; j++){
if(i==0 || i==1 || i==2){
print('I=${i.toStringAsFixed(0)} J=${j.toStringAsFixed(0)}');
}else{
print('I=${i.toStringAsFixed(1)} J=${j.toStringAsFixed(1)}');
}
}
y += 0.2;
}
}
And my output is:
I=0 J=1
I=0 J=2
I=0 J=3
I=0.2 J=1.2
I=0.2 J=2.2
I=0.2 J=3.2
I=0.4 J=1.4
I=0.4 J=2.4
I=0.4 J=3.4
I=0.6 J=1.6
I=0.6 J=2.6
I=0.6 J=3.6
I=0.8 J=1.8
I=0.8 J=2.8
I=0.8 J=3.8
I=1 J=2
I=1 J=3
I=1 J=4
I=1.2 J=2.2
I=1.2 J=3.2
I=1.2 J=4.2
I=1.4 J=2.4
I=1.4 J=3.4
I=1.4 J=4.4
I=1.6 J=2.6
I=1.6 J=3.6
I=1.6 J=4.6
I=1.8 J=2.8
I=1.8 J=3.8
I=1.8 J=4.8
I=2.0 J=3.0
I=2.0 J=4.0
I=2.0 J=5.0
I am not getting desired outputs for the last 3 lines of the output. Can anyone kindly show the the error in my logic.
Thanking you all in advance.
You're using doubles.
That's the issue here. You are adding 0.2 repeatedly to a value starting at 0, but 0.2 is not precisely representable as a double. The 0.2 literal really represents the double value 0.200000000000000011102230246251565404236316680908203125 which is close to 0.2, but not exactly there.
The values you get by adding 0.2 to itself ten times loses some precision along the way. It hits 1.0 precisely, but then the next addition needs to drop some bits so the next value is actually below 1.2. The final result is 1.9999999999999997779553950749686919152736663818359375 which is not == 2.0, so your check for == 2.0 doesn't trigger. When you ask for the value with one decimal, it does round to "2.0", so you can't tell unless you print the actual value.
There are multiple ways to get around the problem.
One is to not use doubles. If you keep the numbers as integers by multiplying them by ten, then you just need a way to create the string to print. That could be
String toPrint(int value) {
var string = value.toString();
var lead = string.substring(0, string.length - 1);
if (string.endsWith('0')) return lead;
return "$lead.${string.substring(string.length - 1)}";
}
Alternatively, you can keep using doubles, but do .toStringAsFixed(1) and then check whether the last digit is zero. If it is, cut off the last two characters before printing.
I have an EA with closes a trade on button click
//void CloseCurrentTrade(). It's called after successfull OrderSelect
int orderType = OrderType();
double price;
if (orderType == OP_BUY)
price = return MarketInfo(OrderSymbol(), MODE_BID);
else if (orderType == OP_SELL)
price = return MarketInfo(OrderSymbol(), MODE_ASK);
else
return;
int slippage = 20;
bool closed = OrderClose(OrderTicket(), OrderLots(), price, slippage);
if (closed)
return;
int lastError = GetLastError();
Sometimes it closes the trade and sometimes it returns error #129 (Invalid price). I can't figure out why. Most of the cases people just misuse bid/ask or don't have enouth slippage. I've try to use slippage up to 200, still the same error. Some EA's just try to close it several times (and it looks like a hack for me), but it does not help as well. There are some mentions that you need to call RefreshRates() before bid/ask, but documentaion says that you don't need to do that for MarketInfo.
I've run out of ideas what it could be. Why it can happen and how to avoid that? I'm testing it on FXCM Demo (if it is the case).
First make sure that you've selected the order properly, and try to use OrderClosePrice where possible(this will eliminate the need for checking the OP_SELL/OP_BUY)
//+------------------------------------------------------------------+
//| Close the latest order for this current symbol |
//+------------------------------------------------------------------+
void CloseCurrentTrade()
{
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if(OrderSymbol()!=Symbol()) continue;
if(OrderMagicNumber()!=MagicNum) continue; // if there is no magic number set, then no need for this(manual orders)
if(OrderType()>OP_SELL) continue;
if(!OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage))
Print("Error in Closing the Order, Error : ",ErrorDescription(GetLastError()));
break; // assuming you want to close the latest trade only, exit the order closing loop
}
}
Also note that your broker might have restrictions on how far the closing price must be from the Order Opened price and other levels(sl/tp), in order to close an order. Refer here
Print and compare Ask/Bid && price when closed!=true. Beware that MarketInfo mode data is stored at Ask/Bid predefined variables already, so you can eliminate that if you OrderSelect in current symbol.
The problem is that when the i in the for loop reaches 15, I get an Array out of range error.
What I want to achieve is on every tick to check every Symbol in the MarketWatch and in each Symbol to check the current bar ( PERIOD_M5 ) and the previous one if there is a gap.
void OnTick()
{
int size = ArraySize( Symbols );
for( int i = 0; i < size; i++ )
{
int current_bar_index = iHighest( Symbols[i], PERIOD_M5, MODE_HIGH, 1, 0 );
int previous_bar_index = iHighest( Symbols[i], PERIOD_M5, MODE_HIGH, 1, 1 );
int current_bar_index_low = iLowest( Symbols[i], PERIOD_M5, MODE_LOW, 1, 0 );
int previous_bar_index_low = iLowest( Symbols[i], PERIOD_M5, MODE_LOW, 1, 1 );
double current_high = High[ current_bar_index];
double previous_high = High[previous_bar_index];
double current_low = Low[ current_bar_index_low];
double previous_low = Low[ previous_bar_index_low];
if ( current_low > ( previous_high + 0.00002 )
|| current_high < ( previous_low - 0.00002 )
)
{
Print( "There is a gap" );
}
}
}
Symbols[] is the array containing all the symbols. I loop through it and pass the current Symbol and get the index for the current bar and the previous one and then simply check if there is a gap.
The first problem is that passing every Symbol doesn't work. It gets only one and that's it. How can I achieve that and also, why I get an Array out of range error?
Let's start with the Array out of range error:
Given the MCVE was not present, let's assume, there is some fair declaration of the MQL4 code in the header or something like that.
So to diagnose this, add a trivial debug tool:
string SymbolsARRAY[] = { ..., // be carefull, some Brokers
..., // have quite strange names
...
};
for ( int cellPTR = 0;
cellPTR < ArraySize( SymbolsARRAY );
cellPTR++
)
PrintFormat( "%s[%d] = %s",
"SymbolsARRAY",
cellPTR,
SymbolsARRAY[cellPTR]
);
and post here the output.
Next, the GAP detection:
if you would not mind, checking a pair of M5-Bars for a GAP on each and every price QUOTE message arrival, is quite devastating the MQL4 computing resources. The GAP may principally appear only upon a new Bar starts ( and yet may disappear, during the Bar duration ).
Let's detect the initial GAP-condition ( it is similar to engulfing detection ):
if ( iLow( SymbolsARRAY[cellPTR], PERIOD_M5, 1 ) > iHigh( SymbolsARRAY[cellPTR], PERIOD_M5, 0 )
|| iHigh( SymbolsARRAY[cellPTR], PERIOD_M5, 1 ) < iLow( SymbolsARRAY[cellPTR], PERIOD_M5, 0 )
)
Print( "Initial GAP detected" );
Using this inside a detection of a new bar event may look like this:
void OnTick(){
// -----------------------------------------------------------------
// MINIMALISTIC CONTEXT-AWARE GAP DETECT/REMOVE
// -----------------------------------------------------------------
static bool aCurrentGAP = False;
static datetime aCurrentBAR = Time[0];
if ( aCurrentBAR != Time[0] ){
aCurrentBAR = Time[0];
// testInitGAP .........................present?
aCurrentGAP = testInitialGAP_onNewBarEVENT();
}
else {
if ( aCurrentGAP ){
// testInitGAP .....................disappeared?
aCurrentGAP = testInitialGAP_DISAPPEARED();
}
}
// -----------------------------------------------------------------
// MAIN COMPUTING & TRADING DUTIES OF EA-MQL4-CODE
// -----------------------------------------------------------------
...
}
about the error - when you receive it, it also can see the address of the code that generates it: number of line and symbol number in that line
about Symbol - as you may know, in MQL5 you can select all symbols from the market watch, in MQL4 such option is not available, as far as I remember, so I suspect your array of symbol names is empty or sth like that.
Could you show how you initialized that array? A correct way is the following one:
string Symbol[]={"EURUSD","AUDUSD","GBPUSD"};
also your code doesn't make any sense - when you select iHighest(*,*,*,i,j) - that means that EA-code checks i-elements, starting from j-th element ( 1, 0 ) means a current bar only, ( 1, 1 ) means to select just 1 bar, starting from bar 1, so still only 1 Bar is used.
For that it is much easier to have
double cur_high = iHigh( Symbol[i], 5, 0 ),
prev_high = iHigh( Symbol[i], 5, 1 );
I'm trying to insert a takeprofit and stoploss argument in my SendOrder() function, but I'm getting the following error:
Order Sent Failed with Error #130
This is my code:
extern double takeprofit = 30.0;
extern double stoploss = 20.0;
stoploss = NormalizeDouble( stoploss, 5 ); // SET stop loss
Print( "stoploss", stoploss );
takeprofit = NormalizeDouble( takeprofit, 5 ); // SET take profit
ticket = OrderSend( Symbol(),
OP_SELL,
lotsize,
Ask,
100,
stoploss,
takeprofit,
0,
0,
0,
CLR_NONE
);
if ( ticket < 0 ) {
Print( "Order send failed with error #", GetLastError() );
}
else Print( "Order send sucesso!!" );
I already checked documentation for the function NormalizeDouble(), but I'm still getting the error.
What should I do?
A ) Fully comply with the MQL4 OrderSend() syntax requirements
int anOrderTKT; // DECLARE int
double anOrderLotSIZE; // DECLARE double
string anOrderCommentSTRING; // DECLARE string
anOrderTKT = OrderSend( _Symbol, // CPU-glitch, is faster than calling Symbol(),
OP_SELL, // XTO.Type
anOrderLotSIZE, // XTO.Size [LT]s
Bid, // XTO.EntryPRICE { OP_BUY: Ask | OP_SELL: Bid }
100, // XTO.SLIPPAGE [PT]s
0, // XTO.SL_PRICE
0, // XTO.TP_PRICE,
anOrderCommentSTRING, // XTO.Comment
0, // XTO.MagNUM#
0, // XTO.PendingOrderEXPIRE
CLR_NONE // GUI.MarkerCOLOR
); // ==> { EMPTY | aTkt# }
Your code fails at setting a correct SHORT trade Entry-Price, as it shall read rather Bid, not Ask ( this error is hidden as it is effectively masked-out by a rather cosmic distance of 100 points in a tolerable slippage distance from the said price ).
Your code fails at assigning int ( 0 ) in place, where string is expected.
B) Error 130: == "invalid stops"
You shall verify with your Broker a few details:
Does their Terms & Conditions allow to OrderSend() one-stop-instruction, incl, TP & SL, or does the Broker T&C require to first open a trade-position & only after that happens to allow an OrderModify() instruction to setup TP & SL price-levels?
In either case, check your Broker T&C settings for STOPLEVEL & FREEZELEVEL distances, within which Broker rejects any TP & SL setup(s) or modification(s) thereof.
C) A good practice is not to assign into extern iterator-variables
While this is not a root-cause for your trouble, do get accustomed with an industry best practices, one of which is not to assign any value to a declared extern. Rather declare your own variable, that you control scope & assignments thereof, but leave extern(s) un-touched from your code side.
can anyone help me, how to write MQL4 code to know if the result is increase OR decrease..
Example:
if a result was first 0.0543 and then it is increased to 0.1342 and later decreased to 0.10345, I want to implement it to my code below:
int start()
{
double val = iCustom( NULL, 0, "SS2009_B", 0, 0, 0 );
ObjectSet( "TimeLable11", OBJPROP_CORNER, obCorner );
ObjectSetText( "TimeLable11", "Result : " + val,
fsize,
"Microsoft Sans Serif",
Yellow
);
return( 0 );
}
I want the result to have an increasing OR a decreasing notification.
Example :
Result : 0.1849 Increasing
Result : 0.01324 Decreasing
To have a SIMPLE example:
//------------------------------------------------------------------
#property copyright "Copyright 2015"
//------------------------------------------------------------------
// Standard Variables (define a variable to store previous value)
//------------------------------------------------------------------
double viIndicatorValuePrev = 0.0000;
int start() {
double viIndicatorValueNow = iCustom(NULL,0,"SS2009_B",0,0,0);
//------------------------------------------------
//Decide on direction (increasing or decreasing)
//------------------------------------------------
string vsDirection = "Same";
if( viIndicatorValueNow>viIndicatorValuePrev)
vsDirection = "Increasing";
if( viIndicatorValueNow<viIndicatorValuePrev)
vsDirection = "Decreasing";
//------------------------------------------------
//------------------------------------------------
// Do your thing here (ie, display stuff)
//------------------------------------------------
ObjectSet( "TimeLable11", OBJPROP_CORNER, obCorner);
ObjectSetText(
"TimeLable11"
, "Result : " + viIndicatorValueNow + " (" + vsDirection + ")"
, fsize, "Microsoft Sans Serif", Yellow
);
//------------------------------------------------
// Store current value for future comparison
//------------------------------------------------
viIndicatorValuePrev = viIndicatorValueNow;
//------------------------------------------------
return(0);
}
Hope this example helps.
Solution to monitor & show delta per each aMarketEVENT call of start() ( upon aMarketQUOTE aka Tick arrival )
First you need a method to store and retain a value, that becomes "old", in the meantime, before the start() ( well actually an OnTick() in the new-MQL century ) is called next time.
A static double is a smart way to go:
static double previousVALUE = EMPTY; // initialised to EMPTY
Next, initialise it in accord with a forward-stepping logic of the Custom Indicator "SS2009_B"
if ( previousVALUE == EMPTY ) {
previousVALUE = iCustom( NULL, // a Symbol
0, // a TimeFRAME
"SS2009_B",
0,
0, // a Buffer# to get value from
1 // step-back one Bar
);
}
For syntax details, review MQL4 documentation
double iCustom(
string symbol, // symbol
int timeframe, // timeframe
string name, // path/name of the custom indicator compiled program
... // custom indicator input parameterA (if
... // custom indicator input parameterB (if
... // custom indicator input parameterC (if necessary)
int mode, // line index
int shift // shift
);
Finally calculate delta & show it on UI & shuffle to get ready for a next call
double currentVALUE = iCustom( NULL, 0, "SS2009_B", 0, 0, 0);
double deltaVALUE = previousVALUE - currentVALUE;
previousVALUE = currentVALUE; // shuffle [1]<-[0] before RET/next call
if ( deltaVALUE > 0 ){
ObjectSetText( "TimeLabel11",
"RESULT: " + NormalizeDouble( deltaVALUE, Digits ) + "|^|",
fsize,
"Courier New",
Yellow // can be deltaVALUE specific too :o)
);
}
if ( deltaVALUE < 0 ){
ObjectSetText( "TimeLabel11",
"RESULT: " + NormalizeDouble( deltaVALUE, Digits ) + "|v|",
fsize,
"Courier New",
Cyan // can be deltaVALUE specific too :o)
);
}
A few remarks on precision of float numbers
You may notice a use of NormalizeDouble()
This is rather important step, to avoid problems with comparison of floats.
If the precision of standard floats ( MQL4 double ) is not sufficient, you may opt-in to use extended precision numbers in MQL4. Check documentation for that.
However, always be carefull on float comparisons.
Best practice, to be on a safer side, is to use both NormalizeDouble() ( as a prevention )
and
comparing to some thresholdDELTA like if ( MathAbs( floatA - floatB ) < anEqualityTresholdDELTA ){ ... } rather than if ( floatA == floatB ) {...}