//Cálculo de correlación entre dos pares
//Ref.:
//http://www.vitutor.com/estadistica/bi/coeficiente_correlacion.html
//http://www.vitutor.com/estadistica/bi/covarianza.html
//
package jforex;

import java.util.*;

import com.dukascopy.api.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class correlacion implements IStrategy {
    enum Precios { OPEN, CLOSE, HIGH, LOW };

    @Configurable("Par 1")      public Instrument eInst1 = Instrument.EURUSD;
    @Configurable("Par 2")      public Instrument eInst2 = Instrument.GBPUSD;
    @Configurable("Periodo")    public Period ePeriodo = Period.DAILY;
    @Configurable("Intervalos") public int eIntervalos = 10;
    @Configurable("OfferSide")  public OfferSide eOfferSide = OfferSide.BID;
    @Configurable("Filter")     public Filter eFilter = Filter.WEEKENDS;
    @Configurable("Precio")     public Precios ePrecio = Precios.CLOSE;
    private IEngine engine;
    private IConsole console;
    private IHistory history;
    private IContext context;
    private IIndicators indicators;
    private IUserInterface userInterface;
    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");   
     
    public void onStart(IContext context) throws JFException {
        this.engine = context.getEngine();
        this.console = context.getConsole();
        this.history = context.getHistory();
        this.context = context;
        this.indicators = context.getIndicators();
        this.userInterface = context.getUserInterface();
        
        Calendar cal = Calendar.getInstance();
        double[] medias = new double[2];
        double[] desviaciones = new double[2];        
        double[] precios = new double[2];
        double covarianza = 0;
        double correlacion = 0;
        List<List<IBar>> barras = new ArrayList();
      
        barras.add( history.getBars(eInst1, ePeriodo, eOfferSide, eFilter, eIntervalos, history.getBarStart(ePeriodo, cal.getTimeInMillis()), 0) );
        barras.add( history.getBars(eInst2, ePeriodo, eOfferSide, eFilter, eIntervalos, history.getBarStart(ePeriodo, cal.getTimeInMillis()), 0) );

        if (barras.get(0).size() != barras.get(1).size()){
            console.getErr().println("Error número de barras distintos");
            context.stop();  
        }
        if (barras.get(0).size() != eIntervalos){
            console.getErr().println("Error número de barras");
            context.stop();  
        }
        
        for(int i = 0;i<barras.get(0).size(); i++){
           switch(ePrecio){
           case OPEN:  precios[0] = barras.get(0).get(i).getOpen();
                       precios[1] = barras.get(1).get(i).getOpen();
                       break;
           case CLOSE: precios[0] = barras.get(0).get(i).getClose();
                       precios[1] = barras.get(1).get(i).getClose();
                       break;
           case HIGH:  precios[0] = barras.get(0).get(i).getHigh();
                       precios[1] = barras.get(1).get(i).getHigh();
                       break;
           case LOW:   precios[0] = barras.get(0).get(i).getLow();
                       precios[1] = barras.get(1).get(i).getLow();
                       break;
           }                                                                  
            console.getOut().println(String.format("Vela %s. %s: %s %.4f - %s: %s %.4f",i, 
                                                   eInst1.toString(), dateFormat.format(barras.get(0).get(i).getTime()), precios[0], 
                                                   eInst2.toString(), dateFormat.format(barras.get(1).get(i).getTime()), precios[1]));
            medias[0]       += precios[0];
            medias[1]       += precios[1];
            covarianza      += ( precios[0] * precios[1] );
            desviaciones[0] += ( precios[0] * precios[0] );
            desviaciones[1] += ( precios[1] * precios[1] );
        }
        medias[0] = medias[0] / barras.get(0).size();
        medias[1] = medias[1] / barras.get(1).size();
        covarianza = ( covarianza/barras.get(0).size() ) - ( medias[0] * medias[1] );
       
        console.getOut().println(String.format("Medias %s: %.4f - %s: %.4f", eInst1.toString(), medias[0], eInst2.toString(), medias[1]));
        console.getOut().println(String.format("Covarianza  %f" ,covarianza));
        
        desviaciones[0] = Math.sqrt( ( desviaciones[0]/barras.get(0).size() ) - (medias[0]*medias[0]) );
        desviaciones[1] = Math.sqrt( ( desviaciones[1]/barras.get(1).size() ) - (medias[1]*medias[1]) );
        
        console.getOut().println(String.format("Desviaciones %s: %f - %s: %f", eInst1.toString(), desviaciones[0], eInst2.toString(), desviaciones[1]));
        
        correlacion = covarianza / ( desviaciones[0] * desviaciones[1] );
         
        console.getOut().println(String.format("Correlación: %.4f", correlacion)); 
        
        context.stop();  
    }

    public void onAccount(IAccount account) throws JFException {
    }

    public void onMessage(IMessage message) throws JFException {
    }

    public void onStop() throws JFException {
    }

    public void onTick(Instrument instrument, ITick tick) throws JFException {
    }
    
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
        
        
    }
}