com.algoTrader.service.SimulationServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.algoTrader.service.SimulationServiceImpl.java

Source

/*******************************************************************************
 * 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.io.File;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.algoTrader.ServiceLocator;
import com.algoTrader.entity.Position;
import com.algoTrader.entity.Strategy;
import com.algoTrader.entity.StrategyImpl;
import com.algoTrader.entity.Transaction;
import com.algoTrader.entity.security.Security;
import com.algoTrader.enumeration.MarketDataType;
import com.algoTrader.enumeration.TransactionType;
import com.algoTrader.esper.io.CsvBarInputAdapterSpec;
import com.algoTrader.esper.io.CsvTickInputAdapterSpec;
import com.algoTrader.util.ConfigurationUtil;
import com.algoTrader.util.MyLogger;
import com.algoTrader.vo.MaxDrawDownVO;
import com.algoTrader.vo.MonthlyPerformanceVO;
import com.algoTrader.vo.PerformanceKeysVO;
import com.algoTrader.vo.SimulationResultVO;
import com.espertech.esperio.csv.CSVInputAdapterSpec;

public class SimulationServiceImpl extends SimulationServiceBase {

    private static final String LF = "\r\n";
    private static final String PCNT = "%";

    private static Logger logger = MyLogger.getLogger(SimulationServiceImpl.class.getName());

    private static NumberFormat format = NumberFormat.getInstance();
    private static int roundDigits = ConfigurationUtil.getBaseConfig().getInt("simulation.roundDigits");
    private static String dataSetType = ConfigurationUtil.getBaseConfig().getString("dataSource.dataSetType")
            .toUpperCase();
    private static MarketDataType marketDataType = MarketDataType.fromString(dataSetType);
    private static String dataSet = ConfigurationUtil.getBaseConfig().getString("dataSource.dataSet");
    private static DecimalFormat twoDigitFormat = new DecimalFormat("#,##0.00");
    private static DateFormat dateFormat = new SimpleDateFormat(" MMM-yy ");

    static {
        format.setMinimumFractionDigits(roundDigits);
    }

    protected void handleResetDB() throws Exception {

        // process all strategies
        Collection<Strategy> strategies = getStrategyDao().loadAll();
        for (Strategy strategy : strategies) {

            // delete all transactions except the initial CREDIT
            Collection<Transaction> transactions = strategy.getTransactions();
            Set<Transaction> toRemoveTransactions = new HashSet<Transaction>();
            Set<Transaction> toKeepTransactions = new HashSet<Transaction>();
            for (Transaction transaction : transactions) {
                if (transaction.getType().equals(TransactionType.CREDIT)) {
                    toKeepTransactions.add(transaction);
                } else {
                    toRemoveTransactions.add(transaction);
                }
            }
            getTransactionDao().remove(toRemoveTransactions);
            strategy.setTransactions(toKeepTransactions);

            // delete all positions and references to them
            Collection<Position> positions = strategy.getPositions();
            getPositionDao().remove(positions);
            strategy.setPositions(new HashSet<Position>());

            getStrategyDao().update(strategy);
        }

    }

    protected void handleInputCSV() {

        getRuleService().initCoordination(StrategyImpl.BASE);

        List<Security> securities = getSecurityDao().findSecuritiesOnActiveWatchlist();
        for (Security security : securities) {

            if (security.getIsin() == null) {
                logger.warn("no data available for " + security.getSymbol());
                continue;
            }

            File file = new File("results/" + marketDataType.toString().toLowerCase() + "data/" + dataSet + "/"
                    + security.getIsin() + ".csv");

            if (file == null || !file.exists()) {
                logger.warn("no data available for " + security.getSymbol());
                continue;
            } else {
                logger.info("data available for " + security.getSymbol());
            }

            CSVInputAdapterSpec spec;
            if (MarketDataType.TICK.equals(marketDataType)) {
                spec = new CsvTickInputAdapterSpec(file);
            } else if (MarketDataType.BAR.equals(marketDataType)) {
                spec = new CsvBarInputAdapterSpec(file);
            } else {
                throw new SimulationServiceException("incorrect parameter for dataSetType: " + marketDataType);
            }

            getRuleService().coordinate(StrategyImpl.BASE, spec);

            logger.debug("started simulation for security " + security.getSymbol());
        }

        getRuleService().startCoordination(StrategyImpl.BASE);
    }

    protected SimulationResultVO handleRunByUnderlayings() {

        long startTime = System.currentTimeMillis();

        // must call resetDB through ServiceLocator in order to get a transaction
        ServiceLocator.serverInstance().getSimulationService().resetDB();

        // init all activatable strategies
        List<Strategy> strategies = getStrategyDao().findAutoActivateStrategies();
        for (Strategy strategy : strategies) {
            getRuleService().initServiceProvider(strategy.getName());
            getRuleService().deployAllModules(strategy.getName());
        }

        // feed the ticks
        inputCSV();

        // get the results
        SimulationResultVO resultVO = getSimulationResultVO(startTime);

        // destroy all service providers
        for (Strategy strategy : strategies) {
            getRuleService().destroyServiceProvider(strategy.getName());
        }

        // reset all configuration variables
        ConfigurationUtil.resetConfig();

        // run a garbage collection
        System.gc();

        return resultVO;
    }

    @SuppressWarnings("unchecked")
    protected SimulationResultVO handleGetSimulationResultVO(long startTime) {

        PerformanceKeysVO performanceKeys = (PerformanceKeysVO) getRuleService().getLastEvent(StrategyImpl.BASE,
                "CREATE_PERFORMANCE_KEYS");
        List<MonthlyPerformanceVO> monthlyPerformances = getRuleService().getAllEvents(StrategyImpl.BASE,
                "KEEP_MONTHLY_PERFORMANCE");
        MaxDrawDownVO maxDrawDown = (MaxDrawDownVO) getRuleService().getLastEvent(StrategyImpl.BASE,
                "CREATE_MAX_DRAW_DOWN");

        // assemble the result
        SimulationResultVO resultVO = new SimulationResultVO();
        resultVO.setMins(((double) (System.currentTimeMillis() - startTime)) / 60000);
        resultVO.setDataSet(dataSet);
        resultVO.setNetLiqValue(getStrategyDao().getPortfolioNetLiqValueDouble());
        resultVO.setMonthlyPerformanceVOs(monthlyPerformances);
        resultVO.setPerformanceKeysVO(performanceKeys);
        resultVO.setMaxDrawDownVO(maxDrawDown);
        return resultVO;
    }

    protected void handleSimulateWithCurrentParams() throws Exception {

        SimulationResultVO resultVO = ServiceLocator.serverInstance().getSimulationService().runByUnderlayings();
        logMultiLineString(convertStatisticsToLongString(resultVO));
    }

    protected void handleOptimizeSingleParamLinear(String strategyName, String parameter, double min, double max,
            double increment) throws Exception {

        for (double i = min; i <= max; i += increment) {

            ConfigurationUtil.getStrategyConfig(strategyName).setProperty(parameter, format.format(i));

            SimulationResultVO resultVO = ServiceLocator.serverInstance().getSimulationService()
                    .runByUnderlayings();
            logMultiLineString(convertStatisticsToLongString(resultVO));
        }
    }

    @SuppressWarnings("unchecked")
    private static String convertStatisticsToLongString(SimulationResultVO resultVO) {

        StringBuffer buffer = new StringBuffer();
        buffer.append("execution time (min): " + (new DecimalFormat("0.00")).format(resultVO.getMins()) + LF);
        buffer.append("dataSet: " + dataSet + LF);

        double netLiqValue = resultVO.getNetLiqValue();
        buffer.append("netLiqValue=" + twoDigitFormat.format(netLiqValue) + LF);

        List<MonthlyPerformanceVO> monthlyPerformanceVOs = resultVO.getMonthlyPerformanceVOs();
        double maxDrawDownM = 0d;
        double bestMonthlyPerformance = Double.NEGATIVE_INFINITY;
        if (monthlyPerformanceVOs != null) {
            StringBuffer dateBuffer = new StringBuffer("month-year:         ");
            StringBuffer performanceBuffer = new StringBuffer("MonthlyPerformance: ");
            for (MonthlyPerformanceVO monthlyPerformanceVO : monthlyPerformanceVOs) {
                maxDrawDownM = Math.min(maxDrawDownM, monthlyPerformanceVO.getValue());
                bestMonthlyPerformance = Math.max(bestMonthlyPerformance, monthlyPerformanceVO.getValue());
                dateBuffer.append(dateFormat.format(monthlyPerformanceVO.getDate()));
                performanceBuffer
                        .append(StringUtils.leftPad(twoDigitFormat.format(monthlyPerformanceVO.getValue() * 100), 6)
                                + "% ");
            }
            buffer.append(dateBuffer.toString() + LF);
            buffer.append(performanceBuffer.toString() + LF);
        }

        PerformanceKeysVO performanceKeys = resultVO.getPerformanceKeysVO();
        MaxDrawDownVO maxDrawDownVO = resultVO.getMaxDrawDownVO();
        if (performanceKeys != null && maxDrawDownVO != null) {
            buffer.append("n=" + performanceKeys.getN());
            buffer.append(" avgM=" + twoDigitFormat.format(performanceKeys.getAvgM() * 100) + PCNT);
            buffer.append(" stdM=" + twoDigitFormat.format(performanceKeys.getStdM() * 100) + PCNT);
            buffer.append(" avgY=" + twoDigitFormat.format(performanceKeys.getAvgY() * 100) + PCNT);
            buffer.append(" stdY=" + twoDigitFormat.format(performanceKeys.getStdY() * 100) + PCNT);
            buffer.append(" sharpRatio=" + twoDigitFormat.format(performanceKeys.getSharpRatio()) + LF);

            buffer.append("maxDrawDownM=" + twoDigitFormat.format(-maxDrawDownM * 100) + PCNT);
            buffer.append(" bestMonthlyPerformance=" + twoDigitFormat.format(bestMonthlyPerformance * 100) + PCNT);
            buffer.append(" maxDrawDown=" + twoDigitFormat.format(maxDrawDownVO.getAmount() * 100) + PCNT);
            buffer.append(
                    " maxDrawDownPeriod=" + twoDigitFormat.format(maxDrawDownVO.getPeriod() / 86400000) + "days");
            buffer.append(
                    " colmarRatio=" + twoDigitFormat.format(performanceKeys.getAvgY() / maxDrawDownVO.getAmount()));
        }

        return buffer.toString();
    }

    private static void logMultiLineString(String input) {

        String[] lines = input.split(LF);
        for (String line : lines) {
            logger.info(line);
        }
    }
}