#property copyright "© RickD 2005-2006"
#property link      "www.e2e-fx.net"
#property show_inputs
//-----
#define template    "[ROOT]\\templates\\report.htm"
#define report      "[ROOT]\\experts\\files\\[ACCOUNT_NUM]rep.htm"
//-----
#import "shell32.dll"
  int ShellExecuteA(int hWnd, int lpVerb, string lpFile, int lpParameters, string lpDirectory, int nCmdShow);
#import "kernel32.dll"
  int GetModuleFileNameA(int hModule, int& buf[], int len);
  int _lcreat(string path, int attr);
  int _lopen(string path, int mode);
  int _lclose(int hFile);  
  int _llseek(int hFile, int offset, int origin);   
  int _lread(int hFile, int buf[], int len);
  int _lwrite(int hFile, string buf, int len);
#import
#define OF_READ             0x00000000
#define OF_WRITE            0x00000001
#define OF_READWRITE        0x00000002
#define HFILE_ERROR         0xFFFFFFFF
#define FILE_BEGIN          0
#define FILE_CURRENT        1
#define FILE_END            2
#define SW_SHOW             5
#define OP_BALANCE          6
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void init() {
}
void deinit(){
}
void start() {
  int ts1 = GetTickCount();
  string root;
  int res = GetRoot(root);
  if (res == FALSE) return;
  //-----
  string html;
  res = GetTemplate(root, html);
  if (res == FALSE) return;
  
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Validate & Sort
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  int Tickets[];
  int ticket = -1;
  int ind = 0;
  int cnt = HistoryTotal();
  ArrayResize(Tickets, cnt);
  
  for (int i=0; i<cnt; i++) {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;
    ticket = OrderTicket();
    if (Validate(ticket)) {
      Tickets[ind] = ticket;
      ind++;
    }
  }
  
  ArrayResize(Tickets, ind);
  Sort(Tickets);
  
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Head
//------------------------------------------------------------------------------------
  html = str_replace(html, "<!--COMPANY-->", CompanyName());
  html = str_replace(html, "<!--ACC_NUMBER-->", AccountNumber());
  html = str_replace(html, "<!--ACC_NAME-->", AccountName());
  html = str_replace(html, "<!--CURRENCY-->", AccountCurrency());
  html = str_replace(html, "<!--LOCAL_TIME-->", time_format(LocalTime(), "d mon yyyy hh:mm"));
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Body
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  
  string row_tpl = str_substr(html, "<!--CLOSED_POSITIONS[-->", "<!--]CLOSED_POSITIONS-->");
  string section = "<!--CLOSED_POSITIONS[-->" + row_tpl + "<!--]CLOSED_POSITIONS-->";
  
  row_tpl = StringTrimLeft(row_tpl);
  row_tpl = StringTrimRight(row_tpl);
  
  //-----
    
  double depo = 0;
  double comm = 0;
  double swap = 0;
  double profit = 0;
  double initial_deposit = 0;
  
  double gross_profit = 0;
  double gross_loss = 0;
  
  double min_account_balance = 0;
  double max_account_balance = 0;
  double max_dd = 0;
  double max_dd_rel = 0;
  
  int trades_total = 0;
  int trades_short = 0;
  int trades_long = 0;
  int trades_profit = 0;
  int trades_loss = 0;
  
  int ticket0 = -1;
  double largest_profit_trade = 0;
  double largest_loss_trade = 0;
  double avg_profit_trade = 0;
  double avg_loss_trade = 0;
  
  int consecutive_wins_cnt = 0;
  int consecutive_losses_cnt = 0;
  double consecutive_wins_summ = 0;
  double consecutive_losses_summ = 0;
  int max_consecutive_wins_cnt = 0;
  int max_consecutive_losses_cnt = 0;
  double max_consecutive_wins_summ = 0;
  double max_consecutive_losses_summ = 0;
  
  double consecutive_profit_summ = 0;
  double consecutive_loss_summ = 0;
  int consecutive_profit_cnt = 0;
  int consecutive_loss_cnt = 0;
  double max_consecutive_profit_summ = 0;
  double max_consecutive_loss_summ = 0;
  int max_consecutive_profit_cnt = 0;
  int max_consecutive_loss_cnt = 0;
  string row = "";
  string rows[];
  int size = -1;
 
  cnt = ArraySize(Tickets);
  for (i=0; i<cnt; i++) {
    if (!OrderSelect(Tickets[i], SELECT_BY_TICKET, MODE_HISTORY)) continue;
    
    int dig = MarketInfo(OrderSymbol(), MODE_DIGITS);
    if (dig == 0) dig = 4;
  
    row = row_tpl;
    if (i%2 == 1) row = str_replace(row, "bgcolor=#FFFFFF", "bgcolor=#E0E0E0");
    row = str_replace(row, "<!--NUM-->", i+1);
    int type = OrderType();
    
    if (OrderType() == OP_BALANCE) {
      row = str_replace(row, "<!--TICKET-->", OrderTicket());
      row = str_replace(row, "<!--OPEN_TIME-->", TimeToStr(OrderOpenTime()));
      row = str_replace(row, "<!--TYPE-->", OrderTypeToStr(OrderType()));
      row = str_replace(row, "<!--LOTS-->", "");
      row = str_replace(row, "<!--SYMBOL-->", "");
      row = str_replace(row, "<!--OPEN_PRICE-->", "");
      row = str_replace(row, "<!--SL-->", "");
      row = str_replace(row, "<!--TP-->", "");
      row = str_replace(row, "<!--CLOSE_TIME-->", "");
      row = str_replace(row, "<!--CLOSE_PRICE-->", "");
      row = str_replace(row, "<!--COMISSION-->", "");
      row = str_replace(row, "<!--SWAP-->", "");
      row = str_replace(row, "<!--PROFIT-->", number_format(OrderProfit(), 2, ".", " "));
      row = str_replace(row, "<!--COMMENT-->", OrderComment());
      
      row = str_replace(row, "mso-number-format:#\\.##;", "mso-number-format:0\\.00;");
      
      depo += OrderProfit();
      if (i == 0 && OrderProfit() > 0) initial_deposit = OrderProfit();
    }
    else {
      bool cancelled = (type == OP_BUYSTOP || type == OP_SELLSTOP || type == OP_BUYLIMIT || type == OP_SELLLIMIT);
      row = str_replace(row, "<!--TICKET-->", OrderTicket());
      row = str_replace(row, "<!--OPEN_TIME-->", TimeToStr(OrderOpenTime()));
      row = str_replace(row, "<!--TYPE-->", OrderTypeToStr(OrderType()));
      row = str_replace(row, "<!--LOTS-->", DoubleToStr(OrderLots(), 2));
      row = str_replace(row, "<!--SYMBOL-->", OrderSymbol());
      row = str_replace(row, "<!--OPEN_PRICE-->", DoubleToStr(OrderOpenPrice(), dig));
      row = str_replace(row, "<!--SL-->", DoubleToStr(OrderStopLoss(), dig));
      row = str_replace(row, "<!--TP-->", DoubleToStr(OrderTakeProfit(), dig));
      row = str_replace(row, "<!--CLOSE_TIME-->", TimeToStr(OrderOpenTime()));
      row = str_replace(row, "<!--CLOSE_PRICE-->", DoubleToStr(OrderClosePrice(), dig));
      row = str_replace(row, "<!--COMISSION-->", number_format(OrderCommission(), 2, ".", " "));
      row = str_replace(row, "<!--SWAP-->", number_format(OrderSwap(), 2, ".", " "));
      
      if (cancelled) {
        row = str_replace(row, "<!--PROFIT-->", "");
      }
      else {
        row = str_replace(row, "<!--PROFIT-->", number_format(OrderProfit(), 2, ".", " "));
      }
      
      row = str_replace(row, "<!--COMMENT-->", OrderComment());
      
      row = str_replace(row, "mso-number-format:#\\.##;", "mso-number-format:0\\." + str_repeat('0', dig) + ";");
      //-----
      if (!cancelled) {
        comm += OrderCommission();
        swap += OrderSwap();
        profit += OrderProfit();
        
        double order_profit = OrderCommission() + OrderSwap() + OrderProfit();
        
        //-----
        
        if (order_profit > 0) gross_profit += order_profit;
        if (order_profit < 0) gross_loss += order_profit;
        
        double account_balance = gross_profit + gross_loss + depo;
        
        if (ticket0 == -1) {
          min_account_balance = account_balance;
        }
        else {
          min_account_balance = MathMin(min_account_balance, account_balance);
        }
              
        if (account_balance > max_account_balance) {
          max_account_balance = account_balance;
        }
        else {
          if (account_balance > 0 && max_account_balance - account_balance > max_dd) {
            max_dd = max_account_balance - account_balance;
            max_dd_rel = 100*max_dd/max_account_balance;
          }
        }
        
        //-----
      
        trades_total++;
        if (type == OP_BUY) trades_long++;
        if (type == OP_SELL) trades_short++;
        
        if (order_profit < 0) {
          trades_loss++;
          avg_loss_trade += order_profit;
        }
        
        if (order_profit >= 0) {
          trades_profit++;
          avg_profit_trade += order_profit;
        }
   
        if (ticket0 == -1) {
          largest_profit_trade = order_profit;
          largest_loss_trade = order_profit;
        }
        else {        
          if (order_profit > 0) {
            largest_profit_trade = MathMax(largest_profit_trade, order_profit);
          }
          
          if (order_profit < 0) {
            largest_loss_trade = MathMin(largest_loss_trade, order_profit);
          }
        }
        
        //-----
        
        if (order_profit >= 0) {
          consecutive_losses_cnt = 0;
          consecutive_losses_summ = 0;
        
          consecutive_wins_cnt++;
          consecutive_wins_summ += order_profit;
          
          if (consecutive_wins_cnt > max_consecutive_wins_cnt || 
             (consecutive_wins_cnt == max_consecutive_wins_cnt && max_consecutive_wins_summ < consecutive_wins_summ)) {
            max_consecutive_wins_cnt = consecutive_wins_cnt;
            max_consecutive_wins_summ = consecutive_wins_summ;
          }
        }
        
        if (order_profit < 0) {
          consecutive_wins_cnt = 0;
          consecutive_wins_summ = 0;
        
          consecutive_losses_cnt++;
          consecutive_losses_summ += order_profit;
          
          if (consecutive_losses_cnt > max_consecutive_losses_cnt ||
             (consecutive_losses_cnt == max_consecutive_losses_cnt && max_consecutive_losses_summ > consecutive_losses_summ)) {
            max_consecutive_losses_cnt = consecutive_losses_cnt;
            max_consecutive_losses_summ = consecutive_losses_summ;
          }
        }
        
        //-----
        
        if (order_profit >= 0) {
          consecutive_loss_summ = 0;
          consecutive_loss_cnt = 0;
          consecutive_profit_summ += order_profit;        
          consecutive_profit_cnt++;
          
          if (consecutive_profit_summ > max_consecutive_profit_summ) {
            max_consecutive_profit_summ = consecutive_profit_summ;
            max_consecutive_profit_cnt = consecutive_profit_cnt;
          }
        }
        
        if (order_profit < 0) {
          consecutive_profit_summ = 0;
          consecutive_profit_cnt = 0;
          consecutive_loss_summ += order_profit;        
          consecutive_loss_cnt++;
          
          if (consecutive_loss_summ < max_consecutive_loss_summ) {
            max_consecutive_loss_summ = consecutive_loss_summ;
            max_consecutive_loss_cnt = consecutive_loss_cnt;
          }
        }
        
        if (ticket0 == -1) ticket0 = OrderTicket();
     
      } //cancelled      
    }
    
    row = row + "\r\n";
    size = ArraySize(rows);
    ArrayResize(rows, size+1);
    rows[size] = row;
  }
 
  if (trades_profit > 0) avg_profit_trade /= trades_profit;
  if (trades_loss > 0) avg_loss_trade /= trades_loss; 
  
  
//  rows = StringTrimRight(rows);
//  html = str_replace(html, section, rows);
  //-----  
  row_tpl = str_substr(html, "<!--CLOSED_TOTAL[-->", "<!--]CLOSED_TOTAL-->");
  section = "<!--CLOSED_TOTAL[-->" + row_tpl + "<!--]CLOSED_TOTAL-->";
  
  row_tpl = StringTrimLeft(row_tpl);
  row_tpl = StringTrimRight(row_tpl);
  
  row = row_tpl;
  //if (i%2 == 1) row = str_replace(row, "bgcolor=#FFFFFF", "bgcolor=#E0E0E0");
  
  row = str_replace(row, "<!--COMISSION-->", number_format(comm, 2, ".", " "));
  row = str_replace(row, "<!--SWAP-->", number_format(swap, 2, ".", " "));
  row = str_replace(row, "<!--PROFIT-->", number_format(profit, 2, ".", " "));
  
  html = str_replace(html, section, row);
  
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Summary
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  html = str_replace(html, "<!--DEPOSIT-->", number_format(depo, 2, ".", " "));
  html = str_replace(html, "<!--CLOSED_PL-->", number_format(comm+swap+profit, 2, ".", " "));
  html = str_replace(html, "<!--BALANCE-->", number_format(depo+comm+swap+profit, 2, ".", " "));
  
  double total_net_profit = gross_profit + gross_loss;
  
  html = str_replace(html, "<!--GROSS_PROFIT-->", number_format(gross_profit, 2, ".", " "));
  html = str_replace(html, "<!--GROSS_LOSS-->", number_format(gross_loss, 2, ".", " "));
  html = str_replace(html, "<!--TOTAL_NET_PROFIT-->", number_format(total_net_profit, 2, ".", " "));
  double absolute_dd = 0;
  if (initial_deposit > 0) {
    absolute_dd = initial_deposit - min_account_balance;
    html = str_replace(html, "<!--ABSOLUTE_DRAWDOWN-->", number_format(absolute_dd, 2, ".", " "));
  }
  else {
    html = str_replace(html, "<!--ABSOLUTE_DRAWDOWN-->", "*");
  }  
  
  html = str_replace(html, "<!--MAXIMAL_DRAWDOWN-->", number_format(max_dd, 2, ".", " ") + " (" + number_format(max_dd_rel, 1, ".", " ") + "%)");
  
  double profit_factor = 0;
  if (NormalizeDouble(gross_loss, 2) != 0) {
    profit_factor = MathAbs(gross_profit/gross_loss);
    html = str_replace(html, "<!--PROFIT_FACTOR-->", number_format(profit_factor, 2, ".", " "));
  }
  else {
    html = str_replace(html, "<!--PROFIT_FACTOR-->", "*");
  }
  
  double expected_payoff = 0;
  if (trades_total > 0) expected_payoff = total_net_profit/trades_total;
  html = str_replace(html, "<!--EXPECTED_PAYOFF-->", number_format(expected_payoff, 2, ".", " "));
  double trades_short_rel = 0;
  double trades_long_rel = 0;
  double trades_profit_rel = 0;
  double trades_loss_rel = 0;      
  if (trades_total > 0) {
    trades_short_rel = 100*trades_short/trades_total;
    trades_long_rel = 100*trades_long/trades_total;
    trades_profit_rel = 100*trades_profit/trades_total;
    trades_loss_rel = 100*trades_loss/trades_total;
  }
  
  html = str_replace(html, "<!--TRADES_TOTAL-->", number_format(trades_total, 0, ".", " "));
  html = str_replace(html, "<!--TRADES_SHORT-->", number_format(trades_short, 0, ".", " ") + " (" + DoubleToStr(trades_short_rel, 1) + "%)");
  html = str_replace(html, "<!--TRADES_LONG-->", number_format(trades_long, 0, ".", " ") + " (" + DoubleToStr(trades_long_rel, 1) + "%)");
  html = str_replace(html, "<!--TRADES_PROFIT-->", number_format(trades_profit, 0, ".", " ") + " (" + DoubleToStr(trades_profit_rel, 1) + "%)");
  html = str_replace(html, "<!--TRADES_LOSS-->", number_format(trades_loss, 0, ".", " ") + " (" + DoubleToStr(trades_loss_rel, 1) + "%)");
  
  html = str_replace(html, "<!--LARGET_PROFIT_TRADE-->", number_format(largest_profit_trade, 2, ".", " "));
  html = str_replace(html, "<!--LARGET_LOSS_TRADE-->", number_format(largest_loss_trade, 2, ".", " "));
  html = str_replace(html, "<!--AVERAGE_PROFIT_TRADE-->", number_format(avg_profit_trade, 2, ".", " "));
  html = str_replace(html, "<!--AVERAGE_LOSS_TRADE-->", number_format(avg_loss_trade, 2, ".", " "));
  html = str_replace(html, "<!--MAX_CONS_WINS-->", number_format(max_consecutive_wins_cnt, 0, ".", " ") + " (" + number_format(max_consecutive_wins_summ, 2, ".", " ") + ")");
  html = str_replace(html, "<!--MAX_CONS_LOSSES-->", number_format(max_consecutive_losses_cnt, 0, ".", " ") + " (" + number_format(max_consecutive_losses_summ, 2, ".", " ") + ")");
  html = str_replace(html, "<!--MAX_CONS_PROFIT-->", number_format(max_consecutive_profit_summ, 2, ".", " ") + " (" + number_format(max_consecutive_profit_cnt, 0, ".", " ") + ")");
  html = str_replace(html, "<!--MAX_CONS_LOSS-->", number_format(max_consecutive_loss_summ, 2, ".", " ") + " (" + number_format(max_consecutive_loss_cnt, 0, ".", " ") + ")");
      
  //-----
  
  string html_part1 = str_substr(html, "", "<!--CLOSED_POSITIONS[-->");
  string html_part2 = str_substr(html, "<!--]CLOSED_POSITIONS-->", "");
  
  //-----
   
  WriteRes(root, html_part1, rows, html_part2); 
  
  int ts2 = GetTickCount();
  Print("Run time: ", ts2-ts1, " msec");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int GetRoot(string& root) 
{
  int buf[255];
  int res = GetModuleFileNameA(0, buf, 4*255);
  if (res == 0) {
    Alert("GetRoot: GetModuleFileName failed!");
    return (FALSE);
  }
  root = "";
  int ch = -1;
  
  for (int i=0; i<res; i++) {
    if (i%4 == 0) ch = buf[i/4] & 0xFF;
    if (i%4 == 1) ch = (buf[i/4] >> 8) & 0xFF;
    if (i%4 == 2) ch = (buf[i/4] >> 16) & 0xFF;
    if (i%4 == 3) ch = (buf[i/4] >> 24) & 0xFF;
    root = root + CharToStr(ch);
  }
  
  root = str_replace(root, "\\terminal.exe", "");
  return (TRUE);
}
int GetTemplate(string root, string& html) 
{
  string path = str_replace(template, "[ROOT]", root);
  int hFile = _lopen(path, OF_READ);
  if (hFile == HFILE_ERROR) {
    Alert("GetTemplate: _lopen('" + path +"', OF_READ) failed!");  
    return (FALSE);
  }
  
  int size = _llseek(hFile, 0, FILE_END);
  _llseek(hFile, 0, FILE_BEGIN);
  int buf[];
  ArrayResize(buf, size/4 + 1);
  int res = _lread(hFile, buf, size);
  if (res == HFILE_ERROR) {
    Alert("GetTemplate: _lread failed!");
    return (FALSE);
  }
  html = "";  
  int ch = -1;
    
  for (int i=0; i<res; i++) {
    if (i%4 == 0) ch = buf[i/4] & 0xFF;
    if (i%4 == 1) ch = (buf[i/4] >> 8) & 0xFF;
    if (i%4 == 2) ch = (buf[i/4] >> 16) & 0xFF;
    if (i%4 == 3) ch = (buf[i/4] >> 24) & 0xFF;
    html = html + CharToStr(ch);
  }
  _lclose(hFile);
  return (TRUE);
}
void Sort(int& Tickets[]) 
{
  int cnt = ArraySize(Tickets);
  for (int i=0; i < cnt; i++) {
    for (int j=i+1; j < cnt; j++) {
      int res = Compare(Tickets[i], Tickets[j]);
      if (res == -1) {
        int ticket = Tickets[i];
        Tickets[i] = Tickets[j];
        Tickets[j] = ticket;        
      }
    }
  }  
}
int WriteRes(string root, string html_part1, string& rows[], string html_part2)
{
  string path = str_replace(report, "[ROOT]", root);
  path = str_replace(path, "[ACCOUNT_NUM]", AccountNumber());
  int hFile = _lcreat(path, 0);
  if (hFile == HFILE_ERROR) {
    Alert("WriteRes: _lcreat('" + path + "', 0) failed!");
    return (FALSE);
  }
  
  _lwrite(hFile, html_part1, StringLen(html_part1));
  int size = ArraySize(rows);
  for (int i=0; i<size; i++) {
    _lwrite(hFile, rows[i], StringLen(rows[i]));
  }
  
  _lwrite(hFile, html_part2, StringLen(html_part2));
  _lclose(hFile);
  ShellExecuteA(0, 0, path, 0, "", SW_SHOW);  
  return (TRUE);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
string str_replace(string subject, string search, string replace) 
{
  string left_part = "";
  string right_part = "";
  for (;;) {
    int pos = StringFind(subject, search);
    if (pos == -1) break;
    
    left_part = "";
    right_part = "";
    
    if (pos > 0) left_part = StringSubstr(subject, 0, pos);
    if (pos+1 < StringLen(subject)) right_part = StringSubstr(subject, pos+StringLen(search));
    subject = left_part + replace + right_part;
  }
  return (subject);
}
string str_substr(string text, string marker1, string marker2)
{
  int pos = -1;
  int pos2 = -1;
    
  if (marker1 == "") {
    pos = 0;
  } 
  else {
    pos = StringFind(text, marker1, 0);
    if (pos == -1) return ("");
  }
  
  pos += StringLen(marker1);
  if (marker2 == "") {
    pos2 = StringLen(text) - 1;
  } else {
    pos2 = StringFind(text, marker2, pos);
    if (pos2 == -1) return ("");
  }
  string res = StringSubstr(text, pos, pos2-pos);
  return (res);
}
string str_repeat(int char, int cnt)
{
  string res = "";
  for (int i=0; i<cnt; i++) {
    res = res + CharToStr(char);
  }
  
  return (res);
}
string str_if(bool cond, string val1, string val2) 
{
  if (cond) return (val1);
  return (val2);
}
string number_format(double number, int decimals, string dec_point, string thousands_sep)
{
  string str = DoubleToStr(number, decimals);
  string res = "";
  int len = StringLen(str);
  int pos = StringFind(str, dec_point);
  if (pos > 0) {
    len = pos;
    res = StringSubstr(str, pos);
  }
  
  for (int i = len-1; i >= 0; i--) {
    res = StringSubstr(str, i, 1) + res;
    
    if (i > 0 && (len-i)%3 == 0) {
      if (StringSubstr(str, i-1, 1) != "-") res = thousands_sep + res;
    }
  }
  return (res);
}
string time_format(datetime tm, string format) 
{
  string month[12] = {"Jan", "Feb", "March", "April", "May", "June", "July", "Aug",
    "Sept", "Oct", "Nov", "Dec"};
  
  string res = format;  
  res = str_replace(res, "d", TimeDay(tm));
  res = str_replace(res, "mon", month[TimeMonth(tm)-1]);
  res = str_replace(res, "yyyy", TimeYear(tm));
  
  int hh = TimeHour(tm);
  int mm = TimeMinute(tm);
  
  res = str_replace(res, "hh", str_if(hh < 10, "0" + hh, hh));
  res = str_replace(res, "mm", str_if(mm < 10, "0" + mm, mm));
  return (res);
}
string OrderTypeToStr(int type) 
{
  if (type == OP_BUY) return ("buy");
  if (type == OP_SELL) return ("sell");
  if (type == OP_BUYLIMIT) return ("buy limit");
  if (type == OP_SELLLIMIT) return ("sell limit");
  if (type == OP_BUYSTOP) return ("buy stop");
  if (type == OP_SELLSTOP) return ("sell stop");
  if (type == OP_BALANCE) return ("balance");
  return ("?");
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Compare
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int Compare(int ticket1, int ticket2) 
{
  if (!OrderSelect(ticket1, SELECT_BY_TICKET, MODE_HISTORY)) return (0);
  datetime tm1 = OrderCloseTime();
  double Profit1 = OrderProfit();
  
  if (!OrderSelect(ticket2, SELECT_BY_TICKET, MODE_HISTORY)) return (0);
  datetime tm2 = OrderCloseTime();
  double Profit2 = OrderProfit();
  
  
  if (tm1 < tm2) return (1);
  if (tm1 > tm2) return (-1);
/*
  if (Profit1 > Profit2) return (1);
  if (Profit1 < Profit2) return (-1);
*/  
  return (0);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Validate
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bool Validate(int ticket) 
{
  if (!OrderSelect(ticket, SELECT_BY_TICKET, MODE_HISTORY)) return (false);
  //if (OrderType() == OP_BALANCE) return (false);
//  if (StringFind(OrderComment(), "[tp]") == -1) return(true);
//  if (OrderOpenTime() < StrToTime("2005.05.27 22.20")) return(false); 
//  if (OrderOpenTime() > StrToTime("2005.06.13 20.00")) return(false); 
//  if (TimeDay(OrderOpenTime()) == 13) return(true);
//  if (OrderProfit() >= 0) return(true);
  
  //if (OrderType() == OP_BUYLIMIT || OrderType() == OP_SELLLIMIT) return (false);
  //return (OrderOpenTime() < StrToTime("2006.01.30 00.00"));
 
  return (true); 
  //return (OrderSymbol() == "NZDUSD");
}
             
            
            
            
Comments