How can I populate a dynamic two dimensional array in a for loop - algorithmic-trading

This might seem trivial to many but it seems to be getting the better of me as I've not been able to figure out how to use the ArrayResize() (which I believe is very necessary) to solve this.
In the code below I want to populate ar[][2] when isBody is true. How can I achieve this.
int ar[][2];
void CheckBody() {
for (int i = 20; i >= 0; i--) {
if (isBody) {
int a = i + 1;
int b = i - 3*i;
// how to populate ar with [a,b] when isBody is true in this block
}
}
}

Try the following code, it's programmed to run as an EA but can easily be modified if used in an indicator (you will have to add your code for the isBody variable).
#property strict
int ar[][2];
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit()
{
ArrayInitialize(ar,NULL);
ArrayResize(ar,1);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| "Tick" event handler function |
//+------------------------------------------------------------------+
void OnTick()
{
for(int i=20; i>=0; i--)
{
if(isBody)
{
if(ar[0][0]!=NULL) ArrayResize(ar,ArrayRange(ar,0)+1);
int a=i+1;
int b=i-3*i;
ar[ArrayRange(ar,0)-1][0]=a; ar[ArrayRange(ar,0)-1][1]=b;
}
}
}

Related

error adding new frame when i received data from webSocket in mql5

websocket server node.js
mql5 websocket is :
used from this library
i give this error
enter image description here
my mq5 expert , its just for connect to server and received data .
//+------------------------------------------------------------------+
//| Websocketclient_test.mq5 |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#include<WebSocketClient.mqh>
input string Address="127.0.0.1";
input int Port =3001;
input bool ExtTLS =false;
input int MaxSize=256;
input int Timeout=500;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string _msg="test webSocket";
//---
CWebSocketClient wsc;
//---
int sent=-1;
uint received=-1;
//---
// string subject,issuer,serial,thumbprint;
//---
// datetime expiration;
//---
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- create timer
EventSetMillisecondTimer(500);
//---
wsc.SetMaxSendSize(MaxSize);
//---
if(wsc.Connect(Address,Port,Timeout,ExtTLS,true))
{
sent=wsc.SendString(_msg);
//--
//Print("sent data is "+IntegerToString(sent));
//---
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- destroy timer
EventKillTimer();
Print("Deinit call");
wsc.Close();
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTimer()
{
if(wsc.Readable()>0)
{
CFrame msg_frames[];
received=wsc.Read(msg_frames);
if(received>0)
{
int ll=ArraySize(msg_frames);
Print("number of received frames is :"+IntegerToString(ll));
for(int i=0; i<ll; i++)
{
Alert("r data ",msg_frames[i].ToString());
//wsc.SendString(msg_frames[i].ToString());
}
if(msg_frames[ll-1].IsFinal())
{
Print("\n Final frame received");
//wsc.Close(NORMAL_CLOSE,"good bye");
//ExpertRemove();
}
}
}
else
{
//Print("\n Nothing readable in socket");
if(wsc.ClientState()!=CONNECTED)
{
Print("\n Client disconnected");
//ExpertRemove();
wsc.Connect(Address,Port,Timeout,ExtTLS,true);
}
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
Sometimes it receives the data, sometimes it gives an error in
this function for get data frames
bool CWebSocketClient::parse(CFrame& out[])
{
uint i,data_len=0,frames=0;
uint s=0;
m_total_len=0;
//---
int shift=0;
for(i=0; i<(uint)ArraySize(m_rxbuf); i+=(data_len+shift))
{
++frames;
m_socket.Log("value of frame is "+IntegerToString(frames)+" Value of i is "+IntegerToString(i),__LINE__,__FUNCTION__);
switch((uint)m_rxbuf[i+1])
{
case 126:
data_len=((uint)m_rxbuf[i+2]<<8)+((uint)m_rxbuf[i+3]);
shift=4;
break;
case 127:
data_len=((uint)m_rxbuf[i+2]<<56)+((uint)m_rxbuf[i+3]<<48)+((uint)m_rxbuf[i+4]<<40)+
((uint)m_rxbuf[i+5]<<32)+((uint)m_rxbuf[i+6]<<24)+((uint)m_rxbuf[i+7]<<16)+
((uint)m_rxbuf[i+8]<<8)+((uint)m_rxbuf[i+9]);
shift=10;
break;
default:
data_len=(uint)m_rxbuf[i+1];
shift=2;
break;
}
m_total_len+=data_len;
if(data_len>0)
{
if(ArraySize(out)<(int)frames)
{
if(ArrayResize(out,frames,1)<=0)
{
m_socket.Log("array resize error",__LINE__,__FUNCTION__);
return(false);
}
}
//---
if(!out[frames-1].Fill(m_rxbuf,i+shift,data_len))
{
**//The error occurs here ....**
m_socket.Log("Error adding new frame",__LINE__,__FUNCTION__);
return(false);
}
//---
switch((uchar)m_rxbuf[i])
{
case 0x1:
if(out[frames-1].MessageType()==0)
out[frames-1].SetMessageType(TEXT_FRAME);
break;
case 0x2:
if(out[frames-1].MessageType()==0)
out[frames-1].SetMessageType(BINARY_FRAME);
break;
case 0x80:
case 0x81:
if(out[frames-1].MessageType()==0)
out[frames-1].SetMessageType(TEXT_FRAME);
case 0x82:
if(out[frames-1].MessageType()==0)
out[frames-1].SetMessageType(BINARY_FRAME);
//m_socket.Log("received last frame",__LINE__,__FUNCTION__);
out[frames-1].SetFinal();
break;
case 0x88:
//m_socket.Log("received close frame",__LINE__,__FUNCTION__);
out[frames-1].SetMessageType(CLOSE_FRAME);
if(m_wsclient==CONNECTED)
{
ArrayCopy(m_txbuf,m_rxbuf,0,i+shift,data_len);
m_wsclient=CLOSING;
}
break;
case 0x89:
//m_socket.Log("received ping frame",__LINE__,__FUNCTION__);
out[frames-1].SetMessageType(PING_FRAME);
if(m_wsclient==CONNECTED)
ArrayCopy(m_txbuf,m_rxbuf,0,i+shift,data_len);
break;
case 0x8a:
//m_socket.Log("received pong frame",__LINE__,__FUNCTION__);
out[frames-1].SetMessageType(PONG_FRAME);
break;
default:
break;
}
}
}
//---
return(true);
}
now , help me to solve it
tanks.

Mql5 function for selecting open orders by Ticket, then Symbol, and trade Direction

Total newbie to Mql5, and need some help with this int OpenOrders() piece of code originally from Mql4 EA's, that finds open positions - (if any), and selects originally by SYMBOL, and MAGIC Number, and the expert doesn't open any other positions for as long as a trade it has opened on that symbol has not yet been closed.
I wish the EA to identify a TICKET it has opened, related SYMBOL, and POSITION_TYPE to be used in the ONTICK, and not open any other trades on the same chart until that one position is closed, but can continue trading on any other charts.
input double LotSize =0.3;
input double Incriment =0.01;
input int StopLoss =50;
input int TakeProfit =100;
input int Trend =21;
input int Momentum =21;
input int Strength =13;
int adxlevel =34;
int buylevel =62;
int selllevel =36;
//---------------------
double pips;
#include <Trade\Trade.mqh>
CTrade Execute;
ulong passport, StopLevel;
double ask, bid;
double takeout=0,stopout=0;
int moving,rsi,adx,Spread;
//+------------------------------------------------------------------+
int OnInit()
{
//---
double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_POINT);
if(_Digits==3||_Digits==4)
pips=ticksize*1000;
else
pips =ticksize;
//---
moving=iMA(_Symbol,PERIOD_CURRENT,Trend,0,MODE_SMA,PRICE_CLOSE);
rsi=iRSI(_Symbol,PERIOD_CURRENT,Momentum,PRICE_MEDIAN);
adx=iADX(_Symbol,PERIOD_CURRENT,Strength);
//---
return(INIT_SUCCEEDED);
}
***int OpenOrders()
{
int BUYS=0,SELLS=0;
for(int i=0; i<PositionsTotal(); i++)
{
if(PositionSelectByTicket(passport)==false) break;
int dealtype=(int)PositionGetInteger(POSITION_TYPE); // buy or sell
// string position_symbol=PositionGetString(POSITION_SYMBOL); // chart symbol
if(Symbol()==PositionGetSymbol(i) && passport==PositionGetTicket(POSITION_TICKET))
{
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) BUYS++;
if(PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_SELL) SELLS++;
}
}
//---
if(BUYS>0) return(BUYS);
else return(SELLS);
}***
//+------------------------------------------------------------------+
void OnTick()
{
//---
MqlRates rates[3];
double movingarray[],rsiarray[],adxarray[];
CopyRates(_Symbol,PERIOD_CURRENT,1,3,rates);
CopyBuffer(rsi,0,1,3,rsiarray);
CopyBuffer(adx,0,1,3,adxarray);
ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
Spread=int(SymbolInfoInteger(_Symbol,SYMBOL_SPREAD));
StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL);
//---
if(OpenOrders()==0)
{
if(rates[0].open > moving )// CONDITION
if(rsiarray[0] > buylevel && rsiarray[1] < buylevel )//SIGNAL
{
if(TakeProfit>0) takeout=ask+TakeProfit*pips;
if(StopLoss>0) stopout=ask-StopLoss*pips;
Execute.Buy(LotSize,NULL,ask,stopout,takeout,NULL);
passport=Execute.ResultOrder();
Print("BUY Opened");
}
if(rates[0].open < moving )//CONTITION
if(rsiarray[0] < selllevel &&rsiarray[1] > selllevel )//SIGNAL
{
if(TakeProfit>0) takeout=bid+TakeProfit*pips;
if(StopLoss>0) stopout=bid-StopLoss*pips;
Execute.Sell(LotSize,NULL,bid,stopout,takeout,NULL);
passport=Execute.ResultOrder();
Print("SELL Opened");
}
}
//---
if(OpenOrders()>0)
{
int dealtype=(int)PositionGetInteger(POSITION_TYPE);
if(dealtype==POSITION_TYPE_BUY)
if(rsiarray[0] < buylevel )
{
Execute.PositionClose(passport);
passport=0;
}
else if(dealtype==POSITION_TYPE_SELL)
if(rsiarray[0] > selllevel )
{
Execute.PositionClose(passport);
passport=0;
}
}
}
I think what you really after is this:
input double LotSize =0.3;
input double Incriment =0.01;
input int StopLoss =50;
input int TakeProfit =100;
input int Trend =21;
input int Momentum =21;
input int Strength =13;
int adxlevel =34;
int buylevel =62;
int selllevel =36;
//---------------------
double pips;
#include <Trade\Trade.mqh>
CTrade Execute;
ulong StopLevel;
double ask, bid;
double takeout=0,stopout=0;
int moving,rsi,adx,Spread;
//+------------------------------------------------------------------+
int OnInit()
{
//---
double ticksize = SymbolInfoDouble(_Symbol,SYMBOL_POINT);
if(_Digits==3||_Digits==4)
pips=ticksize*1000;
else
pips =ticksize;
//---
moving=iMA(_Symbol,PERIOD_CURRENT,Trend,0,MODE_SMA,PRICE_CLOSE);
rsi=iRSI(_Symbol,PERIOD_CURRENT,Momentum,PRICE_MEDIAN);
adx=iADX(_Symbol,PERIOD_CURRENT,Strength);
//---
Execute.SetExpertMagicNumber(0xCAFE); // INCLUDED
Execute.SetAsyncMode(false); // CHANGED
return(INIT_SUCCEEDED);
}
int OpenPositions(ulong &passport)
{
int BUYS=0,SELLS=0;
for(int i=0; i<PositionsTotal(); i++)
{
ulong ticket=PositionGetTicket(i); // changed
if(PositionSelectByTicket(ticket)==false) break;
int dealtype=(int)PositionGetInteger(POSITION_TYPE); // buy or sell
// string position_symbol=PositionGetString(POSITION_SYMBOL); // chart symbol
if(Symbol()==PositionGetSymbol(i) && 0xCAFE==PositionGetInteger(POSITION_MAGIC)) // CHANGED
{
passport = ticket; // CHANGED
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) BUYS++;
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL) SELLS++; // CHANGED
}
}
//---
if(BUYS>0) return(BUYS);
else return(SELLS);
}
//+------------------------------------------------------------------+
void OnTick()
{
//---
MqlRates rates[3];
double movingarray[],rsiarray[],adxarray[];
CopyRates(_Symbol,PERIOD_CURRENT,1,3,rates);
CopyBuffer(rsi,0,1,3,rsiarray);
CopyBuffer(adx,0,1,3,adxarray);
ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
Spread=int(SymbolInfoInteger(_Symbol,SYMBOL_SPREAD));
StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL);
//---
ulong passport = 0; // CHANGED
int positions = OpenPositions(passport); // CHANGED
if(positions==0) // CHANGED
{
if(rates[0].open > moving )// CONDITION
if(rsiarray[0] > buylevel && rsiarray[1] < buylevel )//SIGNAL
{
if(TakeProfit>0) takeout=ask+TakeProfit*pips;
if(StopLoss>0) stopout=ask-StopLoss*pips;
Execute.Buy(LotSize,NULL,ask,stopout,takeout,NULL);
Print("BUY Opened");
}
if(rates[0].open < moving )//CONTITION
if(rsiarray[0] < selllevel &&rsiarray[1] > selllevel )//SIGNAL
{
if(TakeProfit>0) takeout=bid+TakeProfit*pips;
if(StopLoss>0) stopout=bid-StopLoss*pips;
Execute.Sell(LotSize,NULL,bid,stopout,takeout,NULL);
passport=Execute.ResultDeal(); // CHANGED
Print("SELL Opened");
}
}
else if(positions>0) // CHANGED to prevent on the same tick do both
{
int dealtype=(int)PositionGetInteger(POSITION_TYPE);
if(dealtype==POSITION_TYPE_BUY)
if(rsiarray[0] < buylevel )
{
Execute.PositionClose(passport);
}
else if(dealtype==POSITION_TYPE_SELL)
if(rsiarray[0] > selllevel )
{
Execute.PositionClose(passport);
}
}
}
I dont tested the changes. And it should be fine most part of time. It will only have problems when having delay to execute the Buy/Sell stuff.

minimize/maximize a chart window in MQL5

I found a very useful 'indicator' for MT4 that lets you maximize/minimize any chart by double/triple-clicking on it.
I've been trying to port it to MT5 unsuccessfully.
I am not sure what I am doing wrong with the Windows API.
I did change the types to ulong/uint as per MSDN.
I am also using CHART_WINDOW_HANDLE to get the hwnd.
The mouse clicking counter seems to work but I never managed to maximize or minimize a chart window with the below code.
Any help would be greatly appreciated.
//+------------------------------------------------------------------+
//| ClickMax.mq5 |
//| Copyright © 2020 | 2016, MaryJane |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020 | 2016, MaryJane"
#property link "https://www.mql5.com"
#property version "1.00"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots 0
#property strict
input uint clickDelay = 300;
input bool tripleClick = true;
#define SW_MAXIMIZE 3
#define SW_RESTORE 9
//+------------------------------------------------------------------------------------------------------------------------------------------------------+
// --- DLLs
#import "user32.dll"
ulong GetParent(ulong hWnd);
ulong GetWindow(ulong hWnd, uint uCmd);
bool ShowWindow(ulong hWnd, int nCmdShow);
bool IsZoomed(ulong hWnd);
#import
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
if(!TerminalInfoInteger(TERMINAL_DLLS_ALLOWED))
{
Alert("You have to allow DLLs for ClickMax to work");
return(INIT_FAILED);
}
else
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double &price[])
{
return(0);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
static uint clicktime = GetTickCount();
static int clickcount = 0;
bool doubleclick = false;
if(_IsX64)
{
ulong hwnd = GetParent(CHART_WINDOW_HANDLE);
//ulong hwnd = CHART_WINDOW_HANDLE;
if(id == CHARTEVENT_CLICK)
{
uint test = GetTickCount() - clicktime;
if(GetTickCount() - clicktime < clickDelay)
clickcount++;
else
clickcount = 0;
if((tripleClick && clickcount==2) ||
(!tripleClick && clickcount==1))
doubleclick = true;
clicktime = GetTickCount();
if(doubleclick)
{
if(!IsZoomed(hwnd))
ShowWindow(hwnd, SW_MAXIMIZE);
else
ShowWindow(hwnd, SW_RESTORE);
clickcount = 0;
}
}
}
}
as hinted by #dxiv in the comments, CHART_WINDOW_HANDLE is not an actual HWND.
This is: (int)ChartGetInteger(0,CHART_WINDOW_HANDLE)

Converting mql4 EA to mql5

I have been trying to figure out how to change my MQL4 code to MQL5. So far I've been able to change the RSI and MACD conditions and SendOrder() but there's a lot, like the ModifyOrder() and CloseOrder() amongst other stuff that I've not been able to do to complete it. I know this is a mouthful but I would really appreciate some help in completing this.
This is the original MQL4 code:
extern int MagicNumber=112223;
extern double Lots =0.005;
extern double StopLoss=0;
extern double TakeProfit=0;
extern int TrailingStop=0;
extern int Slippage=3;
int mode_main = 0;
int mode_signal = 1;
//+------------------------------------------------------------------+
// expert start function
//+------------------------------------------------------------------+
int start()
{
double MyPoint=_Point;
if(Digits==3 || Digits==5) MyPoint=Point*10;
double TheStopLoss=0;
double TheTakeProfit=0;
if( TotalOrdersCount()==0 )
{
int result=0;
if((iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,mode_signal,0)<iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,mode_main,0))&&(iRSI(NULL,PERIOD_M5,2,PRICE_CLOSE,0)>84)) // Here is your open buy rule
{
result=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,0,0,"EA",MagicNumber,0,Blue);
if(result>0)
{
TheStopLoss=0;
TheTakeProfit=0;
if(TakeProfit>0) TheTakeProfit=Ask+TakeProfit*MyPoint;
if(StopLoss>0) TheStopLoss=Ask-StopLoss*MyPoint;
OrderSelect(result,SELECT_BY_TICKET);
OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(TheStopLoss,Digits),NormalizeDouble(TheTakeProfit,Digits),0,Green);
}
return(0);
}
if((iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,mode_main,0)<iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,mode_signal,0))&&(iRSI(NULL,PERIOD_M5,2,PRICE_CLOSE,0)<16)) // Here is your open Sell rule
{
result=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,0,0,"EA",MagicNumber,0,Red);
if(result>0)
{
TheStopLoss=0;
TheTakeProfit=0;
if(TakeProfit>0) TheTakeProfit=Bid-TakeProfit*MyPoint;
if(StopLoss>0) TheStopLoss=Bid+StopLoss*MyPoint;
OrderSelect(result,SELECT_BY_TICKET);
OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(TheStopLoss,Digits),NormalizeDouble(TheTakeProfit,Digits),0,Green);
}
return(0);
}
}
for(int cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL &&
OrderSymbol()==Symbol() &&
OrderMagicNumber()==MagicNumber
)
{
if(OrderType()==OP_BUY)
{
if((iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,mode_signal,0)>iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,mode_main,0))&&(iRSI(NULL,PERIOD_M5,2,PRICE_OPEN,0)<16)) //here is your close buy rule
{
OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage,Red);
}
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>MyPoint*TrailingStop)
{
if(OrderStopLoss()<Bid-MyPoint*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop*MyPoint,OrderTakeProfit(),0,Green);
return(0);
}
}
}
}
else
{
if((iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,mode_main,0)>iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,mode_signal,0))&&(iRSI(NULL,PERIOD_M5,2,PRICE_OPEN,0)>84)) // here is your close sell rule
{
OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage,Red);
}
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>(MyPoint*TrailingStop))
{
if((OrderStopLoss()>(Ask+MyPoint*TrailingStop)) || (OrderStopLoss()==0))
{
OrderModify(OrderTicket(),OrderOpenPrice(),Ask+MyPoint*TrailingStop,OrderTakeProfit(),0,Red);
return(0);
}
}
}
}
}
}
return(0);
}
int TotalOrdersCount()
{
int result=0;
for(int i=0;i<OrdersTotal();i++)
{
OrderSelect(i,SELECT_BY_POS ,MODE_TRADES);
if (OrderMagicNumber()==MagicNumber) result++;
}
return (result);
}
Here is what I've done so far (MQL5):
#include <indicators/indicators.mqh>
CIndicators g_indicators;
CiRSI *g_rsi;
CiMACD *g_macd;
input int MagicNumber=112223;
input double Lots =0.005;
input double StopLoss=0;
input double TakeProfit=0;
input int TrailingStop=0;
input int Slippage=3;
int OnInit() {
g_rsi = new CiRSI();
g_indicators.Add(g_rsi);
g_macd = new CiMACD();
g_indicators.Add(g_macd);
bool is_init = g_rsi.Create(_Symbol, PERIOD_M5, 2, PRICE_CLOSE);
is_init &= g_macd.Create(_Symbol, PERIOD_M5, 12, 26, 9, PRICE_CLOSE);
return is_init ? INIT_SUCCEEDED : INIT_FAILED;
}
void OnTick() {
g_indicators.Refresh();
double MyPoint=_Point;
if(_Digits==3 || _Digits==5) MyPoint=_Point*10;
double TheStopLoss=0;
double TheTakeProfit=0;
if( TotalOrdersCount()==0 )
{
int result=0;
if (g_macd.Main(0) > g_macd.Signal(0) && g_rsi.Main(0) > 84) { // Here is your open Buy rule
Print("Signal!");
MqlTradeRequest request;
MqlTradeResult result;
MqlTradeCheckResult check;
ZeroMemory(request);
ZeroMemory(result);
ZeroMemory(check);
double Ask = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits); // Get the Ask Price
//--- parameters of request
request.action =TRADE_ACTION_PENDING; // type of trade operation
request.symbol =Symbol(); // symbol
request.volume =Lots; // volume of 0.005 lot
request.type =ORDER_TYPE_BUY; // order type
request.price = Ask; // price for opening
request.deviation=0; // allowed deviation from the price
request.magic =magicnumber; // MagicNumber of the order
request.tp = 0;
request.sl = 0;
request.type_filling=ORDER_FILLING_RETURN;
request.type_time=0;
request.expiration=0;
ObjectSetString(0,name,OBJPROP_TEXT,string(result.order));
if(!OrderSend(request,result))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",result.retcode);
}
}
}
if (g_macd.Main(0) < g_macd.Signal(0) && g_rsi.Main(0) < 16) { // Here is your open Sell rule
Print("Signal!");
MqlTradeRequest request;
MqlTradeResult result;
MqlTradeCheckResult check;
ZeroMemory(request);
ZeroMemory(result);
ZeroMemory(check);
double Bid = NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits); // Get the Bid Price
//--- parameters of request
request.action =TRADE_ACTION_PENDING; // type of trade operation
request.symbol =Symbol(); // symbol
request.volume =Lots; // volume of 0.005 lot
request.type =ORDER_TYPE_SELL; // order type
request.price = Bid; // price for opening
request.deviation=0; // allowed deviation from the price
request.magic =magicnumber; // MagicNumber of the order
request.tp = 0;
request.sl = 0;
request.type_filling=ORDER_FILLING_RETURN;
request.type_time=0;
request.expiration=0;
ObjectSetString(0,name,OBJPROP_TEXT,string(result.order));
if(!OrderSend(request,result))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",result.retcode);
}
}
}
}
}
Thanks in advance.
Yes, it may take long. luckily, someone wrote a library that you are welcome to download from https://www.mql5.com/ru/code/16006.
#include <MT4Orders.mqh> // if you have #include <Trade/Trade.mqh> in your MQL5 files, include this one AFTER.
int ticket = OrderSend(...);
same for `OrderModify()` and `OrderDelete` \ `OrderModify`
Keep in mind that this lib works for hedging mode only, so your MT5 must have a hedging mode.
full example below:
#include <MT45/MT4Orders.mqh>
//better to use MQL5 analogues of Ask etc for both MQL4 and MQL5, or redefine them
#define Ask SymbolInfoDouble(_Symbol,SYMBOL_ASK)
#define Bid SymbolInfoDouble(_Symbol,SYMBOL_BID)
#define Point _Point
#define Digits _Digits
// your inputs
extern int MagicNumber=112223;
extern double Lots =0.005;
extern double StopLoss=0;
extern double TakeProfit=0;
extern int TrailingStop=0;
extern int Slippage=3;
//int mode_main = 0; //probably throw this away
//int mode_signal = 1; //probably throw this away
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//initialize your indicators here
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//deinitialize your indicators here if you need to avoid memory leak
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
double MyPoint=_Point;
if(Digits==3 || Digits==5) MyPoint=Point*10;
double TheStopLoss=0;
double TheTakeProfit=0;
if( TotalOrdersCount()==0 )
{
TICKET_TYPE result=0;
if(isRule4Buy()) // Here is your open buy rule
{
result=OrderSend(Symbol(),OP_BUY,Lots,SymbolInfoDouble(_Symbol,SYMBOL_ASK),Slippage,0,0,"EA",MagicNumber,0,clrBlue);
if(result>0)
{
TheStopLoss=0;
TheTakeProfit=0;
if(TakeProfit>0) TheTakeProfit=Ask+TakeProfit*MyPoint;
if(StopLoss>0) TheStopLoss=Ask-StopLoss*MyPoint;
OrderSelect(result,SELECT_BY_TICKET);
OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(TheStopLoss,Digits),NormalizeDouble(TheTakeProfit,Digits),0,Green);
}
return;
}
if(isRule4Sell())
{
//simply copy the sell block
}
}
for(int cnt=0;cnt<OrdersTotal();cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL &&
OrderSymbol()==Symbol() &&
OrderMagicNumber()==MagicNumber
)
{
if(OrderType()==OP_BUY)
{
if(isRule4Sell())
{
OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage,Red);
}
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>MyPoint*TrailingStop)
{
if(OrderStopLoss()<Bid-MyPoint*TrailingStop)
{
OrderModify(OrderTicket(),OrderOpenPrice(),Bid-TrailingStop*MyPoint,OrderTakeProfit(),0,Green);
return;
}
}
}
}
else
{
//simply copy the sell block
}
}
}
}
//+------------------------------------------------------------------+
int TotalOrdersCount()
{
int result=0;
for(int i=0;i<OrdersTotal();i++)
{
OrderSelect(i,SELECT_BY_POS ,MODE_TRADES);
if (OrderMagicNumber()==MagicNumber) result++;
}
return (result);
}
//+------------------------------------------------------------------+
bool isRule4Buy()
{
#ifdef __MQL4__
return iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0)<iMACD(NULL,PERIOD_M5,12,26,9,PRICE_CLOSE,MODE_MAIN,0)
&& iRSI(NULL,PERIOD_M5,2,PRICE_CLOSE,0)>84;
#else
return true;
//replace with MT5
//g_macd.Main(0) > g_macd.Signal(0) && g_rsi.Main(0) > 84
#endif
}
bool isRule4Sell()
{
//similar for sell
return false;
}

gcc memory overlap between global variables and class members

I've been finally able to add the portion of code to explain my question ...
I've recently upgraded my development PC and with it gcc from 4.1 to 4.8.
Compiling the same source I'm experiencing now a var overlap issue.
I can't post the entire cource since it is huge but just for understand I have some variables defined before the main() that are defined as extern on outside class so that can be accessed.
Someone of theese global variables change their value unexpectedly and debugging this with gdb I can see that this variable is sharing the same memory address as one member of a class instance.
This is the definition of variables on main.cpp the variable loopcounter is the only one I really need, I've surrounded it with unused variables in order to better understand this overlap.
uint64_t loopcounterx = 0;
uint64_t loopcounterxx = 0;
uint64_t loopcounterxxx = 0;
uint64_t loopcounterxxxx = 0;
uint64_t loopcounterxxxxx = 0;
uint64_t loopcounterxxxxxx = 0;
uint64_t loopcounter = 0;
uint64_t loopcountery = 0;
uint64_t loopcounteryy = 0;
uint64_t loopcounteryyy = 0;
uint64_t loopcounteryyyy = 0;
uint64_t loopcounteryyyyy = 0;
uint64_t loopcounteryyyyyy = 0;
uint64_t loopcounteryyyyyyy = 0;
.
.
.
int main(int argc, char *argv[]) {
I've set a watchdog for this variable write access with gdb
watch loopcounter
when the program execution stops I can see that we are inside an instance of the class Timer
Hardware watchpoint 1: loopcounter
Old value = 541
New value = 66077
Timer::signal (this=0xc235b0 (loopcounteryyy), s=true) at chrono.cpp:229
this is the portion of chrono.cpp
bool Timer::signal (bool s) {
if ((s != in_signal_old) && !r_pulse) {
in_signal = s;
if (s) in_signal_fp=true;
else in_signal_rp=true;
in_signal_old = s;
}
}
the watchdog stops the execution at line 229 of chrono.cpp which contains
if (s) in_signal_fp=true;
at the time of stop, the memory violation has already happened, so I think we must consider the line before, that is
in_signal = s;
where the code is accessing a member of it's class and it really seems that the writeing of this member will damage the content of loopcounter variable.
In fact, looking to pointers I get this
(gdb) p &loopcounter
$1 = (uint64_t *) 0xc235c8 (loopcounter)
(gdb) p &in_signal
$2 = (uint64_t *) 0xc235ca (loopcounter + 2)
(gdb) p &in_signal_fp
$5 = (bool *) 0xc235cc (loopcounter+4)
(gdb) p &active_f
$7 = (bool *) 0xc235c8 (loopcounter)
active_f is another member of the chrono class and it is perfectly overlapping the loopcounter variable.
this is the Timer class contained in chrono.h header
class Timer {
private:
Timer *me;
Timer *prev;
Timer *next;
bool active_f;
bool running_f;
bool in_signal;
bool in_signal_old;
bool in_signal_fp;
bool in_signal_rp;
bool out_signal;
bool out_signal_old;
bool out_signal_fp;
bool out_signal_rp;
bool f_pulse;
bool r_pulse;
uint64_t start;
uint64_t end;
uint64_t lenght;
timer_type type;
public:
int init (int lenght);
bool out (void);
bool active () { return active_f; }
bool fp () { return f_pulse; }
bool rp () { return r_pulse; }
bool running () { return running_f; }
void set_next (Timer *n) { next = n; }
void set_prev (Timer *p) { prev = p; }
void set_end (RTIME x) { end = x; }
void set_active (bool x) { active_f = x; }
void set_running (bool x) { running_f = x; }
void set_lenght (RTIME x) { lenght = x; }
void set_start (RTIME x) { start = x; }
void set_type (timer_type x) { type = x; }
void set_timer (RTIME x, timer_type y);// { lenght = x; type = y; }
bool signal (bool);
void set_fp (bool x) { f_pulse = x; }
void set_rp (bool x) { r_pulse = x; }
Timer * get_next () { return next; }
Timer * get_prev () { return prev; }
RTIME get_end () { return end; }
RTIME get_start () { return start; }
RTIME get_lenght (void) { return lenght; }
void append (Timer *newt);
Timer();
};
Why the compiler/linker or I don't know who else, is allocating two different objects on the same memory area ?
I've also used valgrind and the -fsanitize=address option introduced in gcc-4.8 but I can't get more useful informations or something more where to work on.
In which other way can I investigate over this behaviour ?

Resources