//+---------------------------------------------------------------------+ //| TradeStatisticsPanel.mqh | //| jafferwilson | //| https://www.mql5.com/en/users/jafferwilson | //+---------------------------------------------------------------------+ #property copyright "jafferwilson" #property link "https://www.mql5.com/en/users/jafferwilson" //+------------------------------------------------------------------+ //| Include | //+------------------------------------------------------------------+ #include #include #include #include //+------------------------------------------------------------------+ //| Defines | //+------------------------------------------------------------------+ #define INDENT_LEFT 15 // left offset #define INDENT_TOP 30 // top offset #define BUTTON_HEIGHT 19 #define BUTTON_WIDTH 120 #define BUTTON_OFFSET 70 // right offset button #define VALUE_TEXT_LEN 16 // max len text(value) #define VALUE_ROWS 15 // max rows (value) //+------------------------------------------------------------------+ //| Rarameters for create panel | //+------------------------------------------------------------------+ struct Params { long chart; int subwin; string name; //--- int x1; int y1; int x2; int y2; //--- string font_name; int font_size; color font_color; }; //+------------------------------------------------------------------+ //| Class CPanelDialog | //+------------------------------------------------------------------+ class CPanelDialog : public CAppDialog { private: CLabel m_label[3][20]; CLabel m_value[3][20]; CButton m_button[1]; string FontName; int FontSize; color FontColor; int FontHeight; public: virtual bool Create(Params &p); void SetLabelParam(int index,int col,string text); string GetButtonName(int index){if(index>0)index=0; return(m_button[index].Name());} protected: virtual bool OnResize(void); //--- create dependent controls bool CreateButton(int index,bool only_move=false); bool CreateLabel(int index,int col,int index,bool only_move=false); string ParamCaption(int index); }; //+------------------------------------------------------------------+ //| Create | //+------------------------------------------------------------------+ bool CPanelDialog::Create(Params &p) { if(!CAppDialog::Create(p.chart,p.name,p.subwin,p.x1,p.y1,p.x2,p.y2)) return(false); FontName=p.font_name; FontSize=p.font_size; FontColor=p.font_color; FontHeight=FontSize*2; //--- Caption(p.name); //--- create controls if(!CreateButton(0)) return(false); //--- col#1 if(!CreateLabel(0,0,STAT_INITIAL_DEPOSIT))return(false); if(!CreateLabel(1,0,STAT_PROFIT))return(false); if(!CreateLabel(2,0,STAT_GROSS_PROFIT))return(false); if(!CreateLabel(3,0,STAT_GROSS_LOSS))return(false); if(!CreateLabel(4,0,STAT_PROFIT_FACTOR))return(false); if(!CreateLabel(5,0,STAT_RECOVERY_FACTOR))return(false); if(!CreateLabel(6,0,STAT_AHPR))return(false); if(!CreateLabel(7,0,STAT_GHPR))return(false); if(!CreateLabel(8,0,STAT_Z_SCORE))return(false); if(!CreateLabel(10,0,STAT_TRADES))return(false); if(!CreateLabel(11,0,STAT_DEALS))return(false); //---col#2 if(!CreateLabel(0,1,STAT_EXPECTED_PAYOFF))return(false); if(!CreateLabel(1,1,STAT_SHARPE_RATIO))return(false); if(!CreateLabel(2,1,STAT_LR_CORRELATION))return(false); if(!CreateLabel(3,1,STAT_LR_STANDARD_ERROR))return(false); if(!CreateLabel(5,1,STAT_SHORT_TRADES))return(false); if(!CreateLabel(6,1,STAT_PROFIT_TRADES))return(false); if(!CreateLabel(7,1,STAT_MAX_PROFITTRADE))return(false); if(!CreateLabel(8,1,STAT_AVG_PROFIT_TRADE))return(false); if(!CreateLabel(9,1,STAT_MAX_CONWINS))return(false); if(!CreateLabel(10,1,STAT_CONPROFITMAX))return(false); if(!CreateLabel(11,1,STAT_PROFITTRADES_AVGCON))return(false); //--- col#3 if(!CreateLabel(1,2,STAT_BALANCE_DD_ABSOLUTE))return(false); if(!CreateLabel(2,2,STAT_BALANCE_DD))return(false); if(!CreateLabel(3,2,STAT_BALANCE_DD_RELATIVE))return(false); if(!CreateLabel(5,2,STAT_LONG_TRADES))return(false); if(!CreateLabel(6,2,STAT_LOSS_TRADES))return(false); if(!CreateLabel(7,2,STAT_MAX_LOSSTRADE))return(false); if(!CreateLabel(8,2,STAT_AVG_LOSS_TRADE))return(false); if(!CreateLabel(9,2,STAT_MAX_CONLOSSES))return(false); if(!CreateLabel(10,2,STAT_CONLOSSMAX))return(false); if(!CreateLabel(11,2,STAT_LOSSTRADES_AVGCON))return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| ParamCaption | //+------------------------------------------------------------------+ string CPanelDialog::ParamCaption(int index) { switch(index) { case STAT_INITIAL_DEPOSIT: return("Initial Deposit"); case STAT_PROFIT: return("Total Net Profit"); case STAT_BALANCE: return("Balance"); case STAT_EQUITY: return("Equity"); case STAT_GROSS_PROFIT: return("Gross Profit"); case STAT_GROSS_LOSS: return("Gross Loss"); case STAT_PROFIT_FACTOR: return("Profit Factor"); case STAT_RECOVERY_FACTOR: return("Recovery Factor"); case STAT_EXPECTED_PAYOFF: return("Expected Payoff"); case STAT_BALANCE_DD_ABSOLUTE: return("Balance Dr. Abs."); case STAT_BALANCE_DD: return("Balance Dr. Max."); case STAT_BALANCE_DD_RELATIVE: return("Balance Dr. Rel."); case STAT_TRADES: return("Total Trades"); case STAT_DEALS: return("Total Deals"); case STAT_SHORT_TRADES: return("Short Trades"); case STAT_LONG_TRADES: return("Long Trades"); case STAT_PROFIT_TRADES: return("Profit Trades"); case STAT_LOSS_TRADES: return("Loss Trades"); //--- case STAT_MAX_PROFITTRADE: return("Largest Profit Trade"); case STAT_MAX_LOSSTRADE: return("Largest Loss Trade"); case STAT_CONPROFITMAX: return("Max. Cons. Profit"); case STAT_MAX_CONWINS: return("Max. Cons. Wins"); case STAT_CONLOSSMAX: return("Max. Cons. Loss"); case STAT_MAX_CONLOSSES: return("Max. Cons. Losses"); case STAT_AVG_PROFIT_TRADE: return("Avg. Profit Trade"); case STAT_AVG_LOSS_TRADE: return("Avg. Loss Trade"); case STAT_PROFITTRADES_AVGCON: return("Avg. Cons. Wins"); case STAT_LOSSTRADES_AVGCON: return("Avg. Cons. Losses"); case STAT_GHPR: return("GHPR"); case STAT_AHPR: return("AHPR"); case STAT_SHARPE_RATIO: return("Sharpe Ratio"); case STAT_Z_SCORE: return("Z Score"); case STAT_LR_CORRELATION: return("LR Correlation"); case STAT_LR_STANDARD_ERROR: return("LR Standard Error"); default: return("---"); } } //+------------------------------------------------------------------+ //| OnResize | //+------------------------------------------------------------------+ bool CPanelDialog::OnResize(void) { //--- call method of parent class if(!CAppDialog::OnResize()) return(false); //--- move button CreateButton(0,true); //--- move labels for(int c=0;c<=2;c++) for(int i=0;i<=11;i++) CreateLabel(i,c,0,true); //--- succeed return(true); } //+------------------------------------------------------------------+ //| CreateLabel | //+------------------------------------------------------------------+ bool CPanelDialog::CreateLabel(int i,int col,int name,bool only_move=false) { int delta=Height()-ClientAreaHeight(); //--- range check int range1=(int)MathMin(ArrayRange(m_label,0),ArrayRange(m_value,0)); if(col>=range1)col=range1-1; int range2=(int)MathMin(ArrayRange(m_label,1),ArrayRange(m_value,1)); if(i>=range2)i=range2-1; int width_3=ClientAreaWidth()/3; int x1,y1,x2,y2; int x11,y11,x22,y22; //--- coords switch(col) { case 1://col#2 //--- x1 = INDENT_LEFT + width_3; y1 = INDENT_TOP + FontHeight*i; x2 = x1; y2 = y1 + FontHeight; //--- x11 = (int)(width_3*1.5); y11 = INDENT_TOP + FontHeight*i; x22 = x11; y22 = y1 + FontHeight; break; case 2://col#3 //--- x1 = INDENT_LEFT + width_3*2; y1 = INDENT_TOP + FontHeight*i; x2 = x1; y2 = y1 + FontHeight; //--- x11 = (int)(width_3*2.5); y11 = INDENT_TOP + FontHeight*i; x22 = x11; y22 = y1 + FontHeight; break; default://col#1 //--- x1 = INDENT_LEFT; y1 = INDENT_TOP + FontHeight*i; x2 = x1; y2 = y1 + FontHeight; //--- x11 = width_3/2; y11 = INDENT_TOP + FontHeight*i; x22 = x11; y22 = y11 + FontHeight; break; } if(only_move) { m_label[col][i].Move(x1,y1); m_value[col][i].Move(x11,y11); return(true); } //--- create label if(!m_label[col][i].Create(m_chart_id,m_name+"Label_"+IntegerToString(i)+"_"+IntegerToString(col),m_subwin,x1,y1-delta,x2,y2-delta)) return(false); if(!Add(m_label[col][i])) return(false); m_label[col][i].Text(ParamCaption(name)); m_label[col][i].Font(FontName); m_label[col][i].FontSize(FontSize); m_label[col][i].Color(FontColor); //--- create value if(!m_value[col][i].Create(m_chart_id,m_name+"Value_"+IntegerToString(i)+"_"+IntegerToString(col),m_subwin,x11,y11-delta,x22,y22-delta)) return(false); if(!Add(m_value[col][i])) return(false); m_value[col][i].Font(FontName); m_value[col][i].FontSize(FontSize); m_value[col][i].Color(FontColor); m_value[col][i].Text(""); //--- succeed return(true); } //+------------------------------------------------------------------+ //| CreateButton | //+------------------------------------------------------------------+ bool CPanelDialog::CreateButton(int index,bool only_move=false) { int delta=Height()-ClientAreaHeight(); int x1=0,y1=0,x2=0,y2=0; string caption; switch(index) { case 0://--- Calculate x1=ClientAreaWidth()-BUTTON_WIDTH-BUTTON_OFFSET; y1=-delta+3; caption="Calculate"; break; } if(only_move) return(m_button[index].Move(x1,1)); //--- ðàçìåðû x2 = x1 + BUTTON_WIDTH; y2 = y1 + BUTTON_HEIGHT; //--- create if(!m_button[index].Create(m_chart_id,m_name+"Button_"+IntegerToString(index),m_subwin,x1,y1,x2,y2)) return(false); m_button[index].FontSize(8); //m_button[index].Font(FontName); m_button[index].Text(caption); if(!Add(m_button[index])) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| SetLabelParam | //+------------------------------------------------------------------+ void CPanelDialog::SetLabelParam(int i,int col,string text) { //--- check range int range1=ArrayRange(m_value,0); if(col>=range1)col=range1-1; int range2=ArrayRange(m_value,1); if(i>=range2)i=range2-1; //--- fill spaces for line format int text_length=StringLen(text); if(text_length