Writing an expert adviser in [ MQL4 ] - mql4

So if I wanted an EA in MQL4 that took the open price and when current price was 10 pips below the open it places a buy order and when it was 10 pips above the open it sold. Only one order at a time and the open changed daily.
Q1: How could that run unstopped?
Q2: Would that even be profitable?
I know this is simple for some people to write but for me it's depressing.

A1: the simplest part ...
The MQL4 Expert Advisor type-of-code's execution can be principally run unstopped, supposing the execution engine, the MetaTrader Terminal 4, is being run in a nonstop mode. While there still remain the weekends available for service & maintenance tasks, the EA code, per se can be operated infinitely long, state-fully with an automated re-entrant safe re-launch self-protection ( OnInit(){...} + OnDeinit(){...} ).
#property copyright "Copyright © 1987-2016 [MS]"
#property link "nowhere.no"
#property version "0.00"
#property strict
extern int minDist2XTO = 10; // A minimum Distance To XTO
bool aGlobalMUTEX_LOCKED = False; // LOCK "only one order at a time"
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{ // on-launch intialisation tasks go here:
return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit( const int reason )
{ // pre-exit sanitisation tasks go here:
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{ // MAIN: this is being executed upon each anFxMarketEVENT's arrival
// GoLONG();
// GoSHORT();
}
//+------------------------------------------------------------------+
//| Tester function |
//+------------------------------------------------------------------+
double OnTester()
{ // back-testing utility calculation functions go here:
double retVal = 0.0;
return( retVal );
}
//+------------------------------------------------------------------+
void GoLONG()
{ // SELF-CONTROLLABLE ( might even get concurrently run in parallel to GoSHORT on dual resources )
// -------------------------------------------------------------------------------------------------------
static bool aNewBarEVENT = FALSE;
static int aLastBAR = EMPTY,
aCurrBAR = EMPTY;
static double GoLONG_LEVEL = EMPTY;
// -------------------------------------------------------------------------------------------------------
// TEST A STATE-SHIFT
RefreshRates();
aCurrBAR = iBars(_Symbol, PERIOD_D1 );
if ( aLastBAR != aCurrBAR )
{ aLastBAR = aCurrBAR; // .SET
aNewBarEVENT = TRUE; // .FLAG
// ----------------------- // .RESET in-BAR-registers
GoLONG_LEVEL = NormalizeDouble( iOpen( _Symbol, PERIOD_D1, 0 )
- minDist2XTO * _Point
);
// ----------------------
}
else
{ aNewBarEVENT = FALSE; // !FLAG
}
if ( !aGlobalMUTEX_LOCKED
&& Ask <= GoLONG_LEVEL
)
{
// XTO ... // .XTO
if ( success ) aGlobalMUTEX_LOCK = True;
}
}
//+------------------------------------------------------------------+
void GoSHORT()
{ // SELF-CONTROLLABLE ( might even get concurrently run in parallel to GoLONG on dual resources )
...
..
.
}
A2:
This question can be addressed quantitatively. Your trading idea can be tested and validated on the real-market data, so as to provide a reasonable amount of observations that either support or limit the expected performance expectations.
Without quantitative data from adequate TimeDOMAIN span of the market seasonality irregularities, the question cannot have a reasonably supported quantitative answer ( except for just an opinion ).
This goes far beyond a StackOverflow format of Q/A, but in principle back-testing ( with a support of an inbuilt mechanism of double OnTester(){...} post-processing facility ) and forward-testing ( with a support of demo-account forward runs ) are both being used in quant modelling, before any real trading strategy is ever exposed to execute any real market-risk.

Related

problem With repeating Orders and let the Limited order move with the price in MQL5

am Trying To Code an EA has This Jobs dealing with Boom 1000 index
Set Limited Order (Buy \ Sell)
and The Orders moving with the price in that way:
if the price goes down the buy stop will follow each candle for waiting for the bullish candle, and the same thing for the sell order
I have this problem:
the orders repeating if I close the EA or I changed the frame
"I have a problem with deinitialization"
I have no idea how can I let the order move with each candle
"adjust the order
the code I have used:
//+------------------------------------------------------------------+
//| EABoom1000Scalper.mq5 |
//| Copyright 2022, OshGroup ltd. |
//| https://oshgrp.com/ar |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022, OshGroup ltd."
#property link "https://oshgrp.com/ar"
#property version "1.01"
#property description "Note:The EA Work with Buy and Sell\n"
#property description "If You Dont Need TP Or SL just let it 0 "
#property description "Try Version N10 Will destroy after 7 days"
//+-----------------Include--------------------------------+
#include <Trade/Trade.mqh>
#include <Expert\Expert.mqh>
#include <Expert\Signal\SignalMA.mqh>
#include <Expert\Trailing\TrailingParabolicSAR.mqh>
#include <Expert\Money\MoneySizeOptimized.mqh>
//+-----------------------Enumoration------------------------------+
enum TradeAutoOption{
Yes=0,
No=1
};
enum Trade_Type{
BUY=0, SELL=1
}
;
enum SYMBOL_ASK_O{
Boom_Index_1000=0, Crash_Index_1000=1, Boom_Index_500=2, Crash_Index_500=3
};
//+--------------------input parameters-----------------------+
input group "Setting"
input string Inp_Expert_Title ="ScalperExpert";
input group "Trade Type"
input Trade_Type Ordder_Type =BUY;
input group "Order_Details"
input double LOT_SIZE =1.00;
input double Buy_AT =00000.0000;
input double Sell_AT =00000.0000;
input double Tralling_InPoint =2000;
input double Take_Profit_At =0.0;
input double Stop_LOSE =0.0;
input group "Auto Trading"
input TradeAutoOption Trade_Auto =No;
input SYMBOL_ASK_O SYMBOL =Boom_Index_1000;
//--- input parameters
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
CExpert ExtExpert;
CTrade Trade;
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
//+-----------------------Function-----------------------------------+
void Start_Buy(double LOT_SIZE1 ,double Buy_From1 ,double Stop_LOSE1, double Take_Profit_At2){
double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK),_Digits);
if(Ask < Buy_From1){
Trade.BuyStop(LOT_SIZE1 ,Buy_From1,_Symbol,Stop_LOSE1,Take_Profit_At,ORDER_TIME_GTC, NULL , "Buying Started...\n ");
}
else if (Ask > Buy_From1)
{
Trade.BuyLimit(LOT_SIZE1 ,Buy_From1,_Symbol,Stop_LOSE1,Take_Profit_At,ORDER_TIME_GTC, NULL , "Buying Started...\n ");
}
else
{
string comment=StringFormat("\n\nError %d Is the Current Price" , Buy_From1 );
ChartSetString(0,CHART_COMMENT,comment);
}
};//function
void Start_Sell(double LOT_SIZE2 , double Sell_From2 , double Stop_LOSE2 , double Take_Profit_At2)
{
double Bid= NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
if(Bid > Sell_From2 )
{
Trade.SellStop(LOT_SIZE2 , Sell_From2 ,_Symbol,Stop_LOSE2 , Take_Profit_At2 , ORDER_TIME_GTC , "SEll Started...\n");
}
else if (Bid < Sell_From2)
{
Trade.SellLimit(LOT_SIZE2 , Sell_From2 ,_Symbol,Stop_LOSE2 , Take_Profit_At2 , ORDER_TIME_GTC , "SEll Started...\n");
}
else
{
string comment=StringFormat("\n\nError %d Is the Current Price" , Sell_From2 );
ChartSetString(0,CHART_COMMENT,comment);
}
};
void Chek_Typ(int Ordder_Type){
if(Ordder_Type == BUY)
{
Start_Buy(LOT_SIZE ,Buy_AT , Stop_LOSE , Take_Profit_At);
}
else
{
Start_Sell(LOT_SIZE , Sell_AT , Stop_LOSE , Take_Profit_At);
}
};
void SetVAlueOneTheChart(){
double ID = 1;
string comment=StringFormat("The Expert Working... %d" , ID );
ChartSetString(0,CHART_COMMENT,comment);
};
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
//-----------------------Initializing expert--------------------------------
//SetVAlueOneTheChart();
Comment("The Expert Working....");
Chek_Typ(Ordder_Type);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Function-event handler "tick" |
//+------------------------------------------------------------------+
void OnTick(void)
{
}
//+------------------------------------------------------------------+
//| Function-event handler "trade" |
//+------------------------------------------------------------------+
void OnTrade(void)
{
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason )
{
if()
Trade_Type Ordder_Type =BUY;
double LOT_SIZE =1.00;
double Buy_AT =00000.0000;
double Sell_AT =00000.0000;
double Tralling_InPoint =2000;
double Take_Profit_At =0.0;
double Stop_LOSE =0.0;
ExtExpert.Deinit();
Print("The deinitialization occured_Error Number Is" , reason);
}

FileOpen is failed sometimes in MQL4

In an EA I'm writing a couple of integer values (some OrderTickects) into a bin file.
Then I have a TP/SL modification function that loops through active trades and applies the modifications. This function is called by each tick and opens the file and if the order ticket found in the file should ignore that order without modification.
The problem is that it successfully opens the file and reads it but only for the first time.
the rest of the time it gives me an error of 0.
I have checked everything as much as I could and tracked the issue with putting lots of prints until eventually, I am pretty sure that the problem is only the failure of the FileOpen function.
THIS HAPPENED ON TESTER. I'm not sure if it will happen on the live market as well or not, because, to catch the issue on live testing would be very hard with this EA.
I should add that every time that I opened the file, I also closed it.
My only guess is that maybe when I call the FileClose function before it closes the file successfully the next call of FileOpen arrives.
Can it be the reason?
I would highly appreciate any guidance or ideas.
Do you think I can trust opening the file in the live market?
Here are the related parts of the code.
Save function is called so less often, but IsBE_Done() is called by every tick if there are one or more active trades.
void Save(int ticket)
{
int handle = FileOpen("BE1.bin", FILE_BIN | FILE_WRITE | FILE_READ);
if(handle != INVALID_HANDLE)
{
FileSeek(handle, 0, SEEK_END);
FileWriteInteger(handle, ticket);
//---
FileClose(handle);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool IsBE_Done(int ticket)
{
int handle = FileOpen("BE1.bin", FILE_BIN | FILE_WRITE | FILE_READ);
if(handle != INVALID_HANDLE)
{
FileSeek(handle, 0, SEEK_SET);
while(!FileIsEnding(handle))
{
int val = FileReadInteger(handle);
if(ticket == val)
return true;
}
//---
FileClose(handle);
}
//---
return false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void TPSL_Modification()
{
//---
if(!Modifications)
return;
//---
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
continue;
//---
if(OrderMagicNumber() != MAGICMA || OrderSymbol() != _Symbol)
continue;
//---
if(IsBE_Done(OrderTicket())) //====>>> This is what opens the file
continue;
//---

wrong buffer value retrieved from mql5 indicator using iCustom

I just moved from mql4 to mql5 and now i am trying to read buffers values from an indicator , but it only shows me 0 instead of the actual buffer values
Here is my code :
#property version "1.00"
int handle1 = 0;
double valu1,valu2,valu3,valu4;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- create timer
EventSetTimer(60);
handle1 = iCustom(NULL, NULL, "LTD by KDMfx");
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- destroy timer
EventKillTimer();
IndicatorRelease(handle1);
}
//+------------------------------------------------------------------+
//| Get indicator value |
//+------------------------------------------------------------------+
double GetIndicator(int handle, int buffer_num, int index)
{
double arr[];
if(CopyBuffer(handle, buffer_num, 0, index+1, arr) <= 0)
{
Sleep(200);
for(int i=0; i<100; i++)
{
if(BarsCalculated(handle) > 0)
break;
Sleep(50);
}
int copied = CopyBuffer(handle, buffer_num, 0, index+1, arr);
if(copied <= 0)
{
Print("CopyBuffer failed. Maybe history has not download yet? Error = ", GetLastError());
return -1;
}
else
return (arr[index]);
}
return 0;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTick()
{
//---
valu1 = GetIndicator(handle1,0,4);
valu2 = GetIndicator(handle1,1,4);
valu3 = GetIndicator(handle1,2,4);
valu4 = GetIndicator(handle1,3,4);
Comment("b1: ", valu1,
"\nb2: ", valu2,
"\nb3: ", valu3,
"\nb4: ", valu4
);
}
what am i doing wrong here ?
the indicator does not appear on the current or the last closed candle , it appears on the current+4 candle , meaning on the 5th candle in past . so i am using "4" as the candle id but still no use , no matter what i try i can get it to work
Try simplifying things a bit. I don't have a copy of the indicator you are trying to read, but the following code should work
#property version "1.10"
#property strict
int handle;
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit()
{
handle=iCustom(_Symbol, 0, "LTD by KDMfx");
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
IndicatorRelease(handle);
}
//+------------------------------------------------------------------+
//| "Tick" event handler function |
//+------------------------------------------------------------------+
void OnTick()
{
double LTDindicator[];
ArraySetAsSeries(LTDindicator, true);
CopyBuffer(handle, 0, 0, 25, LTDindicator);
Comment(LTDindicator[0]);
return;
}

Messagebox is closing trades regardless of "Yes" or "No" button clicked

This has genuinely got to be one of the must ludicrous, most ridiculous situation I have even been in with this coding language.
Is there any reason as to why my trades are closing, regardless as to the button pressed on the prompted Messagebox- despite the fact my EA is only supposed to close trade when the IDYES button is selected?
I click the IDYES button, my trade liquidates, I click the IDNO button, my trade liquidates.
Why is me EA doing things I have not told it to do? The word "fuming" cannot express enough how I'm feeling.
Here is the snippet below:
//+------------------------------------------------------------------+
//| initialization_test.mq4 |
//| Copyright 2020, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
datetime LastActiontime;
bool totalOrders = OrdersTotal();
double currencyConversion;
double tradeSpread;
int ordersTotal;
int OnInit()
{
//---
LastActiontime=Time[0];
if (totalOrders == 0){
totalOrders = true;
}
//---
return(INIT_SUCCEEDED);
}
void OnTick()
{
//---
int LotSize = 1;
int RewardFactor = 3;
int stopLossPoints = 200;
double entryPriceBid = MarketInfo(Symbol(),MODE_BID);
double spread = MarketInfo(Symbol(), MODE_SPREAD);
double tickvalue = MarketInfo(Symbol(), MODE_TICKVALUE);
color sellcolor = clrGreen;
bool Newbar = true;
currencyConversion = 100000/(tickvalue * 100000);
tradeSpread = (spread * tickvalue)*LotSize;
if(LastActiontime!=Time[0])
if(OrdersTotal() == 0)
if(totalOrders == true){
bool OpenShort = OrderSend(Symbol(),OP_BUY,LotSize,MarketInfo(Symbol(),MODE_BID),100,((entryPriceBid/Point)-(stopLossPoints))*Point,((entryPriceBid/Point)+(stopLossPoints*RewardFactor))*Point,"Spread Charge £"+DoubleToStr((spread * tickvalue)*LotSize,2),Period(),0,sellcolor);
LastActiontime=Time[0];
if (OpenShort == true){
bool msgBox = MessageBox("Please confirm the risk on this trade with the margin at the bottom of the terminal. Would you liketo close this trade?"+
"\n"+
"\n£"+DoubleToStr(((tickvalue * LotSize)*stopLossPoints)+ tradeSpread,2),"Information", MB_YESNO|MB_ICONQUESTION|MB_TOPMOST);
if (msgBox = IDYES){
ordersTotal = OrdersTotal();
for(int b=ordersTotal-1;b>=0;b--){
if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES)==true){
bool closeOrder = OrderClose(OrderTicket(),LotSize,MarketInfo(Symbol(),MODE_BID),300,clrAqua);
}
}
}
if (msgBox = IDNO){
return;
}
Print("The tick value used for this EA is £ "+DoubleToStr(tickvalue , 5)+" and the conversion is "+DoubleToStr(currencyConversion,5));
SendMail("You have opened a position","You have opened a position");
}
}
}
//+------------------------------------------------------------------+
You have defined the return value from your MessageBox as Boolean, however it should be of type int.
int MessageBox(string text, string caption=NULL, int flags=0);
Change your code to
int msgBox = MessageBox("Please confirm the risk on this trade with the margin at the bottom of the terminal. Would you liketo close this trade?"+
"\n"+
"\n£"+DoubleToStr(((tickvalue * LotSize)*stopLossPoints)+ tradeSpread,2),"Information", MB_YESNO|MB_ICONQUESTION|MB_TOPMOST);

MetaTrader Terminal 4: debugging an expert advisor on historical data

I have a MetaTrader Terminal 4 logged into a demo account.
I have written and compiled my first Expert Advisor.
I am able to debug it on a live chart, so working fine. I would like to debug it though on historical data. In the MetaEditor the Debug>Start on history data is grey out though.
Also when running the strategy tester my break points never get hit, I put the break point on the first line in the OnTick() function, so it should get hit in my understanding.
Is this because I have a demo account? If not how can I debug my script on historical data?
update code below
#property strict
//+------------------------------------------------------------------+
//| Includes and object initialization |
//+------------------------------------------------------------------+
#include <book_examples\Trade.mqh>
CTrade Trade;
CCount Count;
#include <book_examples\Timer.mqh>
CTimer Timer;
CNewBar NewBar; // keeps track of timestamp of current bar & allows us to
determine when a new bar has opened so prevents orders being opened intrabar
#include <book_examples\TrailingStop.mqh>
#include <book_examples\MoneyManagement.mqh>
#include <book_examples\Indicators.mqh>
//+------------------------------------------------------------------+
//| Input variables |
//+------------------------------------------------------------------+
// left out to keep the post short
//+------------------------------------------------------------------+
//| Enum |
//+------------------------------------------------------------------+
enum trade_action
{
NO_ACTION = 0,
LONG = 1,
SHORT = 2,
EXIT_TRADE = 3
};
//+------------------------------------------------------------------+
//| Global variable and indicators |
//+------------------------------------------------------------------+
int gBuyTicket, gSellTicket;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Set magic number
Trade.SetMagicNumber(101);
Trade.SetSlippage(10);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Check for bar open
bool newBar = true; // I put a breakpoint on this line
int barShift = 0;
if(TradeOnBarOpen == true)
{
newBar = NewBar.CheckNewBar(_Symbol,_Period);
barShift = 1;
}
// Trading
if(newBar == true)
{
// Money management
double lotSize = FixedLotSize;
if(UseMoneyManagement == true)
{
lotSize = MoneyManagement(_Symbol,FixedLotSize,RiskPercent,StopLoss);
}
trade_action action = calculate_signal();
// Open buy order
if(action == LONG)
{
// close sell orders
Trade.CloseAllSellOrders();
// check if we already have an open buy trade
int open_buy = Count.Buy();
if(open_buy == 0)
{
// no current existing buy position so enter
gBuyTicket = Trade.OpenBuyOrder(_Symbol,lotSize);
ModifyStopsByPoints(gBuyTicket,StopLoss,TakeProfit);
}
}
// Open sell order
else if(action == SHORT)
{
Trade.CloseAllBuyOrders();
// check if we already have an open sell trade
int open_sell = Count.Sell();
if(open_sell == 0)
{
// no current existing sell position so enter
gSellTicket = Trade.OpenSellOrder(_Symbol,lotSize);
ModifyStopsByPoints(gSellTicket,StopLoss,TakeProfit);
}
}
}
}
trade_action calculate_signal()
{
trade_action action = NO_ACTION;
// now calculate trade logic
if (some_value > some_threshold)
{
action = LONG;
}
else if (some_value < some_threshold)
{
// enter short position
action = SHORT;
}
return action;
}
Q : "Is this because I have a demo account?"
No.
Q : "If not how can I debug my script on historical data?"
In the MT4 (as-is-2020/06) you still can implement, if in a need to have such, your own "debugging"-Inspector/Monitor-agent tool to get executed during the StrategyTester-mode of the run of the MQL4 compiled-EA.
The MT4's StrategyTester is a BackTesting tool, not an (emulated)live-market Simulator-and-Debugger, it only operates the EA in synthetic(accelerated|slowed-down)-time, using a controlled-flow of synthetic-QUOTE-message(s), emulated for a given trading instrument and TimeFrame.

Resources