#property copyright "Alphamatic"
#property link      ""

string Indicator_Name = "CFP_HST";

#property indicator_separate_window
#property indicator_buffers 5
#property indicator_minimum 0.0
#property indicator_maximum 10.0

#property indicator_color1 DodgerBlue
#property indicator_color2 Blue
#property indicator_color3 Red
#property indicator_color4 Maroon

extern int TimeFrame = 0;
extern int Processed = 1000;

extern int MA_Method = MODE_LWMA;
extern int MA_Price  = PRICE_WEIGHTED;

extern int MA_FastPeriod = 3;
extern int MA_SlowPeriod = 5;

int Factor = 1;

extern bool USD = TRUE;
extern bool EUR = TRUE;
extern bool GBP = TRUE;
extern bool CHF = TRUE;
extern bool JPY = TRUE;
extern bool AUD = TRUE;
extern bool CAD = TRUE;
extern bool NZD = TRUE;

#define ITEM_USD 0
#define ITEM_EUR 1
#define ITEM_GBP 2
#define ITEM_CHF 3
#define ITEM_JPY 4
#define ITEM_AUD 5
#define ITEM_CAD 6
#define ITEM_NZD 7

#define ARROW_CODE 110

string tf_name;

int Item_1 = -1, Item_2 =-1;

double val_pos_up[], val_pos_dn[], val_neg_dn[], val_neg_up[], values[], direct[];
double fast_data[8], slow_data[8], norm_data[8];

int init() {
  IndicatorBuffers(6);
  IndicatorDigits(Digits);

  if (TimeFrame == 0) TimeFrame = Period();
  Factor =  TimeFrame / Period(); 
  
  switch (TimeFrame) {
    case 1:     tf_name = "M1";  break;
    case 5:     tf_name = "M5";  break;
    case 15:    tf_name = "M15"; break;
    case 30:    tf_name = "M30"; break;
    case 60:    tf_name = "H1";  break;
    case 240:   tf_name = "H4";  break;
    case 1440:  tf_name = "D1";  break;
    case 10080: tf_name = "W1";  break;
    case 43200: tf_name = "MN1"; break;
  }    
  IndicatorShortName(Indicator_Name + " (" + tf_name + ")");
  SetIndexBuffer(0, val_pos_up); SetIndexStyle(0, DRAW_ARROW); SetIndexArrow(0, ARROW_CODE); SetIndexLabel(0, "");
  SetIndexBuffer(1, val_pos_dn); SetIndexStyle(1, DRAW_ARROW); SetIndexArrow(1, ARROW_CODE); SetIndexLabel(1, "");
  SetIndexBuffer(2, val_neg_dn); SetIndexStyle(2, DRAW_ARROW); SetIndexArrow(2, ARROW_CODE); SetIndexLabel(2, "");
  SetIndexBuffer(3, val_neg_up); SetIndexStyle(3, DRAW_ARROW); SetIndexArrow(3, ARROW_CODE); SetIndexLabel(3, "");   
  SetIndexBuffer(4, values);     SetIndexStyle(4, DRAW_NONE);  SetIndexLabel(4, "CFP"); SetIndexEmptyValue(4,0.0);
  SetIndexBuffer(5, direct);     SetIndexStyle(4, DRAW_NONE);  SetIndexLabel(5, "DIR"); SetIndexEmptyValue(5,0.0);
  
  string instrument = Symbol();
  if(0 == StringFind(instrument, "USD", 0)) Item_1 = ITEM_USD; if(3 == StringFind(instrument, "USD", 0)) Item_2 = ITEM_USD;
  if(0 == StringFind(instrument, "EUR", 0)) Item_1 = ITEM_EUR; if(3 == StringFind(instrument, "EUR", 0)) Item_2 = ITEM_EUR;
  if(0 == StringFind(instrument, "GBP", 0)) Item_1 = ITEM_GBP; if(3 == StringFind(instrument, "GBP", 0)) Item_2 = ITEM_GBP;
  if(0 == StringFind(instrument, "CHF", 0)) Item_1 = ITEM_CHF; if(3 == StringFind(instrument, "CHF", 0)) Item_2 = ITEM_CHF;
  if(0 == StringFind(instrument, "JPY", 0)) Item_1 = ITEM_JPY; if(3 == StringFind(instrument, "JPY", 0)) Item_2 = ITEM_JPY;  
  if(0 == StringFind(instrument, "AUD", 0)) Item_1 = ITEM_AUD; if(3 == StringFind(instrument, "AUD", 0)) Item_2 = ITEM_AUD; 
  if(0 == StringFind(instrument, "CAD", 0)) Item_1 = ITEM_CAD; if(3 == StringFind(instrument, "CAD", 0)) Item_2 = ITEM_CAD;  
  if(0 == StringFind(instrument, "NZD", 0)) Item_1 = ITEM_NZD; if(3 == StringFind(instrument, "NZD", 0)) Item_2 = ITEM_NZD;

  return(0);
}

int deinit() {
  return(0);
}


int start() {  
  int i, limit; 
  int time_series[];
  if (IndicatorCounted() < 0) return(-1);
  limit = Bars - IndicatorCounted();
  if (Processed > 0 && limit > Processed) limit = Processed;

  for(i = 0; i < limit; i++){
    if(EUR) {
      fast_data[ITEM_EUR] = Calc_Data("EURUSD", MA_FastPeriod, i);
      slow_data[ITEM_EUR] = Calc_Data("EURUSD", MA_SlowPeriod, i);
      if(!fast_data[ITEM_EUR] || !slow_data[ITEM_EUR]) break;
    }
    if(GBP) {
      fast_data[ITEM_GBP] = Calc_Data("GBPUSD", MA_FastPeriod, i);
      slow_data[ITEM_GBP] = Calc_Data("GBPUSD", MA_SlowPeriod, i);
      if(!fast_data[ITEM_GBP] || !slow_data[ITEM_GBP]) break;
    }
    if(AUD) {    
      fast_data[ITEM_AUD] = Calc_Data("AUDUSD", MA_FastPeriod, i);
      slow_data[ITEM_AUD] = Calc_Data("AUDUSD", MA_SlowPeriod, i);
      if(!fast_data[ITEM_AUD] || !slow_data[ITEM_AUD]) break;
    }
    if(NZD) {      
      fast_data[ITEM_NZD] = Calc_Data("NZDUSD", MA_FastPeriod, i);
      slow_data[ITEM_NZD] = Calc_Data("NZDUSD", MA_SlowPeriod, i);
      if(!fast_data[ITEM_NZD] || !slow_data[ITEM_NZD]) break;
    }
    if(CAD) {
      fast_data[ITEM_CAD] = Calc_Data("USDCAD", MA_FastPeriod, i);
      slow_data[ITEM_CAD] = Calc_Data("USDCAD", MA_SlowPeriod, i);
      if(!fast_data[ITEM_CAD] || !slow_data[ITEM_CAD]) break;
    }
    if(CHF) {
      fast_data[ITEM_CHF] = Calc_Data("USDCHF", MA_FastPeriod, i);
      slow_data[ITEM_CHF] = Calc_Data("USDCHF", MA_SlowPeriod, i);      
      if(!fast_data[ITEM_CHF] || !slow_data[ITEM_CHF]) break;
    }
    if(JPY) {
      fast_data[ITEM_JPY] = Calc_Data("USDJPY", MA_FastPeriod, i);
      slow_data[ITEM_JPY] = Calc_Data("USDJPY", MA_SlowPeriod, i);       
      if(!fast_data[ITEM_JPY] || !slow_data[ITEM_JPY]) break;
    }
         
    if(USD) {
      norm_data[ITEM_USD] = 0.0;
      if(EUR) norm_data[ITEM_USD] += slow_data[ITEM_EUR] / fast_data[ITEM_EUR] - 1;
      if(GBP) norm_data[ITEM_USD] += slow_data[ITEM_GBP] / fast_data[ITEM_GBP] - 1;
      if(AUD) norm_data[ITEM_USD] += slow_data[ITEM_AUD] / fast_data[ITEM_AUD] - 1;
      if(NZD) norm_data[ITEM_USD] += slow_data[ITEM_NZD] / fast_data[ITEM_NZD] - 1;
      if(CHF) norm_data[ITEM_USD] += fast_data[ITEM_CHF] / slow_data[ITEM_CHF] - 1;
      if(CAD) norm_data[ITEM_USD] += fast_data[ITEM_CAD] / slow_data[ITEM_CAD] - 1;
      if(JPY) norm_data[ITEM_USD] += fast_data[ITEM_JPY] / slow_data[ITEM_JPY] - 1;
    }
    
    if(EUR) {
      norm_data[ITEM_EUR] = 0.0;
      if(USD) norm_data[ITEM_EUR] += (fast_data[ITEM_EUR] / slow_data[ITEM_EUR]) - 1;
      if(GBP) norm_data[ITEM_EUR] += (fast_data[ITEM_EUR] / fast_data[ITEM_GBP]) / (slow_data[ITEM_EUR] / slow_data[ITEM_GBP]) - 1;
      if(AUD) norm_data[ITEM_EUR] += (fast_data[ITEM_EUR] / fast_data[ITEM_AUD]) / (slow_data[ITEM_EUR] / slow_data[ITEM_AUD]) - 1;
      if(NZD) norm_data[ITEM_EUR] += (fast_data[ITEM_EUR] / fast_data[ITEM_NZD]) / (slow_data[ITEM_EUR] / slow_data[ITEM_NZD]) - 1;
      if(CHF) norm_data[ITEM_EUR] += (fast_data[ITEM_EUR] * fast_data[ITEM_CHF]) / (slow_data[ITEM_EUR] * slow_data[ITEM_CHF]) - 1;
      if(CAD) norm_data[ITEM_EUR] += (fast_data[ITEM_EUR] * fast_data[ITEM_CAD]) / (slow_data[ITEM_EUR] * slow_data[ITEM_CAD]) - 1;
      if(JPY) norm_data[ITEM_EUR] += (fast_data[ITEM_EUR] * fast_data[ITEM_JPY]) / (slow_data[ITEM_EUR] * slow_data[ITEM_JPY]) - 1;
    }
         
    if(GBP) {
      norm_data[ITEM_GBP] = 0.0;
      if(USD) norm_data[ITEM_GBP] += (fast_data[ITEM_GBP] / slow_data[ITEM_GBP]) - 1;
      if(EUR) norm_data[ITEM_GBP] += (slow_data[ITEM_EUR] / slow_data[ITEM_GBP]) / (fast_data[ITEM_EUR] / fast_data[ITEM_GBP]) - 1;
      if(AUD) norm_data[ITEM_GBP] += (fast_data[ITEM_GBP] / fast_data[ITEM_AUD]) / (slow_data[ITEM_GBP] / slow_data[ITEM_AUD]) - 1;
      if(NZD) norm_data[ITEM_GBP] += (fast_data[ITEM_GBP] / fast_data[ITEM_NZD]) / (slow_data[ITEM_GBP] / slow_data[ITEM_NZD]) - 1;
      if(CHF) norm_data[ITEM_GBP] += (fast_data[ITEM_GBP] * fast_data[ITEM_CHF]) / (slow_data[ITEM_GBP] * slow_data[ITEM_CHF]) - 1;
      if(CAD) norm_data[ITEM_GBP] += (fast_data[ITEM_GBP] * fast_data[ITEM_CAD]) / (slow_data[ITEM_GBP] * slow_data[ITEM_CAD]) - 1;
      if(JPY) norm_data[ITEM_GBP] += (fast_data[ITEM_GBP] * fast_data[ITEM_JPY]) / (slow_data[ITEM_GBP] * slow_data[ITEM_JPY]) - 1;
    }
    
    if(AUD) {
      norm_data[ITEM_AUD] = 0.0;
      if(USD) norm_data[ITEM_AUD] += (fast_data[ITEM_AUD] / slow_data[ITEM_AUD]) - 1;
      if(EUR) norm_data[ITEM_AUD] += (slow_data[ITEM_EUR] / slow_data[ITEM_AUD]) / (fast_data[ITEM_EUR] / fast_data[ITEM_AUD]) - 1;
      if(GBP) norm_data[ITEM_AUD] += (slow_data[ITEM_GBP] / slow_data[ITEM_AUD]) / (fast_data[ITEM_GBP] / fast_data[ITEM_AUD]) - 1;
      if(NZD) norm_data[ITEM_AUD] += (fast_data[ITEM_AUD] / fast_data[ITEM_NZD]) / (slow_data[ITEM_AUD] / slow_data[ITEM_NZD]) - 1;
      if(CHF) norm_data[ITEM_AUD] += (fast_data[ITEM_AUD] * fast_data[ITEM_CHF]) / (slow_data[ITEM_AUD] * slow_data[ITEM_CHF]) - 1;
      if(CAD) norm_data[ITEM_AUD] += (fast_data[ITEM_AUD] * fast_data[ITEM_CAD]) / (slow_data[ITEM_AUD] * slow_data[ITEM_CAD]) - 1;
      if(JPY) norm_data[ITEM_AUD] += (fast_data[ITEM_AUD] * fast_data[ITEM_JPY]) / (slow_data[ITEM_AUD] * slow_data[ITEM_JPY]) - 1;
    }
    
    if(NZD){
      norm_data[ITEM_NZD] = 0.0;
      if(USD) norm_data[ITEM_NZD] += (fast_data[ITEM_NZD] / slow_data[ITEM_NZD]) - 1;
      if(EUR) norm_data[ITEM_NZD] += (slow_data[ITEM_EUR] / slow_data[ITEM_NZD]) / (fast_data[ITEM_EUR] / fast_data[ITEM_NZD]) - 1;
      if(GBP) norm_data[ITEM_NZD] += (slow_data[ITEM_GBP] / slow_data[ITEM_NZD]) / (fast_data[ITEM_GBP] / fast_data[ITEM_NZD]) - 1;
      if(AUD) norm_data[ITEM_NZD] += (slow_data[ITEM_AUD] / slow_data[ITEM_NZD]) / (fast_data[ITEM_AUD] / fast_data[ITEM_NZD]) - 1;
      if(CHF) norm_data[ITEM_NZD] += (fast_data[ITEM_NZD] * fast_data[ITEM_CHF]) / (slow_data[ITEM_NZD] * slow_data[ITEM_CHF]) - 1;
      if(CAD) norm_data[ITEM_NZD] += (fast_data[ITEM_NZD] * fast_data[ITEM_CAD]) / (slow_data[ITEM_NZD] * slow_data[ITEM_CAD]) - 1;
      if(JPY) norm_data[ITEM_NZD] += (fast_data[ITEM_NZD] * fast_data[ITEM_JPY]) / (slow_data[ITEM_NZD] * slow_data[ITEM_JPY]) - 1;
    }
    
    if(CAD) {
      norm_data[ITEM_CAD] = 0.0;
      if(USD) norm_data[ITEM_CAD] += (slow_data[ITEM_CAD] / fast_data[ITEM_CAD]) - 1;
      if(EUR) norm_data[ITEM_CAD] += (slow_data[ITEM_EUR] * slow_data[ITEM_CAD]) / (fast_data[ITEM_EUR] * fast_data[ITEM_CAD]) - 1;
      if(GBP) norm_data[ITEM_CAD] += (slow_data[ITEM_GBP] * slow_data[ITEM_CAD]) / (fast_data[ITEM_GBP] * fast_data[ITEM_CAD]) - 1;
      if(AUD) norm_data[ITEM_CAD] += (slow_data[ITEM_AUD] * slow_data[ITEM_CAD]) / (fast_data[ITEM_AUD] * fast_data[ITEM_CAD]) - 1;
      if(NZD) norm_data[ITEM_CAD] += (slow_data[ITEM_NZD] * slow_data[ITEM_CAD]) / (fast_data[ITEM_NZD] * fast_data[ITEM_CAD]) - 1;
      if(CHF) norm_data[ITEM_CAD] += (fast_data[ITEM_CHF] / fast_data[ITEM_CAD]) / (slow_data[ITEM_CHF] / slow_data[ITEM_CAD]) - 1;
      if(JPY) norm_data[ITEM_CAD] += (fast_data[ITEM_JPY] / fast_data[ITEM_CAD]) / (slow_data[ITEM_JPY] / slow_data[ITEM_CAD]) - 1;
    }
    
    if(CHF) {
      norm_data[ITEM_CHF] = 0.0;
      if(USD) norm_data[ITEM_CHF] += (slow_data[ITEM_CHF] / fast_data[ITEM_CHF]) - 1;
      if(EUR) norm_data[ITEM_CHF] += (slow_data[ITEM_EUR] * slow_data[ITEM_CHF]) / (fast_data[ITEM_EUR] * fast_data[ITEM_CHF]) - 1;
      if(GBP) norm_data[ITEM_CHF] += (slow_data[ITEM_GBP] * slow_data[ITEM_CHF]) / (fast_data[ITEM_GBP] * fast_data[ITEM_CHF]) - 1;
      if(AUD) norm_data[ITEM_CHF] += (slow_data[ITEM_AUD] * slow_data[ITEM_CHF]) / (fast_data[ITEM_AUD] * fast_data[ITEM_CHF]) - 1;
      if(NZD) norm_data[ITEM_CHF] += (slow_data[ITEM_NZD] * slow_data[ITEM_CHF]) / (fast_data[ITEM_NZD] * fast_data[ITEM_CHF]) - 1;
      if(CAD) norm_data[ITEM_CHF] += (slow_data[ITEM_CHF] / slow_data[ITEM_CAD]) / (fast_data[ITEM_CHF] / fast_data[ITEM_CAD]) - 1;
      if(JPY) norm_data[ITEM_CHF] += (fast_data[ITEM_JPY] / fast_data[ITEM_CHF]) / (slow_data[ITEM_JPY] / slow_data[ITEM_CHF]) - 1;
    }
    
    if(JPY) {
      norm_data[ITEM_JPY] = 0.0;
      if(USD) norm_data[ITEM_JPY] += (slow_data[ITEM_JPY] / fast_data[ITEM_JPY]) - 1;
      if(EUR) norm_data[ITEM_JPY] += (slow_data[ITEM_EUR] * slow_data[ITEM_JPY]) / (fast_data[ITEM_EUR] * fast_data[ITEM_JPY]) - 1;
      if(GBP) norm_data[ITEM_JPY] += (slow_data[ITEM_GBP] * slow_data[ITEM_JPY]) / (fast_data[ITEM_GBP] * fast_data[ITEM_JPY]) - 1;
      if(AUD) norm_data[ITEM_JPY] += (slow_data[ITEM_AUD] * slow_data[ITEM_JPY]) / (fast_data[ITEM_AUD] * fast_data[ITEM_JPY]) - 1;
      if(NZD) norm_data[ITEM_JPY] += (slow_data[ITEM_NZD] * slow_data[ITEM_JPY]) / (fast_data[ITEM_NZD] * fast_data[ITEM_JPY]) - 1;
      if(CAD) norm_data[ITEM_JPY] += (slow_data[ITEM_JPY] / slow_data[ITEM_CAD]) / (fast_data[ITEM_JPY] / fast_data[ITEM_CAD]) - 1;
      if(CHF) norm_data[ITEM_JPY] += (slow_data[ITEM_JPY] / slow_data[ITEM_CHF]) / (fast_data[ITEM_JPY] / fast_data[ITEM_CHF]) - 1;
    }
    
    values[i] = 0.0;
    if(Item_1 == ITEM_USD) values[i] += norm_data[ITEM_USD]; if(Item_2 == ITEM_USD) values[i] -= norm_data[ITEM_USD];
    if(Item_1 == ITEM_EUR) values[i] += norm_data[ITEM_EUR]; if(Item_2 == ITEM_EUR) values[i] -= norm_data[ITEM_EUR];
    if(Item_1 == ITEM_GBP) values[i] += norm_data[ITEM_GBP]; if(Item_2 == ITEM_GBP) values[i] -= norm_data[ITEM_GBP];
    if(Item_1 == ITEM_CHF) values[i] += norm_data[ITEM_CHF]; if(Item_2 == ITEM_CHF) values[i] -= norm_data[ITEM_CHF];
    if(Item_1 == ITEM_JPY) values[i] += norm_data[ITEM_JPY]; if(Item_2 == ITEM_JPY) values[i] -= norm_data[ITEM_JPY];   
    if(Item_1 == ITEM_AUD) values[i] += norm_data[ITEM_AUD]; if(Item_2 == ITEM_AUD) values[i] -= norm_data[ITEM_AUD]; 
    if(Item_1 == ITEM_CAD) values[i] += norm_data[ITEM_CAD]; if(Item_2 == ITEM_CAD) values[i] -= norm_data[ITEM_CAD];
    if(Item_1 == ITEM_NZD) values[i] += norm_data[ITEM_NZD]; if(Item_2 == ITEM_NZD) values[i] -= norm_data[ITEM_NZD];
  } 
  
  for(i = limit; i >= 0; i--){ 
    direct[i] = direct[i+1];
    if (values[i] > 0.0) {if (values[i] > values[i+1]) direct[i] = 2; else direct[i] = 1;}  
      else if (values[i] < 0.0) { if (values[i] < values[i+1]) direct[i] =-2; else direct[i] =-1;} 
    switch(direct[i]) {
      case -2: val_neg_dn[i] = 5; val_neg_up[i] = EMPTY_VALUE; val_pos_dn[i] = EMPTY_VALUE; val_pos_up[i] = EMPTY_VALUE; break; 
      case -1: val_neg_dn[i] = EMPTY_VALUE; val_neg_up[i] = 5; val_pos_dn[i] = EMPTY_VALUE; val_pos_up[i] = EMPTY_VALUE; break;
      case  1: val_neg_dn[i] = EMPTY_VALUE; val_neg_up[i] = EMPTY_VALUE; val_pos_dn[i] = 5; val_pos_up[i] = EMPTY_VALUE; break;
      case  2: val_neg_dn[i] = EMPTY_VALUE; val_neg_up[i] = EMPTY_VALUE; val_pos_dn[i] = EMPTY_VALUE; val_pos_up[i] = 5; break; 
      default: val_neg_dn[i] = EMPTY_VALUE; val_neg_up[i] = EMPTY_VALUE; val_pos_dn[i] = EMPTY_VALUE; val_pos_up[i] = EMPTY_VALUE;
    }   
  }
  return(0);
}

double Calc_Data(string instrument, int period, int index){
  double avg = 0.0, result = 0.0;
  if (Factor == 1) {result = iMA(instrument, 0, period, 0, MA_Method, MA_Price, index);}
    else if (Factor > 1) {
      for(int i = 0; i < period; i++) avg += iMA(instrument, 0, Factor * period - Factor, 0, MA_Method, MA_Price, index + i);
      result = avg / period;
    }
  return (result);
}