You really should be using the CChartObject classes instead of interacting via the direct API functions. also you should not be tracking the last alert time in the name of the object… I hope this isn’t offensive, but that’s just lazy coding.
#include <ChartObjects\ChartObjectsLines.mqh>
#include <Arrays\ArrayObj.mqh>
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class MyTrend : public CChartObjectTrend
{
datetime m_last_alert;
public:
datetime LastAlert() const { return m_last_alert;}
void LastAlert(datetime time){ m_last_alert = time;}
double CurrentPrice() const { return ObjectGetValueByTime(m_chart_id,m_name,TimeCurrent());}
void Alert(datetime bar_time)
{
m_last_alert = bar_time;
::Alert("Trendline ["+m_name+"] has been crossed!");
}
bool Attach(string sparam)
{
bool res = Attach(ChartID(),sparam,0,2);
res = RayRight(true);
res = Description(string(0.0));
return res;
}
void OnTick() { Description(DoubleToString(CurrentPrice(),_Digits));}
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class TrendList : public CArrayObj
{
double m_last_tick;
double m_tick;
public:
TrendList():m_tick(0.0){}
MyTrend* operator[](int i)const{return At(i);}
void OnTick(double price,datetime bar_time)
{
for(int i=Total()-1;i>=0;i--)
{
this[i].OnTick();
m_last_tick=m_tick;
m_tick = price;
if(m_last_tick != 0.0 && this[i].LastAlert()!= bar_time)
{
double trend_price = this[i].CurrentPrice();
if((m_last_tick>trend_price&&trend_price>=m_tick)||(m_last_tick<trend_price&&trend_price<=m_tick))
this[i].Alert(bar_time);
}
}
}
bool OnCreate(string sparam)
{
for(int i=Total()-1;i>=0;i--)
if(this[i].Name()==sparam)
return true;
MyTrend *trend = new MyTrend;
trend.Attach(sparam);
return Add(trend);
}
bool OnDelete(string sparam)
{
for(int i=Total()-1;i>=0;i--)
if(this[i].Name()==sparam)
return Delete(i);
return false;
}
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
TrendList trend_list;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
ChartSetInteger(0,CHART_EVENT_OBJECT_CREATE,true);
ChartSetInteger(0,CHART_EVENT_OBJECT_DELETE,true);
ChartSetInteger(0,CHART_SHOW_OBJECT_DESCR,true);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
trend_list.OnTick(close[rates_total-1],time[rates_total-1]);
return(rates_total);
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
if(id==CHARTEVENT_OBJECT_CREATE && ObjectGetInteger(0,sparam,OBJPROP_TYPE)==OBJ_TREND)
if(trend_list.OnCreate(sparam))
Alert("ADDED");
if(id==CHARTEVENT_OBJECT_DELETE)
if(trend_list.OnDelete(sparam))
Alert("DELETED");
}
//+------------------------------------------------------------------+