/******************************************************************************* * Copyright (c) 2013 Luigi Sgro. All rights reserved. This * program and the accompanying materials are made available under the terms of * the Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Luigi Sgro - initial API and implementation ******************************************************************************/ package com.quantcomponents.algo.service; import java.util.Collection; import java.util.Date; import java.util.Map; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.logging.Level; import java.util.logging.Logger; import com.quantcomponents.algo.ExecutionCreationException; import com.quantcomponents.algo.ExecutionType; import com.quantcomponents.algo.IExecutionService; import com.quantcomponents.algo.IManagedRunnable.RunningStatus; import com.quantcomponents.algo.ISimulatedExecutionServiceFactory; import com.quantcomponents.algo.ITradingAgent; import com.quantcomponents.algo.ITradingAgentExecution; import com.quantcomponents.algo.ITradingAgentFactory; import com.quantcomponents.algo.ITradingAgentHierarchyContainer; import com.quantcomponents.algo.ITradingManager; import com.quantcomponents.algo.TradingAgentBinding; import com.quantcomponents.algo.TradingAgentBindingHandle; import com.quantcomponents.algo.TradingAgentConfiguration; import com.quantcomponents.algo.TradingAgentConfigurationHandle; import com.quantcomponents.algo.TradingAgentExecutionHandle; import com.quantcomponents.algo.TradingAgentFactoryHandle; import com.quantcomponents.core.model.ISeries; import com.quantcomponents.core.model.ISeriesPoint; import com.quantcomponents.core.series.LinkedListSeries; import com.quantcomponents.core.utils.HostUtils; public class TradingManager implements ITradingManager { private static final Logger logger = Logger.getLogger(TradingManager.class.getName()); private volatile String name; private volatile ITradingAgentHierarchyContainer hierarchyContainer; private volatile IExecutionService liveExecutionService; private volatile ISimulatedExecutionServiceFactory simulatedExecutionServiceFactory; private volatile ExecutorService threadPool; public TradingManager() { name = "TradingManager@" + HostUtils.hostname(); } public void deactivate() { logger.log(Level.INFO, "Shutting down trading manager!"); } public void setHierarchyContainer(ITradingAgentHierarchyContainer hierarchyContainer) { this.hierarchyContainer = hierarchyContainer; } public void addTradingAgentFactory(ITradingAgentFactory factory) { hierarchyContainer.addTradingAgentFactory(factory); } public void removeTradingAgentFactory(ITradingAgentFactory factory) { hierarchyContainer.removeTradingAgentFactory(factory); } public void setLiveExecutionService(IExecutionService liveExecutionService) { logger.log(Level.INFO, "Setting LIVE execution service"); this.liveExecutionService = liveExecutionService; if (liveExecutionService != null) { name += "[" + liveExecutionService.toString() + "]"; } } public void resetLiveExecutionService(IExecutionService liveExecutionService) { if (this.liveExecutionService == liveExecutionService) { this.liveExecutionService = null; } } public void setSimulatedExecutionServiceFactory(ISimulatedExecutionServiceFactory simulatedExecutionServiceFactory) { logger.log(Level.INFO, "Setting SIMULATED execution service factory"); this.simulatedExecutionServiceFactory = simulatedExecutionServiceFactory; } public void resetSimulatedExecutionServiceFactory(ISimulatedExecutionServiceFactory simulatedExecutionServiceFactory) { if (this.simulatedExecutionServiceFactory == simulatedExecutionServiceFactory) { this.simulatedExecutionServiceFactory = null; } } public void setThreadPool(ExecutorService threadPool) { this.threadPool = threadPool; } @Override public Collection<TradingAgentFactoryHandle> getAllTradingAgentFactories() { return hierarchyContainer.getAllTradingAgentFactories(); } @Override public boolean isConfigurationValid(TradingAgentFactoryHandle factoryHandle, Properties configuration, Map<String, String> messages) { ITradingAgentFactory factory = retrieveFactory(factoryHandle); return factory.isConfigurationValid(configuration, messages); } @Override public TradingAgentConfigurationHandle createConfiguration(TradingAgentFactoryHandle factoryHandle, Properties properties, String name) { ITradingAgentFactory factory = retrieveFactory(factoryHandle); TradingAgentConfiguration configuration = new TradingAgentConfiguration(factory, properties); TradingAgentConfigurationHandle handle = new TradingAgentConfigurationHandle(name == null || name.equals("") ? configuration.toString() : name, factory.getInputSeriesNames()); hierarchyContainer.putTradingAgentConfiguration(handle, configuration, factoryHandle); return handle; } @Override public TradingAgentBindingHandle createBinding(TradingAgentConfigurationHandle configurationHandle, Map<String, ? extends ISeries<Date, Double, ISeriesPoint<Date, Double>>> inputSeries, String name) { TradingAgentConfiguration configuration = retrieveConfiguration(configurationHandle); TradingAgentBinding binding = new TradingAgentBinding(configuration, inputSeries); TradingAgentBindingHandle handle = new TradingAgentBindingHandle(name == null || name.equals("") ? binding.toString() : name); hierarchyContainer.putTradingAgentBinding(handle, binding, configurationHandle); return handle; } @SuppressWarnings("unchecked") @Override public Map<String, ISeries<Date, Double, ISeriesPoint<Date, Double>>> getBindingInputSeries(TradingAgentBindingHandle bindingHandle) { TradingAgentBinding binding = retrieveBinding(bindingHandle); return binding == null ? null : (Map<String, ISeries<Date, Double, ISeriesPoint<Date, Double>>>) binding.getInputSeries(); } @Override public TradingAgentExecutionHandle createExecution(TradingAgentBindingHandle bindingHandle, ExecutionType type) throws ExecutionCreationException { TradingAgentBinding binding = retrieveBinding(bindingHandle); ITradingAgentExecution execution; ITradingAgent tradingAgent = binding.getConfiguration().newTradingAgent(); if (!isExecutionTypeAvailable(type)) { throw new ExecutionCreationException(type.name() + " execution service not available"); } if (type == ExecutionType.LIVE){ execution = new TradingAgentExecution(tradingAgent, liveExecutionService); } else { execution = new SimulatedTradingAgentExecution(tradingAgent, simulatedExecutionServiceFactory.createSimulatedExecutionService()); } String executionOutputSeriesId = "output-" + execution.toString(); LinkedListSeries<Date, Double, ISeriesPoint<Date, Double>> outputSeries = new LinkedListSeries<Date, Double, ISeriesPoint<Date, Double>>(executionOutputSeriesId, false); execution.wire(binding.getInputSeries(), outputSeries); TradingAgentExecutionHandle handle = new TradingAgentExecutionHandle(execution.toString()); hierarchyContainer.putTradingAgentExecution(handle, execution, bindingHandle); return handle; } @Override public ISeries<Date, Double, ISeriesPoint<Date, Double>> getExecutionOutput(TradingAgentExecutionHandle executionHandle) { return hierarchyContainer.getTradingAgentExecution(executionHandle).getOutput(); } @Override public Properties getConfigurationProperties(TradingAgentConfigurationHandle tradingAgentConfigurationHandle) { return hierarchyContainer.getTradingAgentConfiguration(tradingAgentConfigurationHandle).getProperties(); } @Override public void removeExecution(TradingAgentExecutionHandle executionHandle) { ITradingAgentExecution execution = hierarchyContainer.removeTradingAgentExecution(executionHandle); if (execution == null) { throw new IllegalArgumentException("Handle: " + executionHandle + " does not correspont to an object"); } execution.kill(); } @Override public void removeBinding(TradingAgentBindingHandle bindingHandle) { hierarchyContainer.removeTradingAgentBinding(bindingHandle); } @Override public void removeConfiguration(TradingAgentConfigurationHandle configurationHandle) { hierarchyContainer.removeTradingAgentConfiguration(configurationHandle); } @Override public void startExecution(TradingAgentExecutionHandle executionHandle) { threadPool.execute(retrieveExecution(executionHandle)); } @Override public void pauseExecution(TradingAgentExecutionHandle executionHandle) { retrieveExecution(executionHandle).pause(); } @Override public void resumeExecution(TradingAgentExecutionHandle executionHandle) { retrieveExecution(executionHandle).resume(); } @Override public void killExecution(TradingAgentExecutionHandle executionHandle) { retrieveExecution(executionHandle).kill(); } @Override public RunningStatus getRunningStatus(TradingAgentExecutionHandle executionHandle) { return retrieveExecution(executionHandle).getRunningStatus(); } private ITradingAgentExecution retrieveExecution(TradingAgentExecutionHandle executionHandle) { ITradingAgentExecution execution = hierarchyContainer.getTradingAgentExecution(executionHandle); if (execution == null) { throw new IllegalArgumentException("Handle: " + execution + " does not correspont to an object"); } return execution; } private TradingAgentBinding retrieveBinding(TradingAgentBindingHandle bindingHandle) { TradingAgentBinding binding = hierarchyContainer.getTradingAgentBinding(bindingHandle); if (binding == null) { throw new IllegalArgumentException("Handle: " + bindingHandle + " does not correspont to an object"); } return binding; } private TradingAgentConfiguration retrieveConfiguration(TradingAgentConfigurationHandle configurationHandle) { TradingAgentConfiguration configuration = hierarchyContainer.getTradingAgentConfiguration(configurationHandle); if (configuration == null) { throw new IllegalArgumentException("Handle: " + configurationHandle + " does not correspont to an object"); } return configuration; } private ITradingAgentFactory retrieveFactory(TradingAgentFactoryHandle factoryHandle) { ITradingAgentFactory factory = hierarchyContainer.getTradingAgentFactory(factoryHandle); if (factory == null) { throw new IllegalArgumentException("Handle: " + factoryHandle + " does not correspont to an object"); } return factory; } @Override public String getPrettyName() { return name; } @Override public String toString() { return getPrettyName(); } @Override public Collection<TradingAgentConfigurationHandle> getChildren(TradingAgentFactoryHandle tradingAgentFactoryHandle) { return hierarchyContainer.getChildrenHandles(tradingAgentFactoryHandle); } @Override public TradingAgentFactoryHandle getParent(TradingAgentConfigurationHandle tradingAgentConfigurationHandle) { return hierarchyContainer.getParentHandle(tradingAgentConfigurationHandle); } @Override public Collection<TradingAgentBindingHandle> getChildren(TradingAgentConfigurationHandle tradingAgentConfigurationHandle) { return hierarchyContainer.getChildrenHandles(tradingAgentConfigurationHandle); } @Override public TradingAgentConfigurationHandle getParent(TradingAgentBindingHandle tradingAgentBindingHandle) { return hierarchyContainer.getParentHandle(tradingAgentBindingHandle); } @Override public Collection<TradingAgentExecutionHandle> getChildren(TradingAgentBindingHandle tradingAgentBindingHandle) { return hierarchyContainer.getChildrenHandles(tradingAgentBindingHandle); } @Override public TradingAgentBindingHandle getParent(TradingAgentExecutionHandle tradingAgentExecutionHandle) { return hierarchyContainer.getParentHandle(tradingAgentExecutionHandle); } @Override public boolean isExecutionTypeAvailable(ExecutionType type) { switch(type) { case LIVE: return liveExecutionService != null; case BACKTEST: return simulatedExecutionServiceFactory != null; default: return false; } } }