ch.algotrader.service.sim.SimulationOrderServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for ch.algotrader.service.sim.SimulationOrderServiceImpl.java

Source

/***********************************************************************************
 * AlgoTrader Enterprise Trading Framework
 *
 * Copyright (C) 2015 AlgoTrader GmbH - All rights reserved
 *
 * All information contained herein is, and remains the property of AlgoTrader GmbH.
 * The intellectual and technical concepts contained herein are proprietary to
 * AlgoTrader GmbH. Modification, translation, reverse engineering, decompilation,
 * disassembly or reproduction of this material is strictly forbidden unless prior
 * written permission is obtained from AlgoTrader GmbH
 *
 * Fur detailed terms and conditions consult the file LICENSE.txt or contact
 *
 * AlgoTrader GmbH
 * Aeschstrasse 6
 * 8834 Schindellegi
 ***********************************************************************************/
package ch.algotrader.service.sim;

import java.math.BigDecimal;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang.Validate;

import ch.algotrader.entity.Account;
import ch.algotrader.entity.marketData.MarketDataEventVO;
import ch.algotrader.entity.security.Security;
import ch.algotrader.entity.trade.Fill;
import ch.algotrader.entity.trade.LimitOrderI;
import ch.algotrader.entity.trade.OrderStatus;
import ch.algotrader.entity.trade.SimpleOrder;
import ch.algotrader.enumeration.Direction;
import ch.algotrader.enumeration.OrderServiceType;
import ch.algotrader.enumeration.Side;
import ch.algotrader.enumeration.Status;
import ch.algotrader.esper.EngineManager;
import ch.algotrader.ordermgmt.OrderBook;
import ch.algotrader.service.MarketDataCacheService;
import ch.algotrader.service.OrderExecutionService;

/**
 * @author <a href="mailto:aflury@algotrader.ch">Andy Flury</a>
 */
public class SimulationOrderServiceImpl implements SimulationOrderService {

    private final MarketDataCacheService marketDataCacheService;
    private final OrderBook orderBook;
    private final OrderExecutionService orderExecutionService;
    private final EngineManager engineManager;
    private final AtomicLong counter;
    private final AtomicLong seqnum;

    public SimulationOrderServiceImpl(final OrderBook orderBook, final OrderExecutionService orderExecutionService,
            final MarketDataCacheService marketDataCacheService, final EngineManager engineManager) {

        Validate.notNull(orderBook, "OpenOrderRegistry is null");
        Validate.notNull(orderExecutionService, "OrderExecutionService is null");
        Validate.notNull(marketDataCacheService, "MarketDataCacheService is null");
        Validate.notNull(engineManager, "EngineManager is null");

        this.orderBook = orderBook;
        this.orderExecutionService = orderExecutionService;
        this.engineManager = engineManager;
        this.marketDataCacheService = marketDataCacheService;
        this.counter = new AtomicLong(0);
        this.seqnum = new AtomicLong(0);
    }

    @Override
    public String sendOrder(SimpleOrder order) {

        Validate.notNull(order, "Order is null");

        String intId = order.getIntId();
        if (intId == null) {

            intId = getNextOrderId(order.getAccount());
            order.setIntId(intId);
        }

        this.orderBook.add(order);

        Date d = this.engineManager.getCurrentEPTime();

        // send ack
        OrderStatus ack = OrderStatus.Factory.newInstance();
        ack.setStatus(Status.SUBMITTED);
        ack.setIntId(order.getIntId());
        ack.setFilledQuantity(0);
        ack.setRemainingQuantity(order.getQuantity());
        ack.setExtDateTime(d);
        ack.setDateTime(d);
        ack.setOrder(order);
        ack.setSequenceNumber(this.seqnum.incrementAndGet());

        // send the orderStatus to the AlgoTrader Server
        this.orderExecutionService.handleOrderStatus(ack);

        // send full execution
        OrderStatus orderStatus = OrderStatus.Factory.newInstance();
        orderStatus.setStatus(Status.EXECUTED);
        orderStatus.setIntId(order.getIntId());
        orderStatus.setFilledQuantity(order.getQuantity());
        orderStatus.setRemainingQuantity(0);
        orderStatus.setExtDateTime(d);
        orderStatus.setDateTime(d);
        orderStatus.setOrder(order);
        orderStatus.setSequenceNumber(this.seqnum.incrementAndGet());

        // send the orderStatus to the AlgoTrader Server
        this.orderExecutionService.handleOrderStatus(orderStatus);

        // create one fill per order
        Fill fill = new Fill();
        fill.setDateTime(d);
        fill.setExtDateTime(d);
        fill.setSide(order.getSide());
        fill.setQuantity(order.getQuantity());
        fill.setPrice(getPrice(order));
        fill.setOrder(order);
        fill.setExecutionCommission(getExecutionCommission(order));
        fill.setClearingCommission(getClearingCommission(order));
        fill.setFee(getFee(order));

        this.orderExecutionService.handleFill(fill);

        return intId;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public BigDecimal getPrice(final SimpleOrder order) {

        Validate.notNull(order, "Order is null");

        if (order instanceof LimitOrderI) {

            // limit orders are executed at their limit price
            return ((LimitOrderI) order).getLimit();

        } else {

            Security security = order.getSecurity();

            // all other orders are executed the the market
            MarketDataEventVO marketDataEvent = this.marketDataCacheService
                    .getCurrentMarketDataEvent(security.getId());
            return marketDataEvent
                    .getMarketValue(Side.BUY.equals(order.getSide()) ? Direction.SHORT : Direction.LONG)
                    .setScale(security.getSecurityFamily().getScale(), BigDecimal.ROUND_HALF_UP);
        }

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public BigDecimal getExecutionCommission(final SimpleOrder order) {

        Validate.notNull(order, "Order is null");

        return null;

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public BigDecimal getClearingCommission(final SimpleOrder order) {

        Validate.notNull(order, "Order is null");

        return null;

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public BigDecimal getFee(final SimpleOrder order) {

        Validate.notNull(order, "Order is null");

        return null;

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getNextOrderId(final Account account) {

        long n = counter.incrementAndGet();
        return "sim" + n + ".0";
    }

    @Override
    public void validateOrder(SimpleOrder order) {

        // do nothing
    }

    @Override
    public String cancelOrder(SimpleOrder order) {

        throw new UnsupportedOperationException("cancel order not supported in simulation");
    }

    @Override
    public String modifyOrder(SimpleOrder order) {

        throw new UnsupportedOperationException("modify order not supported in simulation");
    }

    @Override
    public String getOrderServiceType() {

        return OrderServiceType.SIMULATION.name();
    }

}