Java tutorial
/******************************************************************************* * Copyright (c) 2013 Andy Flury. * http://code.google.com/p/algo-trader * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v2.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html ******************************************************************************/ package com.algoTrader.service; import java.math.BigDecimal; import java.util.List; import org.apache.commons.math.MathException; import org.apache.log4j.Logger; import com.algoTrader.ServiceLocator; import com.algoTrader.entity.Position; import com.algoTrader.entity.Strategy; import com.algoTrader.entity.security.Security; import com.algoTrader.entity.trade.MarketOrderImpl; import com.algoTrader.entity.trade.Order; import com.algoTrader.enumeration.Side; import com.algoTrader.util.MyLogger; import com.algoTrader.util.RoundUtil; import com.espertech.esper.client.EventBean; import com.espertech.esper.client.UpdateListener; public class PositionServiceImpl extends PositionServiceBase { private static Logger logger = MyLogger.getLogger(PositionServiceImpl.class.getName()); @Override protected void handleClosePosition(int positionId) throws Exception { Position position = getPositionDao().load(positionId); reducePosition(positionId, Math.abs(position.getQuantity())); } @Override protected void handleReducePosition(int positionId, long quantity) throws Exception { Position position = getPositionDao().findByIdFetched(positionId); Security security = position.getSecurity(); Order order = new MarketOrderImpl(); order.setSecurity(security); order.setStrategy(position.getStrategy()); order.setQuantity(Math.abs(quantity)); order.setSide((position.getQuantity() > 0) ? Side.SELL : Side.BUY); getOrderService().sendOrder(order); // only remove the security from the watchlist, if the position is closed if (!position.isOpen()) { ServiceLocator.commonInstance().getMarketDataService() .removeFromWatchlist(position.getStrategy().getName(), security.getId()); } } @Override protected void handleSetExitValue(int positionId, double exitValue, boolean force) throws MathException { Position position = getPositionDao().load(positionId); // there needs to be a position if (position == null) { throw new PositionServiceException("position does not exist: " + positionId); } // in generall there should have been set a exitValue on creation of the position if (!force && position.getExitValue() == null) { logger.warn("no exitValue was set for position: " + positionId); return; } // we don't want to set the exitValue to (almost)Zero if (exitValue <= 0.05) { logger.warn("setting of exitValue below 0.05 is prohibited: " + exitValue); return; } // in generall, exit value should not be set higher than existing exitValue if (!force) { if (position.isShort() && exitValue > position.getExitValueDouble()) { logger.warn("exit value " + exitValue + " is higher than existing exit value " + position.getExitValue() + " of short position " + positionId); return; } else if (position.isLong() && exitValue < position.getExitValueDouble()) { logger.warn("exit value " + exitValue + " is lower than existing exit value " + position.getExitValue() + " of long position " + positionId); return; } } // exitValue cannot be lower than currentValue double currentValue = position.getSecurity().getCurrentValue().doubleValue(); if (position.isShort() && exitValue < currentValue) { throw new PositionServiceException("ExitValue (" + exitValue + ") for short-position " + position.getId() + " is lower than currentValue: " + currentValue); } else if (position.isLong() && exitValue > currentValue) { throw new PositionServiceException("ExitValue (" + exitValue + ") for long-position " + position.getId() + " is higher than currentValue: " + currentValue); } position.setExitValue(exitValue); getPositionDao().update(position); logger.info("set exit value " + position.getSecurity().getSymbol() + " to " + exitValue); } @Override protected void handleSetMargin(int positionId) throws Exception { Position position = getPositionDao().load(positionId); setMargin(position); } @Override protected void handleSetMargin(Position position) throws Exception { Security security = position.getSecurity(); double marginPerContract = security.getMargin(); if (marginPerContract != 0) { long numberOfContracts = Math.abs(position.getQuantity()); BigDecimal totalMargin = RoundUtil.getBigDecimal(marginPerContract * numberOfContracts); position.setMaintenanceMargin(totalMargin); getPositionDao().update(position); Strategy strategy = position.getStrategy(); int percent = (int) (strategy.getAvailableFundsDouble() / strategy.getNetLiqValueDouble() * 100.0); if (strategy.getAvailableFundsDouble() >= 0) { logger.info("set margin for " + security.getSymbol() + " to " + RoundUtil.getBigDecimal(marginPerContract) + " total margin: " + RoundUtil.getBigDecimal(strategy.getMaintenanceMarginDouble()) + " availableFunds: " + RoundUtil.getBigDecimal(strategy.getAvailableFundsDouble()) + " (" + percent + "% of balance)"); } else { logger.warn("set margin for " + security.getSymbol() + " to " + RoundUtil.getBigDecimal(marginPerContract) + " total margin: " + RoundUtil.getBigDecimal(strategy.getMaintenanceMarginDouble()) + " availableFunds: " + RoundUtil.getBigDecimal(strategy.getAvailableFundsDouble()) + " (" + percent + "% of balance)"); } } } @Override protected void handleSetMargins() throws Exception { List<Position> positions = getPositionDao().findOpenPositions(); for (Position position : positions) { setMargin(position); } } public static class ClosePositionSubscriber { public void update(int positionId) { long startTime = System.currentTimeMillis(); logger.debug("closePosition start"); ServiceLocator.serverInstance().getPositionService().closePosition(positionId); logger.debug("closePosition end (" + (System.currentTimeMillis() - startTime) + "ms execution)"); } } public static class SetExitValueSubscriber { public void update(int positionId, double exitValue) { long startTime = System.currentTimeMillis(); logger.debug("setExitValue start"); ServiceLocator.commonInstance().getPositionService().setExitValue(positionId, exitValue, false); logger.debug("setExitValue end (" + (System.currentTimeMillis() - startTime) + "ms execution)"); } } public static class SetMarginsListener implements UpdateListener { @Override public void update(EventBean[] newEvents, EventBean[] oldEvents) { long startTime = System.currentTimeMillis(); logger.debug("setMargins start"); ServiceLocator.serverInstance().getPositionService().setMargins(); logger.debug("setMargins end (" + (System.currentTimeMillis() - startTime) + "ms execution)"); } } }