package jforex;

import java.util.*;

import com.dukascopy.api.*;

public class StochStrategy implements IStrategy {
    
    // my variables
       
    static int LONG = 1;
    static int SHORT = -1;
    static int FLAT = 0;

    int CNT = 1;
    

     
    @Configurable("Instrument") public Instrument currInstrument = Instrument.EURUSD;   
    @Configurable("MA Length") public int maLength = 200;
    
    @Configurable("Fast K Length") public int fastKLength = 13;
    @Configurable("Slow K Length") public int slowKLength = 5;
    @Configurable("Slow D Length") public int slowDLength = 5;
    
    @Configurable("ATR Length") public int atrLength = 13;
    @Configurable("Period") public Period currPeriod = Period.ONE_HOUR;
    
    @Configurable("Top Stoch ThreasHold") public double topStoch = 80.0;
    @Configurable("Bot Stoch ThreadHold") public double botStoch = 20.0;
    @Configurable("Profit Factor") public int profitFactor = 2;
    
    
    private List<IOrder>currentOrders = new ArrayList<IOrder>();
     
    private IEngine engine;
    private IConsole console;
    private IHistory history;
    private IContext context;
    private IIndicators indicators;
    private IUserInterface userInterface;
    private IAccount account;
    private JFUtils utils;
    
    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();
        this.account = context.getAccount();
    }

    public void onAccount(IAccount Passedaccount) 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 {
        
        int T;
        int D;
        int P;
        

        double stopPrice;
        double targetPrice;
        
        IOrder I;
        
        if (period == currPeriod && instrument == currInstrument) {
         
            double ema1 = indicators.ema(currInstrument,currPeriod,OfferSide.BID,IIndicators.AppliedPrice.CLOSE,maLength,1);
            double ema2 = indicators.ema(currInstrument,currPeriod,OfferSide.BID,IIndicators.AppliedPrice.CLOSE,maLength,2);
            
            double atr1 = indicators.atr(currInstrument,currPeriod,OfferSide.BID,atrLength,1) * 10.0;
            
            double[] stoch1 = indicators.stoch(currInstrument,currPeriod,OfferSide.BID,fastKLength,slowKLength,IIndicators.MaType.SMA,slowDLength,IIndicators.MaType.SMA,1);
            double[] stoch2 = indicators.stoch(currInstrument,currPeriod,OfferSide.BID,fastKLength,slowKLength,IIndicators.MaType.SMA,slowDLength,IIndicators.MaType.SMA,2);
            
            D = FLAT;
            if (ema1 > ema2) D = LONG;
            else if (ema1 < ema2) D = SHORT;
            
            T = FLAT;
            if (stoch1[1] > topStoch && stoch1[1] < stoch2[1]) T = SHORT;
            else if (stoch1[1] < botStoch && stoch1[1] > stoch2[1]) T = LONG;
           
            P = FLAT;
            if (bidBar.getClose() > ema1) P = LONG;
            else if (bidBar.getClose() < ema1) P = SHORT;
    
            try {
                
                if (D == LONG && T == LONG && P == LONG) {
                
                       
                   
                    
                    stopPrice = bidBar.getLow() - atr1;
                    targetPrice = bidBar.getClose() + profitFactor*( bidBar.getClose() - stopPrice);
                    
                    double stopD = (bidBar.getClose() - stopPrice)/currInstrument.getPipValue();
                    double targetD = (targetPrice - bidBar.getClose())/currInstrument.getPipValue();
                    
                    console.getInfo().println("BUY ");
                    console.getInfo().println("atr "+atr1/currInstrument.getPipValue()); 
                    
                    console.getInfo().println("stop d "+stopD);  
                    console.getInfo().println("target d "+targetD);  
                    
                    console.getInfo().println("--------------------");        
                    I = engine.submitOrder(getNextLabel(),currInstrument,IEngine.OrderCommand.BUY,getLOTS(),0,3,stopPrice,targetPrice);
                    console.getInfo().println("order id "+I.getId());
                
                } else if (D == SHORT && T == SHORT && P == SHORT) {
                
                    stopPrice = bidBar.getHigh() + atr1;
                    targetPrice = bidBar.getClose() - profitFactor*( stopPrice - bidBar.getClose());
                    
                    double stopD = (stopPrice - bidBar.getClose())/currInstrument.getPipValue();
                    double targetD = (bidBar.getClose() - targetPrice)/currInstrument.getPipValue();
                    
                    console.getInfo().println("SELL ");
                    console.getInfo().println("atr "+atr1/currInstrument.getPipValue()); 
       
                    console.getInfo().println("stop d "+stopD);  
                    console.getInfo().println("target d "+targetD);
                    console.getInfo().println("--------------------");
                    I = engine.submitOrder(getNextLabel(),currInstrument,IEngine.OrderCommand.SELL,getLOTS(),0,3,stopPrice,targetPrice);
                     console.getInfo().println("order id "+I.getId());
                
                }
            
                    
            } catch (JFException E) {
                  console.getInfo().println(E.toString());
          } finally {         
              return;
          }    
            
            
              
        }
    }
    
    
   

    //////////////////
    //////////////////
    //////////////////
    
    private String getNextLabel() {
      
      String Z;
      
      CNT++;
      Z = currInstrument.name();
      Z = Z.substring(0,2) + Z.subSequence(3,5);
      Z = Z + (CNT++);
      

      return(Z);

    }
    
    //////////////////
    //////////////////
    //////////////////
    
    private double getLOTS() {
        
        return (0.01);
        /*
        double A = account.getEquity();
        
                 //console.getInfo().println(A);
                 try {
                 A = utils.convert(currInstrument, Instrument.fromString("GBP/USD"), A);              
                 //console.getInfo().println(A);
                 return(0.01);
                 } catch (JFException E) {
                     
                      //console.getInfo().println(E.toString());
                      return(0.01);
                 } finally {         
                      return(0.001);
                  }      
        */       
    }
    
    //////////////////
    //////////////////
    //////////////////
    
  
}