How to calculate indicator buffer only once per day mql4 - mql4

I have an indicator which gives one signal [Down Buffer]... I wish to only give signal once per day... Like after the first signal it will not paint any signal for the rest of the day! I have tested with below code it's now not painting at all?
//--- indicator buffers
double Buffer1[];
int day = 0;
int OnInit()
{
........................
}
int OnCalculate(......)
{
//--- main loop
for(int i = limit-1; i >= 0; i--)
{
//Indicator Buffer 1
if( here goes my condition )
{
if( day != Day() )
{
Buffer1[i] = High[i] + iATR(NULL, PERIOD_CURRENT, 14, i); //Set indicator value at Candlestick High + Average True Range
day = Day();
}
}
else
{
Buffer1[i] = EMPTY_VALUE;
}
}
return(rates_total);
}
What is wrong with my code? It's now not showing any signal at all...
Note : I have removed some of the code to make it simple...

Use the following function to check whether it is a new day.
It returns true if it is a new day, else returns false.
bool IsNewDay(){
static datetime prevDay = -1;
if( iTime(_Symbol, PERIOD_D1, 0) == prevDay ) return false;
prevDay = iTime(_Symbol, PERIOD_D1, 0);
return true;
}

Related

How to check particular bit in dart?

How do you know if a particular bit is set in dart?
example how to do this?
int value = 5;
if(checkBit(value, 4)) {
print("position: 4 TRUE");
} else {
print("position: 4 FALSE");
}
The solution is the same as #MihaiBC points to but since that is in C#, I am still going to post this just so we also have a Dart example:
void main() {
const value = 5;
print(value.toRadixString(2).padLeft(64, '0'));
// 0000000000000000000000000000000000000000000000000000000000000101
print(checkBit(value, 0)); // true
print(checkBit(value, 1)); // false
print(checkBit(value, 2)); // true
print(checkBit(value, 3)); // false
}
bool checkBit(int value, int bit) => (value & (1 << bit)) != 0;

EA Opens more orders than expected in MQL4

Everything seems fine. But EA usually opens multiple trades in the same second... The way I built it is very linear and i can't seem to spot the logical mistake. It is basically a random martingale EA to test stuff out. Any indicator (that's why I called it random, haven't decided myself) can be put in there.
Basic idea is that it has an upper and lower threshold which determines when it is in buy zone and when at sell zone. Once it is in either zone, if trend goes against it (determined by indicator's value, not symbol's price) it opens another trade with the same SL/TP of the initial order. Also it checks whether initial trade still runs so it does not open other ones and once the initial trade is open. After that the criterias about the rest of the trades (that go against the trade are different).
The problem is that it opens multiple trades at times that it shouldn't, or like 3-4 trades within the same second or two. Any idea why this happens?
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
input int stepValue = 5;
input double lotsize = 0.01;
input int stoploss = 2000;
input int takeprofit = 140;
input int slippage = 10;
input double upper_border = 60.0;
input double lower_border = 40.0;
const string EAComment = "Xind";
string mode = "";
bool first_trade = false;
int InitTicket = 1;
double X = 0.0;
double X_Last = 0.0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
first_trade = false;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
SearchSignal();
if (mode == "Buy")
{
if (first_trade == false)
{
Buy();
}
if (first_trade == true)
{
MartinCheck();
CloseCheck();
}
}
if (mode == "Sell")
{
if (first_trade == false)
{
Sell();
}
if (first_trade == true)
{
MartinCheck();
CloseCheck();
}
}
}
//+------------------------------------------------------------------+
void Buy()
{
X_Last = X;
first_trade = true;
InitTicket = OrderSend(NULL,OP_BUY,lotsize,Ask,slippage,Ask-stoploss*Point,Ask+takeprofit*Point,EAComment,1,0,clrDarkBlue);
}
//---
void Sell()
{
X_Last = X;
first_trade = true;
InitTicket = OrderSend(NULL,OP_SELL,lotsize,Bid,slippage,Bid+stoploss*Point,Bid-takeprofit*Point,EAComment,1,0,clrDarkRed);
}
//---
void MartinBuy()
{
if (OrderSelect(InitTicket, SELECT_BY_TICKET) == true)
{
double new_SL = OrderStopLoss();
double new_TP = OrderTakeProfit();
int dont_care = OrderSend(NULL,OP_BUY,lotsize,Ask,slippage,new_SL,new_TP,EAComment+" martin",1,0,clrDarkBlue);
}
}
//---
void MartinSell()
{
if (OrderSelect(InitTicket, SELECT_BY_TICKET) == true)
{
double new_SL = OrderStopLoss();
double new_TP = OrderTakeProfit();
int dont_care = OrderSend(NULL,OP_SELL,lotsize,Bid,slippage,new_SL,new_TP,EAComment+" martin",1,0,clrDarkRed);
}
}
//---
void SearchSignal()
{
X = 0.0; //where 0.0, put here the iCustom for external indicators, or some built-in indicator
if (X >= upper_border)
{
mode = "Sell";
}
else if (X <= lower_border)
{
mode = "Buy";
}
else
{
mode = "";
first_trade = false;
InitTicket = 1;
X_Last = 0.0;
}
}
//---
void CloseCheck()
{
if (OrderSelect(InitTicket, SELECT_BY_TICKET))
{
if (OrderCloseTime() == 0)
{
first_trade = true;
}
else if (OrderCloseTime() != 0)
{
first_trade = false;
}
else
{
return;
}
}
}
//---
void MartinCheck()
{
if (mode == "Buy")
{
if ((X_Last - stepValue) >= X)
{
X_Last = X;
MartinBuy();
}
}
if (mode == "Sell")
{
if ((X_Last + stepValue) <= X)
{
X_Last = X;
MartinSell();
}
}
}
The layout of your code makes it possible for several processes to happen in sequence all on the same tick which I assume you do not want. Try changing your code initially to this and work from there:
void OnTick()
{
SearchSignal();
if(mode=="Buy")
{
if(!first_trade) Buy();
else
{
MartinCheck();
CloseCheck();
}
}
else if(mode=="Sell")
{
if(!first_trade) Sell();
else
{
MartinCheck();
CloseCheck();
}
}
}
Remember to use if(...) else to stop executing all functions when it should only be an either/or situation.

How to code a MACD in an expert advisor that uses EMA instead of SMA for the signal line

#include <MovingAverages.mqh>
input int fast = 7;
input int slow = 26;
input int signallength =9;
input int closeoropen = 1; //close=0, open=1
input int movingavglength =114;
double ema, macd, signal;
double ind_buffer1[26], ind_buffer2[26];
bool sellsignaldone = false;
bool buysignaldone = false;
void OnTick()
{
ema = iMA(NULL,0,movingavglength,0,MODE_EMA,PRICE_CLOSE,1);
//---- macd counted in the 1-st buffer
for(int i=0; i<slow-1; i++)
ind_buffer1[i]=iMA(NULL,0,fast,0,MODE_EMA,closeoropen,i)-iMA(NULL,0,slow,0,MODE_EMA,closeoropen,i);
//---- signal line counted in the 2-nd buffer
for(int i=0; i<slow-1; i++)
ind_buffer2[i]=iMAOnArray(ind_buffer1,0,signallength,0,MODE_EMA,i);
macd = ind_buffer1[1];
signal = ind_buffer2[1];
if (macd > signal && macd<0 && Close[1]>ema && !buysignaldone && OrdersTotal()==0) {
buysignaldone = true;
OrderSend(NULL, OP_BUY,1/Ask, Ask, 3, Ask-(Ask*0.004), Ask+(Ask*0.008), "Buy Order",0,0,clrGreen);
}
if (macd < signal) {
buysignaldone = false;
}
if (macd < signal && macd>0 && Close[1]<ema && !sellsignaldone && OrdersTotal()==0) {
sellsignaldone = true;
OrderSend(NULL, OP_SELL,1/Bid, Bid, 3, Bid+(Bid*0.004), Bid-(Bid*0.008), "Sell Order",0,0,clrRed);
}
if (macd > signal) {
sellsignaldone = false;
}
}
You can't use iMACD for this. I'm not sure what I've done wrong but the signals are in the wrong place
Crossover is here
I got a much better result using iOsMA, but it's still not identical to the indicator.
#property strict
#include <MovingAverages.mqh>
input int fast = 7;
input int slow = 26;
input int signallength =9;
input int closeoropen = 1; //close=0, open=1
input int movingavglength =114;
double sma1, sma2, ema, macd, fastema, slowema, signal;
double ind_buffer1[26], ind_buffer2[26];
bool sellsignaldone = false;
bool buysignaldone = false;
void OnTick()
{
signal = iOsMA(NULL,0,fast,slow,signallength,closeoropen,1);
fastema = iMA(NULL,0,fast,0,MODE_EMA,closeoropen,1);
slowema = iMA(NULL,0,slow,0,MODE_EMA,closeoropen,1);
macd = fastema-slowema;
ema = iMA(NULL,0,movingavglength,0,MODE_EMA,PRICE_CLOSE,1);
if (signal>0 && macd<0 && Close[1]>ema && !buysignaldone && OrdersTotal()==0) {
buysignaldone = true;
OrderSend(NULL, OP_BUY,1/Ask, Ask, 3, Ask-(Ask*0.004), Ask+(Ask*0.008), "Buy Order",0,0,clrGreen);
}
if (macd < signal) {
buysignaldone = false;
}
if (signal<0 && macd>0 && Close[1]<ema && !sellsignaldone && OrdersTotal()==0) {
sellsignaldone = true;
OrderSend(NULL, OP_SELL,1/Bid, Bid, 3, Bid+(Bid*0.004), Bid-(Bid*0.008), "Sell Order",0,0,clrRed);
}
if (macd > signal) {
sellsignaldone = false;
}
}
You can also modify the MACD indicator in the indicator folder, simply adding on the bottom the "ExponentialMAOnBuffer(...);" and "call" the second indicator in the expert using the iCustom function linked to the number of the index of the indicator. (es. for MACD (0,ExtMacdBuffer);(1,ExtSignalBuffer);)
the ea code now is more clear!

Modify Pending Order at Mql4

I am trying to figure out an EA which updates its pending orders if current price pass the SL level of pending order both for buy and sell orders. As you can see below pic current price is below the SL point of pending orders. Therefore I want to modify new updated pending orders with openning price of from those SL point (+30 & -30 point) and not only for window currency but also for other currencies which are in the pending order list.
I tried below code but it didn't work out. Could you help me?
//------------------------------------------------------------------------------- 1 --
int start()
{
string Symb=Symbol(); // Symbol
//------------------------------------------------------------------------------- 2 --
for(int i=1; i<=OrdersTotal(); i++)
{
if (OrderSelect(i-1,SELECT_BY_POS)==true)
{
//---------------------------------------------------------------------- 3 --
if (OrderSymbol()== Symb) continue;
if (OrderType()==OP_BUYSTOP || OrderType()==OP_SELLSTOP) continue; // Market order
//---------------------------------------------------------------------- 4 --
{
int Tip =OrderType();
int Ticket=OrderTicket();
double Price =OrderOpenPrice();
double SL =OrderStopLoss();
double TP =OrderTakeProfit();
}
}
}
//------------------------------------------------------------------------------- 5 --
if (Tip==0)
{
Alert("For ",Symb," no pending orders available");
return;
}
//------------------------------------------------------------------------------- 6 --
while(true)
{
RefreshRates(); // Update data
//------------------------------------------------------------------------- 7 --
double c_bid =MarketInfo(Symb,MODE_BID); // Request for the value of Bid
double c_ask =MarketInfo(Symb,MODE_ASK); // Request for the value of Ask
//------------------------------------------------------------------------- 8 --
string Text=""; // Not to be modified
double New_SL=0;
double New_TP=0;
switch(Tip) // By order type
{
case 4: // BuyStopt
if (NormalizeDouble(SL,Digits) > // If it is further than by
NormalizeDouble(c_ask,Digits))//..the preset value
{
double New_Price=SL+30*Point; // Its new price
if (NormalizeDouble(SL,Digits)>0)
New_SL=New_Price-(Price-SL); // New StopLoss
if (NormalizeDouble(TP,Digits)>0)
New_TP=New_Price+(TP-Price); // New TakeProfit
Text= "BuyStopt "; // Modify it.
}
break; // Exit 'switch'
case 5: // SellStop
if (NormalizeDouble(SL,Digits) < // If it is further than by
NormalizeDouble(c_bid,Digits))//..the preset value
{
New_Price=SL-30*Point; // Its new price
if (NormalizeDouble(SL,Digits)>0)
New_SL=New_Price+(SL-Price); // New StopLoss
if (NormalizeDouble(TP,Digits)>0)
New_TP=New_Price-(Price-TP); // New TakeProfit
Text= "SellStop "; // Modify it.
}
}
if (NormalizeDouble(New_SL,Digits)<0) // Checking SL
New_SL=0;
if (NormalizeDouble(New_TP,Digits)<0) // Checking TP
New_TP=0;
if (Text=="") // If it is not modified
{
Alert("No conditions for modification.");
break; // Exit 'while'
}
//------------------------------------------------------------------------ 10 --
Alert ("Modification ",Text,Ticket,". Awaiting response..");
bool Ans=OrderModify(Ticket,New_Price,New_SL,New_TP,0);//Modify it!
//------------------------------------------------------------------------ 11 --
if (Ans==true) // Got it! :)
{
Alert ("Modified order ",Text," ",Ticket," :)");
break; // Exit the closing cycle
}
//------------------------------------------------------------------------ 12 --
int Error=GetLastError(); // Failed :(
switch(Error) // Overcomable errors
{
case 4: Alert("Trade server is busy. Retrying..");
Sleep(3000); // Simple solution
continue; // At the next iteration
case 137:Alert("Broker is busy. Retrying..");
Sleep(3000); // Simple solution
continue; // At the next iteration
case 146:Alert("Trading subsystem is busy. Retrying..");
Sleep(500); // Simple solution
continue; // At the next iteration
}
switch(Error) // Critical errors
{
case 2 : Alert("Common error.");
break; // Exit 'switch'
case 64: Alert("Account is blocked.");
break; // Exit 'switch'
case 133:Alert("Trading is prohibited");
break; // Exit 'switch'
case 139:Alert("Order is blocked and is being processed");
break; // Exit 'switch'
case 145:Alert("Modification prohibited. ",
"Order is too close to the market");
break; // Exit 'switch'
default: Alert("Occurred error ",Error);//Other alternatives
}
break; // Exit the closing cycle
} // End of closing cycle
//------------------------------------------------------------------------------ 13 --
Alert ("The script has completed its operations -----------------------");
return; // Exit start()
}
//------------------------------------------------------------------------------ 14 --
Welcome to the Worlds of MQL-4.56789...
Since the early days of the MQL4 language, the specifications 've changed a lot.
Your script suffers from a "recent"-New-MQL4.56789... change, where scope of validity of declared variables got restricted to a syntax-constructor-only ( this was not in the MQL4 original ).
So, declaring an int Tip et al but inside an if(){...}-block causes no Tip-variable to remain visible outside the {...}-block-constructor, not being know there anymore.
Next, your code requires a complete re-design, so as to meet your requirement of :
"not only for window currency but also for other currencies which are in the pending order list."
// ------------------------------------------------------------------------------- 2 --
for( int i=1; i <= OrdersTotal(); i++ )
{
if ( True == OrderSelect( i-1, SELECT_BY_POS ) )
{
//---------------------------------------------------------------------- 3 --
if ( OrderSymbol() == Symb ) continue; // ------------------------^ JIT/LOOP
if ( OrderType() == OP_BUYSTOP
|| OrderType() == OP_SELLSTOP
) continue; //-----------------------------------------------^ JIT/LOOP
// btw. was a pending { BUYSTOP || SELLSTOP }
//---------------------------------------------------------------------- 4 --
{ // a rest goes here :
int Tip = OrderType();
int Ticket = OrderTicket();
double Price = OrderOpenPrice();
double SL = OrderStopLoss();
double TP = OrderTakeProfit();
}
// ------------------------------ BUT ALL THESE GOT FORGOTTEN RIGHT HERE...
}
}
// ------------------------------------ OK, 've LOOPED THE WHOLE DB-POOL,
// BUT DID NOTHING SO FAR
// AND NOTHING SO FORTH
So, something evolved from this will help to settle the script on the rock-solid grounds :
#define MASK "(for i==(%3d)) got OrderTKT(%20d) of TYPE{BUY|SELL|BUYLIMIT|SELLLIMIT|BUYSTOP|SELLSTOP}=[%d] in (%10s)-MARKET ... WILL LOOP for a NEXT(?) ONE"
while ( !IsStopped() ) // ----------------------------------------------------------- 1 --
{ // (almost) INFINITE SCRIPT SERVICE LOOP
// as (almost) HEADLESS Sir NICHOLAS :)
string TradeSYMBOL;
int Tip;
int Ticket;
double Price;
double SL;
double TP;
if ( 1 > OrdersTotal() ) { Sleep( 333 ); continue; } // NOP / NAP ----------^ NOP/LOOP
// ------------------------------------------------------------------------------ 2 --
for( int i=0; i < OrdersTotal(); i++ ) // DB-POOL LOOP
{
if ( OrderSelect( i, SELECT_BY_POS ) )
{
//---------------------------------------------------------------------- 3 --
if ( OrderType() != OP_BUYSTOP
&& OrderType() != OP_SELLSTOP
) {
PrintFormat( MASK, i, OrderTicket(), OrderType(), OrderSymbol() );
continue; //-------------------------------------------------^ JIT/LOOP
} // btw. ! a pending { BUYSTOP || SELLSTOP }
//---------------------------------------------------------------------- 4 --
else
{ // a { BUYSTOP || SELLSTOP } go here :
// -------------------------------------------------------------------- SET :
Tip = OrderType();
Ticket = OrderTicket();
Price = OrderOpenPrice();
SL = OrderStopLoss();
TP = OrderTakeProfit();
TradeSYMBOL = OrderSymbol();
// ------------------------------------------------------------- PROCESS it :
RefreshRates();
...
// Alert() - a blocking GUI operation, quite dangerous in auto-trading
// any
// OrderModify() - has also to respect the Broker-defined {Stop|Freeze}Level
...
} // { BUYSTOP || SELLSTOP }
} // .SELECT
} // .DB-POOL LOOP________________________________________________________
} // .SERVICE LOOP........................................................

How to make Break even trigger more than one time in one entry

I now trying to make Break Even Code trigger more than one time,
example EA entry is 1.28000 and stop loss 1.28500
if current price reach 1.175000(50pips), sl move to break even such as to 1.28000(5pips).
EA will not make more modify order after condition are meet.
so how to trigger break even again if price reach 1.17000(100pips), sl move to (1.175000)(50 pips)
and again price reach 1.165000(150pips),sl move to 1.17000(100pips)
I want to make
BE_B_M(sl move to(example:5))
and
BE_B_T(price reach(example:50))
as variable and every time price reach target variable change to next value
so became
BE_B_M(sl move to(example:50)) and BE_B_T(price reach(example:100))
The entire code is as follows
extern double BE_T_1 = 50;
extern double BE_M_1 = 5;
extern double BE_T_2 = 100;
extern double BE_M_2 = 50;
extern double BE_T_3 = 150;
extern double BE_M_3 = 100;
double BE_S_M;
double BE_S_T;
void MOVE_BE_1()
{
for(int b=OrdersTotal()-1;b>=0;b--)
{
if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
if(OrderMagicNumber()!=M_Number)continue;
if(OrderSymbol()==Symbol())
if(OrderType()==OP_BUY)
if(Bid-OrderOpenPrice()>BE_S_T*Pips)
if(OrderOpenPrice()>OrderStopLoss())
if(!OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()+(BE_S_M*Pips),OrderTakeProfit(),0,CLR_NONE))
Print("eror");
}
for(int s=OrdersTotal()-1;s>=0;s--)
{
if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES))
if(OrderMagicNumber()!=M_Number)continue;
if(OrderSymbol()==Symbol())
if(OrderType()==OP_SELL)
if(OrderOpenPrice()-Ask>BE_S_T*Pips)
if(OrderOpenPrice()<OrderStopLoss())
if(!OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice()-(BE_S_M*Pips),OrderTakeProfit(),0,CLR_NONE))
Print("eror");
}
}
i expect sl will move after price reach every 50pips from entry
Here you can put all the 3 break even levels on one function.
Note: you can use 1 for-loop for both OP_BUY and OP_SELL
Here is my OnInit()
// Global variable
double point;
int OnInit()
{
if(Digits == 5 || Digits == 3) point=Point*10;
else point=Point;
return(INIT_SUCCEEDED);
}
Here is the BreakEven() function
//+------------------------------------------------------------------+
//| Break even the trade at 3 levels |
//+------------------------------------------------------------------+
void BreakEven()
{
// get the stop level for that symbol
double stopLevel = SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL)*Point;
for(int i=OrdersTotal()-1;i>=0;i--)
{
if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
if(OrderMagicNumber()!=M_Number)continue;
if(OrderSymbol()!=Symbol())continue;
if(OrderType()==OP_BUY)
{
double profitPips=Bid-OrderOpenPrice();
double newSL=OrderStopLoss();
if(profitPips>=BE_T_1*point && OrderStopLoss()<OrderOpenPrice()) // Break Even
{
newSL=OrderOpenPrice()+BE_M_1*point;
}
else if(profitPips>=BE_T_3*point) // 150/100
{
newSL=OrderOpenPrice()+BE_M_3*point;
}
else if(profitPips>=BE_T_2*point) // 100/50
{
newSL=OrderOpenPrice()+BE_M_2*point;
}
if(newSL>=OrderStopLoss()+Point && newSL<Bid-stopLevel)
if(!OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(newSL,Digits),OrderTakeProfit(),0))
Print("Error at BE: ",GetLastError());
}
else if(OrderType()==OP_SELL)
{
double profitPips=OrderOpenPrice()-Ask;
double newSL=OrderStopLoss();
if(profitPips>=BE_T_1*point && (OrderStopLoss()>OrderOpenPrice() || OrderStopLoss()==0)) // Break Even
{
newSL=OrderOpenPrice()-BE_M_1*point;
}
else if(profitPips>=BE_T_3*point) // 150/100
{
newSL=OrderOpenPrice()-BE_M_3*point;
}
else if(profitPips>=BE_T_2*point) // 100/50
{
newSL=OrderOpenPrice()-BE_M_2*point;
}
if(newSL<=OrderStopLoss()-Point && newSL>Ask+stopLevel)
if(!OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(newSL,Digits),OrderTakeProfit(),0))
Print("Error at BE: ",GetLastError());
}
}
}
I didn't test this myself in a trade, but it should work.

Resources