/*
   Generated by EX4-TO-MQ4 decompiler FREEWARE V4.0.451.1 [-]
   Website: http://www.metaquotes.net
   E-mail : support@metaquotes.net
*/
#property copyright "Steph    stereyn@gmail.com"
#property link      "http://www.metaquotes.net"

int g_count_76;
int gi_unused_80;
extern string txt4 = "------------------- Phase 2 : Run  --------------------------";
extern string txt5 = "..........NB_INPUT=1 to 4";
extern string txt9 = " sigma=0.05 to 0.5 : sensibility of the PNN.";
extern int lots = 1;
extern int NB_INPUT = 1;
extern double sigma = 0.3;
extern double delta = 0.5025;
extern string txt6 = "..........if pnn>delta: open long, if pnn<0.5, close long";
extern string txt7 = "..........if pnn<-delta: open short, if pnn>0.5, close short";
extern int step = 10;
extern string txt8 = "each \'step\' pips, the PNN is calculated.";
extern int sl = 500;
extern int tp = 500;
extern string txt1 = "-- Phase 1 : create file for the PNN (create_file=true)--";
extern string txt2 = "hh= nb period in the futur, the pnn calculate the output";
extern string txt3 = "when run in M5, hh=12 or 24 is ok = (1 or 2 hour)";
extern bool create_file = FALSE;
extern string FileParam = "pnn_data.txt";
extern int hh = 24;
extern int MA_METHOD = 1;
extern int MA1 = 800;
extern int PERIOD1 = 5;
extern int MA2 = 500;
extern int PERIOD2 = 5;
extern int MA3 = 250;
extern int PERIOD3 = 5;
extern int MA4 = 150;
extern int PERIOD4 = 5;
int gi_unused_244 = 30;
int gi_248 = 0;
int gi_unused_252 = 75;
double gda_256[500000][20];
double gda_260[500000][20];
double gda_264[500000];
double gda_unused_268[1000];
double gda_unused_272[1000];
double gda_276[100];
double gda_280[100];
int g_datetime_284 = 0;
int gi_300;
int gi_304;
double gda_unused_308[10000][10];
double gda_unused_312[1000][250];
int gi_unused_316 = 0;
int gi_unused_320 = 0;
double gda_unused_324[1000];
double gda_328[1000][10];
double gda_332[1000];
double gda_unused_336[1000];
bool gi_344 = FALSE;
bool gi_348 = FALSE;
double gd_352;
double gd_360;
double gd_368;
int g_file_376;
double g_ask_380;
double g_order_profit_388 = 0.0;
int g_count_396;

int init() {
   gi_unused_80 = NB_INPUT;
   g_count_76 = 500000;
   if (create_file) g_file_376 = FileOpen(FileParam, FILE_CSV|FILE_WRITE, ';');
   else {
      g_file_376 = FileOpen(FileParam, FILE_CSV|FILE_READ);
      if (g_file_376 < 1) {
         Print("File data not found, the last error is ", GetLastError());
         return (0);
      }
      lire_fichier();
      Print("MAX_HISTO=", g_count_76);
      calc_moy_ecartype();
   }
   g_count_396 = 0;
   return (0);
}

int lire_fichier() {
   g_count_76 = 0;
   Print("Wait ... The PNN is created from the file.");
   for (int li_0 = 1; li_0 <= 500000; li_0++) {
      gda_260[li_0][1] = StrToDouble(FileReadString(g_file_376));
      for (int li_4 = 1; li_4 <= 10; li_4++) gda_256[li_0][li_4] = StrToDouble(FileReadString(g_file_376));
      if (gda_256[li_0][1] != 0.0) g_count_76++;
   }
   return (0);
}

int calc_moy_ecartype() {
   double ld_0;
   for (int li_8 = 1; li_8 <= NB_INPUT; li_8++) {
      ld_0 = 0;
      for (int li_12 = 1; li_12 <= g_count_76; li_12++) ld_0 += gda_256[li_12][li_8];
      gda_276[li_8] = ld_0 / g_count_76;
   }
   for (li_8 = 1; li_8 <= NB_INPUT; li_8++) {
      ld_0 = 0;
      for (li_12 = 1; li_12 <= g_count_76; li_12++) ld_0 += (gda_256[li_12][li_8] - gda_276[li_12]) * (gda_256[li_12][li_8] - gda_276[li_12]);
      gda_280[li_8] = MathSqrt(ld_0 / g_count_76);
   }
   return (0);
}

int deinit() {
   if (create_file) {
      for (int li_0 = 1; li_0 <= g_count_396 - hh; li_0++) {
         FileWrite(g_file_376, (gda_264[li_0 + hh] - gda_264[li_0]) / Point, gda_256[li_0][1], gda_256[li_0][2], gda_256[li_0][3], gda_256[li_0][4], gda_256[li_0][5], gda_256[li_0][6],
            gda_256[li_0][7], gda_256[li_0][8], gda_256[li_0][9], gda_256[li_0][10]);
      }
      FileClose(g_file_376);
      Print("OK. The file is created. You can run the PNN now.");
   }
   return (0);
}

int start() {
   double ld_0;
   if (create_file) {
      if (g_datetime_284 == iTime(Symbol(), 0, 0)) return (0);
      g_datetime_284 = iTime(Symbol(), 0, 0);
      g_count_396++;
      lire_input(g_count_396);
      return (0);
   }
   if (NB_INPUT <= 0 && NB_INPUT > 4) {
      Print("Error. NB_INPUT between 1 to 4.");
      return (0);
   }
   if (Year() >= 2008 && Month() > 6) {
      Print("Expiration.");
      return (0);
   }
   gi_248 = 0;
   if (Ask > g_ask_380 + step * Point || Ask < g_ask_380 - step * Point) {
      g_datetime_284 = iTime(Symbol(), 0, 0);
      g_ask_380 = Ask;
      ld_0 = Calculer_Bar(0);
      Traiter_syst(999, ld_0, delta);
   }
   StopLoss(999, 1000);
   return (0);
}

double Calculer_Bar(int ai_unused_0) {
   int li_4 = 1;
   int li_unused_8 = 0;
   double ld_unused_12 = 0;
   lire_input(0);
   for (int li_20 = 1; li_20 <= 1; li_20++) {
      for (int li_24 = 1; li_24 <= 1; li_24++) {
         for (int li_28 = 1; li_28 <= 1; li_28++) {
            gda_328[li_4][1] = 1 * (li_20 - 1) + 1;
            gda_328[li_4][2] = g_count_76;
            gda_328[li_4][3] = sigma;
            KDE(gda_328[li_4][2], 1, NB_INPUT);
            if (gd_352 > gd_360 && gd_352 > gd_368) gda_332[li_4] = gd_352;
            if (gd_360 > gd_352 && gd_360 > gd_368) gda_332[li_4] = -1.0 * gd_360;
            if (gd_368 > gd_352 && gd_368 > gd_360) gda_332[li_4] = 0;
            if (gd_352 + gd_360 + gd_368 == 0.0) gda_332[li_4] = 0;
            li_4++;
         }
      }
   }
   gi_304 = li_4 - 1;
   Print(Ask, "  pnn= ", gda_332[1]);
   return (gda_332[1]);
}

int StopLoss(int ai_0, int ai_4) {
   if (OrdersTotal() >= 1) {
      for (int pos_8 = 0; pos_8 < OrdersTotal(); pos_8++) {
         OrderSelect(pos_8, SELECT_BY_POS, MODE_TRADES);
         if (sl > 0 && OrderMagicNumber() >= ai_0 && OrderMagicNumber() <= ai_4) {
            if (OrderType() == OP_BUY && OrderOpenPrice() - Bid > Point * sl) {
               Close_All(OrderMagicNumber());
               gi_344 = TRUE;
            }
            if (OrderType() == OP_SELL && Ask - OrderOpenPrice() > Point * sl) {
               Close_All(OrderMagicNumber());
               gi_348 = TRUE;
            }
         }
      }
   }
   return (0);
}

int Traiter_syst(int a_magic_0, double ad_4, double ad_12) {
   int count_20 = 0;
   string ls_24 = "FB";
   if (ad_4 > 0 - ad_12) ls_24 = "B";
   if (ad_4 > 0.0) ls_24 = "H";
   if (ad_4 > ad_12 + 0.0) ls_24 = "FH";
   if (ad_4 == 0.0) ls_24 = "!";
   bool li_32 = FALSE;
   if (OrdersTotal() >= 1) {
      for (int order_total_36 = OrdersTotal(); order_total_36 >= 0; order_total_36--) {
         OrderSelect(order_total_36, SELECT_BY_POS, MODE_TRADES);
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == a_magic_0) {
            count_20++;
            if (OrderType() == OP_BUY && ls_24 == "B" || ls_24 == "FB" || ls_24 == "!") li_32 = TRUE;
            if (OrderType() == OP_SELL && ls_24 == "H" || ls_24 == "FH" || ls_24 == "!") li_32 = TRUE;
            g_order_profit_388 = OrderProfit();
         }
      }
   }
   if (li_32) {
      Close_All(a_magic_0);
      count_20--;
   }
   if (count_20 < 1) {
      if (ls_24 == "FH" && (!gi_344)) {
         OpenBuy(a_magic_0, lots);
         gi_348 = FALSE;
      }
      if (ls_24 == "FB" && (!gi_348)) {
         OpenSell(a_magic_0, lots);
         gi_344 = FALSE;
      }
   }
   return (0);
}

double Close_All(int a_magic_0) {
   for (int order_total_4 = OrdersTotal(); order_total_4 >= 0; order_total_4--) {
      OrderSelect(order_total_4, SELECT_BY_POS, MODE_TRADES);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == a_magic_0) OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 5, Orange);
   }
   return (0);
}

double OpenBuy(int a_magic_0, double a_lots_4) {
   OrderSend(Symbol(), OP_BUY, a_lots_4, Ask, 3, 0, Ask + tp * Point, "Syst " + a_magic_0, a_magic_0, 0, Green);
   return (0.0);
}

double OpenSell(int a_magic_0, double a_lots_4) {
   OrderSend(Symbol(), OP_SELL, a_lots_4, Bid, 3, 0, Bid - tp * Point, "Syst " + a_magic_0, a_magic_0, 0, Red);
   return (0.0);
}

double KDE(int ai_0, int ai_4, int ai_8) {
   double ld_24 = 0;
   double ld_unused_32 = 0;
   double ld_40 = 0;
   int count_12 = 0;
   int count_16 = 0;
   int count_20 = 0;
   ld_40 = 0;
   gd_352 = 0;
   gd_360 = 0;
   gd_368 = 0;
   double ld_48 = 0;
   double ld_56 = 0;
   double ld_64 = 0;
   int index_72 = gi_300;
   index_72 = 0;
   for (int li_76 = 1; li_76 <= ai_0; li_76++) {
      index_72++;
      if (index_72 > g_count_76) index_72 = 1;
      ld_24 = 1;
      for (int li_80 = ai_4; li_80 < ai_4 + ai_8; li_80++) ld_24 *= K(INPUT(0, li_80), INPUT(index_72, li_80), li_80);
      if (gda_260[index_72][1] > gi_248) {
         ld_48 += ld_24;
         count_12++;
      } else {
         if (gda_260[index_72][1] < -1 * gi_248) {
            ld_56 += ld_24;
            count_16++;
         } else {
            ld_64 += ld_24;
            count_20++;
         }
      }
   }
   ld_40 = ld_48 + ld_56 + ld_64;
   if (count_12 > 0) ld_48 /= count_12;
   if (count_16 > 0) ld_56 /= count_16;
   if (count_20 > 0) ld_64 /= count_20;
   double ld_ret_84 = 0;
   ld_64 = 0;
   if (ld_48 + ld_56 + ld_64 != 0.0) {
      gd_352 = ld_48 / (ld_48 + ld_56 + ld_64);
      gd_360 = ld_56 / (ld_48 + ld_56 + ld_64);
      gd_368 = ld_64 / (ld_48 + ld_56 + ld_64);
   } else {
      gd_352 = 0;
      gd_360 = 0;
      gd_368 = 0;
   }
   return (ld_ret_84);
}

double K(double ad_0, double ad_8, int ai_unused_16) {
   double ld_20 = (ad_0 - ad_8) / sigma;
   return (MathExp(-0.5 * (ld_20 * ld_20)) / MathSqrt(6.28));
}

int lire_input(int ai_0) {
   int li_unused_4;
   if (ai_0 == 0) li_unused_4 = 0;
   gda_264[ai_0] = Ask;
   gda_256[ai_0][1] = (Ask - iMA(NULL, PERIOD1, MA1, 0, MA_METHOD, PRICE_CLOSE, 0)) / Point;
   gda_256[ai_0][2] = (Ask - iMA(NULL, PERIOD2, MA2, 0, MA_METHOD, PRICE_CLOSE, 0)) / Point;
   gda_256[ai_0][3] = (Ask - iMA(NULL, PERIOD3, MA3, 0, MA_METHOD, PRICE_CLOSE, 0)) / Point;
   gda_256[ai_0][4] = (Ask - iMA(NULL, PERIOD4, MA4, 0, MA_METHOD, PRICE_CLOSE, 0)) / Point;
   for (int li_8 = 1; li_8 <= 10; li_8++) gda_256[ai_0][li_8] = NormalizeDouble(gda_256[ai_0][li_8], 2);
   return (0);
}

double INPUT(int ai_0, int ai_4) {
   double ld_ret_8 = (gda_256[ai_0][ai_4] - gda_276[ai_4]) / (1.5 * gda_280[ai_4]);
   ld_ret_8 = ld_ret_8 / 2.0 + 0.5;
   if (ld_ret_8 > 1.0) ld_ret_8 = 1;
   if (ld_ret_8 < 0.0) ld_ret_8 = 0;
   return (ld_ret_8);
}
