package JForex.myStrategies;

import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.*;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;



/**
 * Strategy not complete !!!
 * but can be used as a template
 * 
 * @author JLongo
 */
public class MyFirstStrategy implements IStrategy {
    
    //Strategy base objects
    private IContext myContext          = null;
    private IAccount myAccount          = null; 
    private IEngine myEngine            = null;
    private IOrder myOrder              = null; 
    private IHistory myHistory          = null;
    private IIndicators myIndicators    = null;
    private IConsole myConsole          = null;
    

    /**
     * Strategy changeable parameters
     */
    
    /** 
     * Instrument object from API with default value
     */
    @Configurable("Currency Pair to use:")
    public Instrument myInstrument = Instrument.EURUSD;  
    /**
     * Period object from API
     */
    @Configurable("Time frame to use:")
    public Period myPeriod = Period.ONE_MIN;  
    /**
     * Default position value - we are very poor :)
     */
    @Configurable("Position value to use:")
    public double myPositionValue = 0.001; 
    /**
     * Default value for Stop Loss - don't risk too much
     */
    @Configurable("Stop Loss to use:")
    public int myStopLoss = 10; 
    /**
     * Default value for Take Profit - we want to get it here
     */
    @Configurable("Take Profit to use")
    public int myTakeProfit = 20;  
    
    /**
     * Fixed variables - You can made them configurable if you want
     */
    private IEngine.OrderCommand myOrderDirection = null;
    private boolean myCanTrade = false;
    /**
     * Here i'm using generic variables for indicators. 
     * In this example we use variables for oscillator type indicators where
     * their values are bouncing between defined and know values. Examples of
     * this are RSI, RVI, CCI, Stochastics etc.
     * Other indicators may need other variables.
     * You can see information about the indicators and their parameters and
     * return values here:
     *http://www.dukascopy.com/client/javadoc/com/dukascopy/api/IIndicators.html
     */
    private int myIndicatorHighValue = 70;
    private int myIndicatorLowValue = 30;
    private int myIndicatorPeriod = 14;
    
    

    /**
     * Executed at strategy start.
     * 
     * @param context - Plataform interface
     * @throws JFException
     */
    @Override 
    public void onStart(IContext context) throws JFException {
        
        myContext       = context; // i like my variables :)
        myEngine        = myContext.getEngine();
        myAccount       = myContext.getAccount();
        myHistory       = myContext.getHistory();
        myIndicators    = myContext.getIndicators();
        myConsole       = context.getConsole();
              
    }// end onStart

    /**
     * Executed on every tick received
     * 
     * @param instrument - instrumment of the tick received
     * @param tick - tick data
     * @throws JFException
     */
    @Override
    public void onTick(Instrument instrument, ITick tick) throws JFException {
              
        
    }// end onTick

    /**
     * Executed on every bar completed
     * 
     * @param instrument - instrument for the bar received 
     * @param period - period of the bar received
     * @param askBar - OHLC and volume for the ask bar
     * @param bidBar - OHLC and volume for the bid bar
     * @throws JFException
     */
    @Override
    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) throws JFException {
                
        
    }// end onBar

    /**
     * Executed everytime a message is received from stream data 
     * 
     * @param message - the message itself
     * @throws JFException
     */
    @Override
    public void onMessage(IMessage message) throws JFException {       
        if (message.getType() == IMessage.Type.ORDER_FILL_OK ||
                message.getType() == IMessage.Type.ORDER_SUBMIT_OK ||
                message.getType() == IMessage.Type.SENDING_ORDER){
            myCanTrade = false;
        }
        if (message.getType() == IMessage.Type.ORDER_CLOSE_REJECTED ||
                message.getType() == IMessage.Type.ORDER_FILL_REJECTED ||
                message.getType() == IMessage.Type.ORDER_SUBMIT_REJECTED ||
                message.getType() == IMessage.Type.ORDER_CLOSE_OK){
            myCanTrade = true;
        }
         
        
    }// end onMessage

    /**
     * Executed on every account change
     * 
     * @param account - updated account data
     * @throws JFException
     */
    @Override
    public void onAccount(IAccount account) throws JFException {

        
    }// end onAccount

    /**
     * Executed when the strategy stops
     * 
     * @throws JFException
     */
    @Override
    public void onStop() throws JFException {
        
        
    }// end onStop
    
    /**
     * Returns the value for order label in the format AAABBB_YYYYMMDDHHMM
     * where AAABBB is the pair and followed by the date and time
     * 
     * @param instrument - the instrument in use
     * @return 
     * @throws JFException 
     */
    private String getLabel (Instrument instrument) throws JFException{
        String label;
        String stripSlash = instrument.toString();
        String[] stripped = stripSlash.split("/");
        String instrumentName = stripped[0] + stripped[1];
        Calendar now = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
        
        String nowYear = "" + now.get(Calendar.YEAR);
        String nowMonth =  "00" + now.get(Calendar.MONTH); //leading 0 if needed
        String nowDay = "00" + now.get(Calendar.DAY_OF_MONTH);
        String nowHours = "00" + now.get(Calendar.HOUR_OF_DAY);
        String nowMinutes = "00" + now.get(Calendar.MINUTE);
        
        label = instrumentName + "_" + nowYear +
                nowMonth.substring(nowMonth.length()- 2) + // get only the last 
                nowDay.substring(nowDay.length() - 2) +  // two digits of 
                nowHours.substring(nowHours.length() - 2) + // the string
                nowMinutes.substring(nowMinutes.length() - 2);
        return label;
    }// end getLabel
    
    /**
     * Executes buy or sell orders and waits for final state and sets myCantrade
     * 
     * @param myOrderCommand - Sell or Buy
     * @param stopLossPrice - Price for StopLoss
     * @param takeProfitPrice - Price for Take profit
     * @throws JFException 
     */
    private void placeBuyorSell(OrderCommand myOrderCommand,
            double stopLossPrice, double takeProfitPrice) throws JFException{

        //buy @ price market and with 0.5 slippage
        if (myOrderCommand == OrderCommand.BUY && myCanTrade){
            myOrder = myEngine.submitOrder(getLabel(myInstrument), myInstrument, 
                    myOrderCommand, myPositionValue, 0, 0.5, stopLossPrice, 
                    takeProfitPrice);
        }
        //sell @ price market and with 0.5 slippage
        if (myOrderCommand == OrderCommand.SELL && myCanTrade){
            myOrder = myEngine.submitOrder(getLabel(myInstrument), myInstrument, 
                    myOrderCommand, myPositionValue, 0, 0.5, stopLossPrice,
                    takeProfitPrice);
        }
        /* This code was better implemented in onMessage method/function
         * //wait for final order state
         *while(myOrder.getState() != IOrder.State.CANCELED || 
         *        myOrder.getState() != IOrder.State.FILLED ) 
         *    myOrder.waitForUpdate();
         * // set if we can or can't submit trades after 
         * if (myOrder.getState() == IOrder.State.CANCELED) myCanTrade = true;
         * if (myOrder.getState() == IOrder.State.FILLED) myCanTrade = false;
         * 
         */
    }// end placeBuyorSell
 
}
