MQL4 automatic stop - mql4

My Martingale EA should be stopped automatically if the previously manually set limit has been reached or exceeded. The last trade should expire normally and not be interrupted.
So far, I've tried the following code, without interruption, etc. the code works fine.
I also heard about RemoveExpert, but I do not know how to do it. Am grateful for any help :)
enum tradeD{Buy=1, Sell=2};
input tradeD TradeType = Buy;
input double Initial_Lot = 0.01;
input double Lot_Factor = 2;
input int Max_Spread = 30;
input double Pct_SL = 0.1; // Percentage Stop Loss
input double Pct_TP = 0.1; // Percentage Take Profit
input int Magic_Number= 73726;
input int interrupt = 1,0000;
input bool StopEA = false;
int OnInit()
{
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
int start()
{
if (StopEA == true) { return(0); } //This line will skip the execution of EA.
}
void OnTick()
{
if(OpenOrders()==0 && (SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)<Max_Spread||Max_Spread==0)){
if(TradeType==Buy){
double flot=Initial_Lot;
double etp=Ask+(Ask*(Pct_TP/100));
etp=NormalizeDouble(etp,Digits);
double esl=Ask-(Ask*(Pct_TP/100));
esl=NormalizeDouble(esl,Digits);
if (ask <= interrupt) { StopEA = true; return(0); }
if(lastProfit()<0){
flot=NormalizeDouble(lastLot()*Lot_Factor,2);
}
int snd=OrderSend(Symbol(),OP_BUY,flot,Ask,10,esl,etp,NULL,Magic_Number,0,clrAliceBlue);
}
if(TradeType==Sell){
double flot=Initial_Lot;
double etp=Bid-(Bid*(Pct_TP/100));
etp=NormalizeDouble(etp,Digits);
double esl=Bid+(Bid*(Pct_TP/100));
esl=NormalizeDouble(esl,Digits);
if (bid >= interrupt) { StopEA = true; return(0); }
if(lastProfit()<0){
flot=NormalizeDouble(lastLot()*Lot_Factor,2);
}
int snd=OrderSend(Symbol(),OP_SELL,flot,Bid,10,esl,etp,NULL,Magic_Number,0,clrAliceBlue);
}
}
//checkProfit();
}
int checkProfit(){
int total=0;
for(int i=OrdersTotal()+5; i >= 0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
string ordsymB = OrderSymbol();
int ordtypeB =OrderType();
int magicnB = OrderMagicNumber();
int magicn=magicnB;
double ordProfit=OrderProfit();
int tick=OrderTicket();
double oLots=OrderLots();
if(ordsymB==Symbol() && magicnB==Magic_Number){
double pctBalT=AccountBalance()*(Pct_TP/100);
double pctBalS=AccountBalance()*(Pct_SL/100);
if(ordProfit>=pctBalT){
int clo=OrderClose(tick,oLots,Close[0],10,clrAntiqueWhite);
}
if(ordProfit<0 && MathAbs(ordProfit)>=pctBalS){
int clo=OrderClose(tick,oLots,Close[0],10,clrAntiqueWhite);
}
}
}
}
return (total);
}
int OpenOrders(){
int total=0;
for(int i=OrdersTotal()+5; i >= 0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
string ordsymB = OrderSymbol();
int ordtypeB =OrderType();
int magicnB = OrderMagicNumber();
int magicn=magicnB;
if(ordsymB==Symbol() && magicnB==Magic_Number){
total++;
}
}
}
return (total);
}
double lastProfit(){
double total=0;
datetime lastTime=0;
for(int i=OrdersHistoryTotal(); i >= 0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)){
string ordSym=OrderSymbol();
int ordType=OrderType();
datetime ordTime=OrderOpenTime();
double ordLot=OrderLots();
double ordOp=OrderOpenPrice();
int ordMag=OrderMagicNumber();
double ordProfit=OrderProfit();
if(ordSym==Symbol() && ordTime>lastTime && ordMag==Magic_Number){
lastTime=ordTime;
total=ordProfit;
}
}
}
return(total);
}
double lastLot(){
double total=0;
datetime lastTime=0;
for(int i=OrdersHistoryTotal(); i >= 0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)){
string ordSym=OrderSymbol();
int ordType=OrderType();
datetime ordTime=OrderOpenTime();
double ordLot=OrderLots();
double ordOp=OrderOpenPrice();
int ordMag=OrderMagicNumber();
if(ordSym==Symbol() && ordTime>lastTime && ordMag==Magic_Number){
lastTime=ordTime;
total=ordLot;
}
}
}
return(total);
}

if(tick_counter>=ticks_to_close)
{
ExpertRemove();
Print(TimeCurrent(),": ",__FUNCTION__," expert advisor will be unloaded");
}

Related

My do while loop is not entering the while loop

I'm trying to complete my homework assignment and am having trouble. The instructions state that I need to change the while expression to a not but whenever I do it wont enter the loop.
import java.util.Scanner;
public class GuessNumberApp {
public static void main(String[] args) {
final int LIMIT = 10;
System.out.println("Guess the number!");
System.out.println("I'm thinking of a number from 1 to " + LIMIT);
System.out.println();
// get a random number between 1 and the limit
double d = Math.random() * LIMIT; // d is >= 0.0 and < limit
int number = (int) d; // convert double to int
number++; // int is >= 1 and <= limit
Scanner sc = new Scanner(System.in);
int count = 1;
int guess;
do {
System.out.print("Your guess: ");
guess = Integer.parseInt(sc.nextLine());
}
while (guess != number); {
if (guess < 1 || guess > LIMIT) {
System.out.println("Invalid guess. Try again.");
}
else if (guess < number) {
System.out.println("Too low.");
count++;
}
else if (guess > number) {
System.out.println("Too high.");
count++;
}
}
System.out.println("You guessed it in " + count + " tries.\n");
System.out.println("Bye!");
}
}

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!

how can i fix array error in mql4 source?

I have a angle checking mql4 source but it have array out of range error.
I can't figure out what is the problem.
I can guess the problem comes from a loop but can't fix the error.
I did several modifications like i+1 or so where possibly can fix the error but to no success.
I'm guessing the error comes from here: MALast= varMA[i+nb_0];
anyone enlighten me much appreciate
#property indicator_chart_window
#property indicator_color1 CLR_NONE
#property indicator_buffers 3
#property indicator_color2 CLR_NONE
extern int ma_per = 10;
extern int ma_met = 3;
extern color col_ang = clrYellow;
extern int ExtDepth = 21;
extern int ext = 0;
extern int Complect = 0;
double varMA[], value[];
//-------------------------------------------------------------------------
int init()
{
IndicatorBuffers(3);
IndicatorDigits(Digits+1);
SetIndexBuffer(0,varMA);
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(1, value);
return(0);
}
//-------------------------------------------------------------------------
int deinit()
{
ObjectDelete("AngleA "+Complect);
ObjectDelete("AngleText "+Complect);
Comment("");
return(0);
}
//-------------------------------------------------------------------------
int start()
{
int i, limit, counted_bars=IndicatorCounted();
limit = Bars-counted_bars-1;
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
double MALast, MACurr;
for(i=limit; i >=0; i--)
{
varMA[i] = iMA(NULL,0,ma_per,0,ma_met,PRICE_CLOSE,i);
int nb_0 = GetZZbar(ext);
MALast= varMA[i+nb_0];
MACurr= varMA[i+1];
if (ObjectFind("AngleA "+Complect)<0)
{
ObjectCreate("AngleA "+Complect,OBJ_TRENDBYANGLE,0,Time[i+nb_0],MALast,Time[i+1],MACurr);
ObjectSet("AngleA "+Complect,OBJPROP_STYLE,2);
}
if (ObjectFind("AngleText "+Complect)==-1)
ObjectCreate("AngleText "+Complect,OBJ_TEXT,0,0,0);
ObjectSet("AngleA "+Complect,OBJPROP_TIME2,Time[i+1]);
ObjectSet("AngleA "+Complect,OBJPROP_PRICE2,MACurr);
ObjectSet("AngleA "+Complect,OBJPROP_TIME1,Time[i+nb_0]);
ObjectSet("AngleA "+Complect,OBJPROP_PRICE1,MALast);
ObjectSet("AngleA "+Complect,OBJPROP_COLOR,col_ang);
value[i] = (double)ObjectGet("AngleA "+Complect,OBJPROP_ANGLE);
if(value[i]>90)
value[i] = value[i]-360;
value[i+1] = value[i];
ObjectSetText("AngleText "+Complect,DoubleToStr(value[i],2),8,"Verdana",col_ang);
ObjectMove("AngleText "+Complect,0,Time[0]+8*Period()*60,ObjectGetValueByShift("AngleA "+Complect,i));
}
Comment(value[0]);
return(0);
}
//-------------------------------------------------------------------------
int GetZZbar(int ne=0)
{
double zz;
int j, k=iBars(NULL, 0), ke=0;
for (j =1; j <k; j++)
{
zz=iCustom(NULL, 0, "ZigZag", ExtDepth,5,3, 0,j);
if (zz !=0)
{
ke++;
if (ke > ne)
return(j);
}
}
return(-1);
}
//-------------------------------------------------------------------------

MQL4 How to call OnChartEvent() from init()

I want to call OnChartEvent() from init() like the code below, so the EA should process first the password and then the rest of the code.
I am just newbie not an expert in coding.
The idea or objective, the password must enter first and correctly, after successful then process the rest of code.
#include <ChartObjects/ChartObjectsTxtControls.mqh>
int init()
{
password_edit.Create(0, "password_edit", 0, 10, 10, 260, 25);
password_edit.BackColor(White);
password_edit.BorderColor(Black);
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent( const int id,
const long &lparam,
const double &dparam,
const string &sparam
)
{
//---
if (id == CHARTEVENT_OBJECT_ENDEDIT && sparam == "password_edit" )
{
password_status = -1;
for (int i=0; i<ArraySize(allowed_passwords); i++)
if (password_edit.GetString(OBJPROP_TEXT) == allowed_passwords[i])
{
password_status = i;
break;
}
if (password_status == -1)
{
password_edit.SetString(OBJPROP_TEXT, 0, password_message[0]);
ExpertRemove();
}
else
{
password_edit.SetString(OBJPROP_TEXT, 0, password_message[1]);
}
}
}
//+------------------------------------------------------------------+
int OnInit(){
passwordOperation();
return INIT_SUCCEED;
}
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//---
if (id == CHARTEVENT_OBJECT_ENDEDIT && sparam == "password_edit" )
{
passwordOperation();
}
}
void passwordOperation()
{
password_status = -1;
for (int i=0; i<ArraySize(allowed_passwords); i++)
if (password_edit.GetString(OBJPROP_TEXT) == allowed_passwords[i])
{
password_status = i;
break;
}
if (password_status == -1)
{
password_edit.SetString(OBJPROP_TEXT, 0, password_message[0]);
ExpertRemove();
}
else
{
password_edit.SetString(OBJPROP_TEXT, 0, password_message[1]);
}
}

Resources