package jforex;

import java.util.*;

import com.dukascopy.api.*;
public class ReadBars implements IStrategy {

    private InnerStrategy ReadBarsAUDcad;
    private InnerStrategy ReadBarsAUDchf;   
    private InnerStrategy ReadBarsAUDnzd;
    private InnerStrategy ReadBarsAUDusd;
    
    private InnerStrategy ReadBarsEURaud;
    private InnerStrategy ReadBarsEURcad;
    private InnerStrategy ReadBarsEURchf;
    private InnerStrategy ReadBarsEURgbp;    
    private InnerStrategy ReadBarsEURnzd;
    private InnerStrategy ReadBarsEURusd;
    
    private InnerStrategy ReadBarsGBPaud;
    private InnerStrategy ReadBarsGBPcad;
    private InnerStrategy ReadBarsGBPchf;   
    private InnerStrategy ReadBarsGBPnzd;
    private InnerStrategy ReadBarsGBPusd;
    
    private InnerStrategy ReadBarsNZDcad;
    private InnerStrategy ReadBarsNZDchf;
    private InnerStrategy ReadBarsNZDusd;
    
    private InnerStrategy ReadBarsUSDcad;
    private InnerStrategy ReadBarsUSDchf;
    
    private InnerStrategy ReadBarsCADchf;
  
    
    private IConsole console;

    
    @Override
    public void onStart(IContext context) throws JFException {
        ReadBarsAUDcad = new InnerStrategy();       
        ReadBarsAUDcad.instrument = Instrument.AUDCAD;
        ReadBarsAUDcad.onStart(context);
        
        ReadBarsAUDchf = new InnerStrategy();      
        ReadBarsAUDchf.instrument = Instrument.AUDCHF;
        ReadBarsAUDchf.onStart(context);
              
        ReadBarsAUDnzd = new InnerStrategy();     
        ReadBarsAUDnzd.instrument = Instrument.AUDNZD;
        ReadBarsAUDnzd.onStart(context);
         
        ReadBarsAUDusd = new InnerStrategy();    
        ReadBarsAUDusd.instrument = Instrument.AUDUSD;      
        ReadBarsAUDusd.onStart(context);              
       
        
    
        ReadBarsEURaud = new InnerStrategy();       
        ReadBarsEURaud.instrument = Instrument.EURAUD;
        ReadBarsEURaud.onStart(context);
                
        ReadBarsEURcad = new InnerStrategy();       
        ReadBarsEURcad.instrument = Instrument.EURCAD;
        ReadBarsEURcad.onStart(context);
                 
        ReadBarsEURchf = new InnerStrategy();      
        ReadBarsEURchf.instrument = Instrument.EURCHF;        
        ReadBarsEURchf.onStart(context);
        
        ReadBarsEURgbp = new InnerStrategy();      
        ReadBarsEURgbp.instrument = Instrument.EURGBP;  
        ReadBarsEURgbp.onStart(context);  
        
        ReadBarsEURnzd = new InnerStrategy();     
        ReadBarsEURnzd.instrument = Instrument.EURNZD;    
        ReadBarsEURnzd.onStart(context);
         
        ReadBarsEURusd = new InnerStrategy();    
        ReadBarsEURusd.instrument = Instrument.EURUSD;      
        ReadBarsEURusd.onStart(context);       
        
        ReadBarsGBPaud = new InnerStrategy();       
        ReadBarsGBPaud.instrument = Instrument.GBPAUD;
        ReadBarsGBPaud.onStart(context);
                 
        ReadBarsGBPcad = new InnerStrategy();       
        ReadBarsGBPcad.instrument = Instrument.GBPCAD;
        ReadBarsGBPcad.onStart(context);
                 
        ReadBarsGBPchf = new InnerStrategy();      
        ReadBarsGBPchf.instrument = Instrument.GBPCHF;
        ReadBarsGBPchf.onStart(context);
         
        ReadBarsGBPnzd = new InnerStrategy();     
        ReadBarsGBPnzd.instrument = Instrument.GBPNZD;        
        ReadBarsGBPnzd.onStart(context);
        
        ReadBarsGBPusd = new InnerStrategy();    
        ReadBarsGBPusd.instrument = Instrument.GBPUSD;      
        ReadBarsGBPusd.onStart(context);
    
        ReadBarsNZDcad = new InnerStrategy();       
        ReadBarsNZDcad.instrument = Instrument.NZDCAD;
        ReadBarsNZDcad.onStart(context);
         
        ReadBarsNZDchf = new InnerStrategy();      
        ReadBarsNZDchf.instrument = Instrument.NZDCHF;
        ReadBarsNZDchf.onStart(context);
         
        ReadBarsNZDusd = new InnerStrategy();    
        ReadBarsNZDusd.instrument = Instrument.NZDUSD;
        ReadBarsNZDusd.onStart(context);
        
        ReadBarsUSDcad = new InnerStrategy();       
        ReadBarsUSDcad.instrument = Instrument.USDCAD;
        ReadBarsUSDcad.onStart(context);
                 
        ReadBarsUSDchf = new InnerStrategy();      
        ReadBarsUSDchf.instrument = Instrument.USDCHF;
        ReadBarsUSDchf.onStart(context);       
       
        ReadBarsCADchf = new InnerStrategy();      
        ReadBarsCADchf.instrument = Instrument.CADCHF;    
        ReadBarsCADchf.onStart(context);
    
    
    
    
    }    
    @Override
    public void onAccount(IAccount account) throws JFException {
        ReadBarsAUDcad.onAccount(account);
        ReadBarsAUDchf.onAccount(account);        
        ReadBarsAUDnzd.onAccount(account);
        ReadBarsAUDusd.onAccount(account);
        
        ReadBarsEURaud.onAccount(account);
        ReadBarsEURcad.onAccount(account);
        ReadBarsEURchf.onAccount(account);
        ReadBarsEURgbp.onAccount(account);       
        ReadBarsEURnzd.onAccount(account);
        ReadBarsEURusd.onAccount(account);
        
        ReadBarsGBPaud.onAccount(account);
        ReadBarsGBPcad.onAccount(account);
        ReadBarsGBPchf.onAccount(account);
        ReadBarsGBPnzd.onAccount(account);
        ReadBarsGBPusd.onAccount(account);
        
        ReadBarsNZDcad.onAccount(account);
        ReadBarsNZDchf.onAccount(account);
        ReadBarsNZDusd.onAccount(account);
        
        ReadBarsUSDcad.onAccount(account);
        ReadBarsUSDchf.onAccount(account);
        
        ReadBarsCADchf.onAccount(account);
    } 
    
    @Override
    public void onMessage(IMessage message) throws JFException {    
        ReadBarsAUDcad.onMessage(message);
        ReadBarsAUDchf.onMessage(message);        
        ReadBarsAUDnzd.onMessage(message);
        ReadBarsAUDusd.onMessage(message);
        
        ReadBarsEURaud.onMessage(message);
        ReadBarsEURcad.onMessage(message);
        ReadBarsEURchf.onMessage(message);
        ReadBarsEURgbp.onMessage(message);       
        ReadBarsEURnzd.onMessage(message);
        ReadBarsEURusd.onMessage(message);
        
        ReadBarsGBPaud.onMessage(message);
        ReadBarsGBPcad.onMessage(message);
        ReadBarsGBPchf.onMessage(message);
        ReadBarsGBPnzd.onMessage(message);
        ReadBarsGBPusd.onMessage(message);
        
        ReadBarsNZDcad.onMessage(message);
        ReadBarsNZDchf.onMessage(message);
        ReadBarsNZDusd.onMessage(message);
        
        ReadBarsUSDcad.onMessage(message);
        ReadBarsUSDchf.onMessage(message);
        
        ReadBarsCADchf.onMessage(message);
    }
        
    @Override
    public void onStop() throws JFException {    
        ReadBarsAUDcad.onStop();
        ReadBarsAUDchf.onStop();       
        ReadBarsAUDnzd.onStop();
        ReadBarsAUDusd.onStop();
        
        ReadBarsEURaud.onStop();
        ReadBarsEURcad.onStop();
        ReadBarsEURchf.onStop();
        ReadBarsEURgbp.onStop();       
        ReadBarsEURnzd.onStop();
        ReadBarsEURusd.onStop();
        
        ReadBarsGBPaud.onStop();
        ReadBarsGBPcad.onStop();
        ReadBarsGBPchf.onStop();       
        ReadBarsGBPnzd.onStop();
        ReadBarsGBPusd.onStop();
        
        ReadBarsNZDcad.onStop();
        ReadBarsNZDchf.onStop();
        ReadBarsNZDusd.onStop();
        
        ReadBarsUSDcad.onStop();
        ReadBarsUSDchf.onStop();
        
        ReadBarsCADchf.onStop();                  
    }
    
    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {}
    
    @Override
   public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {        
        try {
        ReadBarsAUDcad.onBar(instrument, period, askBar, bidBar);
            } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        }
      try {  
        ReadBarsAUDchf.onBar(instrument, period, askBar, bidBar);
            } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        }       
      try {
        ReadBarsAUDnzd.onBar(instrument, period, askBar, bidBar);
            } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        }
         try {
        ReadBarsAUDusd.onBar(instrument, period, askBar, bidBar);        
        } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        }
    
       try {               
       ReadBarsEURaud.onBar(instrument, period, askBar, bidBar);
          } catch(JFException e) {
            e.printStackTrace();               
        }
        try {
        ReadBarsEURcad.onBar(instrument, period, askBar, bidBar);
          } catch(JFException e) {
            e.printStackTrace();               
        }
        try {
        ReadBarsEURchf.onBar(instrument, period, askBar, bidBar);
          } catch(JFException e) {
            e.printStackTrace();               
        }
        try {
        ReadBarsEURgbp.onBar(instrument, period, askBar, bidBar);
          } catch(JFException e) {
            e.printStackTrace();               
        }       
        try {
        ReadBarsEURnzd.onBar(instrument, period, askBar, bidBar);
          } catch(JFException e) {
            e.printStackTrace();                
        }
        try {
        ReadBarsEURusd.onBar(instrument, period, askBar, bidBar);
        
        } catch(JFException e) {
            e.printStackTrace();               
        }
        
        try {       
        ReadBarsGBPaud.onBar(instrument, period, askBar, bidBar);
        } catch(JFException e) {
            e.printStackTrace();                
        }
        try {
        ReadBarsGBPcad.onBar(instrument, period, askBar, bidBar);
        } catch(JFException e) {
            e.printStackTrace();                
        }
        try {
        ReadBarsGBPchf.onBar(instrument, period, askBar, bidBar);
        } catch(JFException e) {
            e.printStackTrace();                
        }        
        try {
        ReadBarsGBPnzd.onBar(instrument, period, askBar, bidBar);
        } catch(JFException e) {
            e.printStackTrace();                
        }
        try {
        ReadBarsGBPusd.onBar(instrument, period, askBar, bidBar);
        } catch(JFException e) {
            e.printStackTrace();                
        }
        
        try {            
        ReadBarsNZDcad.onBar(instrument, period, askBar, bidBar);
         } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        }
        try {
        ReadBarsNZDchf.onBar(instrument, period, askBar, bidBar);
         } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        }       
        try {        
        ReadBarsNZDusd.onBar(instrument, period, askBar, bidBar);        
        } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        }
        
        try{
        ReadBarsUSDcad.onBar(instrument, period, askBar, bidBar);
         } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        }
        try {
        ReadBarsUSDchf.onBar(instrument, period, askBar, bidBar); 
         } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        } 
        
        try {
        ReadBarsCADchf.onBar(instrument, period, askBar, bidBar); 
         } catch(JFException e) {
            e.printStackTrace();
                console.getErr().println(e);
        }
    
    }
   
   
}

class InnerStrategy implements IStrategy {
    private IEngine engine;
    private IConsole console;
    private IHistory history;
    private IContext context;
    private IIndicators indicators;
    private IUserInterface userInterface;
    
    
    
    public Instrument instrument;
    public Period defaultPeriod = Period.THIRTY_MINS;
    @Configurable("MIX Pairs")
    public Set<Instrument> instruments = new HashSet<Instrument>( 
            Arrays.asList(new Instrument[] {                
               Instrument.AUDCAD,Instrument.AUDCHF,Instrument.AUDNZD,Instrument.AUDUSD,
                    Instrument.EURAUD,Instrument.EURCAD,Instrument.EURCHF,Instrument.EURGBP, Instrument.EURNZD,Instrument.EURUSD,
                            Instrument.GBPAUD,Instrument.GBPCAD,Instrument.GBPCHF,Instrument.GBPNZD,Instrument.GBPUSD,
                                    Instrument.NZDCAD,Instrument.NZDCHF,Instrument.NZDUSD,
                                            Instrument.USDCAD,Instrument.USDCHF,
                                                Instrument.CADCHF
            }) 
    );   
    
    
     private boolean executed;
     private double _candles5high;
     private double _candles5low;
     private Tick LastTick =  null ;   
     private List<IOrder> AllPositions =  null ;
     private List<IOrder> PendingPositions =  null ;
     private List<IOrder> OpenPositions =  null ;
     private Candle LastAskCandle =  null ;
     private Candle LastBidCandle =  null ; 
    
    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();
        
        subscriptionInstrumentCheck(instrument);
        
        ITick lastITick = context.getHistory().getLastTick(instrument);
        LastTick = new Tick(lastITick, instrument);
        IBar bidBar = context.getHistory().getBar(instrument, defaultPeriod, OfferSide.BID, 1);
        IBar askBar = context.getHistory().getBar(instrument, defaultPeriod, OfferSide.ASK, 1);
        LastAskCandle = new Candle(askBar, defaultPeriod, instrument, OfferSide.ASK);
        LastBidCandle = new Candle(bidBar, defaultPeriod, instrument, OfferSide.BID);     
       
        Thread fecthBars = new Thread(new Runnable() {
            @Override
                public void run() {
                    try {
                        GetHistoricalCandles();
                            
                        } catch (Exception e) {
                            console.getErr().println(Thread.currentThread().getName() + " " + e);
                    }
                }
            });
                fecthBars.start();
    }
    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 {       
        updateVariables(instrument);   
    }


  private  void GetHistoricalCandles()throws JFException {   
       subscriptionInstrumentCheck(instrument);

    try {
        
        long lastTickTime = history.getLastTick(instrument).getTime();
        long lastBarTime = history.getBarStart(defaultPeriod, lastTickTime); 
        
     if (!executed) {     
             
            history.readBars(instrument, Period.THIRTY_MINS, OfferSide.BID, Filter.WEEKENDS, 5, lastBarTime, 0,
                    new LoadingDataListener() {
                        public void newTick(Instrument instrument, long time, double ask, double bid, double askVol, double bidVol) {}
                        public void newBar(Instrument instrument, Period period, OfferSide side, long time, double open, double close, double low, double high, double vol) {
                              
                               
                            double maxHigh = Double.MIN_VALUE;
                            double minLow = Double.MAX_VALUE;
                             
                             if(maxHigh <  LastBidCandle.getHigh()){
                                 maxHigh = LastBidCandle.getHigh();
                             }
                             if(minLow > LastBidCandle.getLow()){
                                 minLow = LastBidCandle.getLow();
                             }                 
                                _candles5high =  maxHigh;
                                _candles5low =  minLow;
                                    
                            }                      
                 }, new LoadingProgressListener() {
                        public void dataLoaded(long startTime, long endTime, long currentTime, String information) {}   
                        public void loadingFinished(boolean allDataLoaded, long startTime, long endTime, long currentTime) {
                            if (allDataLoaded) {                                                           
                                 executed = true;
                                  console.getOut().println(instrument+" High: "+_candles5high+" Low: "+_candles5low);
                            } else {
                                return;
                            }
                           
                        }
                        public boolean stopJob() {
                            return false;                            
                        }
                    });
                          
       }
        } catch (JFException e) {
            e.printStackTrace();
            console.getErr().println(e);
        }    
    }
    
    public void subscriptionInstrumentCheck(Instrument instrument) {
        try {
              if (!context.getSubscribedInstruments().contains(instrument)) {
                  Set<Instrument> instruments = new HashSet<Instrument>();
                  instruments.add(instrument);
                  context.setSubscribedInstruments(instruments, true);
                  Thread.sleep(1000);
              }
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
  }
        
        
   private void updateVariables(Instrument instrument) {
        try {           
            AllPositions = engine.getOrders(instrument);
            List<IOrder> listMarket = new ArrayList<IOrder>();
            for (IOrder order: AllPositions) {
                if (order.getState().equals(IOrder.State.FILLED)){
                    listMarket.add(order);
                }
            }
            List<IOrder> listPending = new ArrayList<IOrder>();
            for (IOrder order: AllPositions) {
                if (order.getState().equals(IOrder.State.OPENED)){
                    listPending.add(order);
                }
            }
            OpenPositions = listMarket;
            PendingPositions = listPending;
        } catch(JFException e) {
            e.printStackTrace();
        }
    }
}

class Candle  {

    IBar bar;
    Period period;
    Instrument instrument;
    OfferSide offerSide;

    public Candle(IBar bar, Period period, Instrument instrument, OfferSide offerSide) {
        this.bar = bar;
        this.period = period;
        this.instrument = instrument;
        this.offerSide = offerSide;
    }

    public Period getPeriod() {
        return period;
    }

    public void setPeriod(Period period) {
        this.period = period;
    }

    public Instrument getInstrument() {
        return instrument;
    }

    public void setInstrument(Instrument instrument) {
        this.instrument = instrument;
    }

    public OfferSide getOfferSide() {
        return offerSide;
    }

    public void setOfferSide(OfferSide offerSide) {
        this.offerSide = offerSide;
    }

    public IBar getBar() {
        return bar;
    }

    public void setBar(IBar bar) {
        this.bar = bar;
    }

    public long getTime() {
        return bar.getTime();
    }

    public double getOpen() {
        return bar.getOpen();
    }

    public double getClose() {
        return bar.getClose();
    }

    public double getLow() {
        return bar.getLow();
    }

    public double getHigh() {
        return bar.getHigh();
    }

    public double getVolume() {
        return bar.getVolume();
    }
}
class Tick {

    private ITick tick;
    private Instrument instrument;

    public Tick(ITick tick, Instrument instrument){
        this.instrument = instrument;
        this.tick = tick;
    }

    public Instrument getInstrument(){
       return  instrument;
    }

    public double getAsk(){
       return  tick.getAsk();
    }

    public double getBid(){
       return  tick.getBid();
    }

    public double getAskVolume(){
       return  tick.getAskVolume();
    }

    public double getBidVolume(){
        return tick.getBidVolume();
    }

   public long getTime(){
       return  tick.getTime();
    }

   public ITick getTick(){
       return  tick;
    }
}