/*
 * Copyright (c) 2009 Dukascopy (Suisse) SA. All Rights Reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * -Redistribution of source code must retain the above copyright notice, this
 *  list of conditions and the following disclaimer.
 * 
 * -Redistribution in binary form must reproduce the above copyright notice, 
 *  this list of conditions and the following disclaimer in the documentation
 *  and/or other materials provided with the distribution.
 * 
 * Neither the name of Dukascopy (Suisse) SA or the names of contributors may 
 * be used to endorse or promote products derived from this software without 
 * specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any kind. ALL 
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. DUKASCOPY (SUISSE) SA ("DUKASCOPY")
 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL DUKASCOPY OR ITS LICENSORS BE LIABLE FOR ANY LOST 
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, 
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY 
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 
 * EVEN IF DUKASCOPY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * 
 * This software is provided "AS IS," without a warranty of any kind. ALL 
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. THIS SOFTWARE DEVELOPER
 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL THE DEVELOPER OR ITS LICENSORS BE LIABLE FOR ANY LOST 
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, 
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY 
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 
 * EVEN IF THE DEVELOPER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 */
package singlejartest;

import com.dukascopy.api.*;
import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IOrder.State;

public class SlippageTestStrategy implements IStrategy {
    private IEngine engine = null;
    private int tagCounter = 0;
    private IConsole console;
    
    int counter = 0;

    public SlippageTestStrategy() {
    }
    
    public void onStart(IContext context) throws JFException {
        try {
            engine = context.getEngine();
            this.console = context.getConsole();
            console("Started");
            // buildState(instrument);
        } catch (RuntimeException e) {
            e.printStackTrace(this.console.getOut());
            throw e;
        } catch (Exception e) {
            e.printStackTrace(this.console.getOut());
        }
    }

    public void onStop() throws JFException {
        try {
            console("Stopped");
        } catch (RuntimeException e) {
            e.printStackTrace(this.console.getOut());
            throw e;
        }
        
    }

    public void onTick(Instrument instrument, ITick tick) throws JFException {
        for (IOrder order : engine.getOrders()) {
            //console("Closing Order " + order.getLabel());
            if (order.getState() == State.FILLED)
                order.close();
        }

        counter++;

        OrderCommand cmd = counter % 2 == 0 ? OrderCommand.BUY : OrderCommand.SELL;
        double expectedPrice = cmd == OrderCommand.BUY ? tick.getAsk() : tick.getBid();
        double volume = 0.01;
        double price = 0.0;
        int slippage = -1;
        IOrder order = engine.submitOrder(getLabel(instrument), instrument, cmd, volume, price, slippage);
        for (int i = 0; i < 5; i++) {
            order.waitForUpdate(1000);
            if (order.getState() != State.OPENED)
                break;
        }
        if (order.getState() == State.FILLED) {
            double diffPips = (order.isLong() ? 1.0 : -1.0) * toPips(instrument, expectedPrice - order.getOpenPrice());
            console(instrument.toString() + "," + diffPips);
        }
    }

    public void onBar(Instrument instrument, Period period, IBar askBar, IBar bidBar) {
    }

    protected String getLabel(Instrument instrument) {
        String label = instrument.name();
        label = label.substring(0, 2) + label.substring(3, 5);
        label = label + (tagCounter++);
        label = label.toLowerCase();
        return label;
    }
    
    public void onMessage(IMessage message) throws JFException {
    }

    public void onAccount(IAccount account) throws JFException {
    }

    private void console(String s) {
        console.getOut().println(s);
    }

    private double toPips(Instrument instrument, double diff) {
        return diff / instrument.getPipValue();
    }

}