/*******************************************************************************
* 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.net.ConnectException;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import com.quantcomponents.algo.IInputSeriesStreamer;
import com.quantcomponents.algo.IManagedRunnable;
import com.quantcomponents.algo.ISimulatedExecutionService;
import com.quantcomponents.algo.ITradingAgent;
import com.quantcomponents.algo.ITradingAgentExecution;
import com.quantcomponents.algo.InputSeriesStreamer;
import com.quantcomponents.core.model.IMutableSeries;
import com.quantcomponents.core.model.ISeries;
import com.quantcomponents.core.model.ISeriesPoint;
public class SimulatedTradingAgentExecution extends AbstractTradingAgentExecution implements ITradingAgentExecution, IManagedRunnable {
private static final long ALGO_START_WAIT_QUANTUM = 100;
volatile IInputSeriesStreamer inputSeriesStreamer;
public SimulatedTradingAgentExecution(ITradingAgent tradingAgent, ISimulatedExecutionService executionService) {
super(tradingAgent, executionService);
}
@SuppressWarnings("unchecked")
@Override
public void run() {
Map<String, IMutableSeries<Date, Double, ? extends ISeriesPoint<Date, Double>>> targetSeriesMap = new HashMap<String, IMutableSeries<Date, Double, ? extends ISeriesPoint<Date, Double>>>();
for (Map.Entry<String, ? extends ISeries<Date, Double, ? extends ISeriesPoint<Date, Double>>> entry : inputSeriesMap.entrySet()) {
targetSeriesMap.put(entry.getKey(), entry.getValue().createEmptyMutableSeries(entry.getValue().getPersistentID()));
}
this.inputSeriesStreamer = new InputSeriesStreamer(inputSeriesMap, targetSeriesMap);
Map<String, ? extends ISeries<Date, Double, ? extends ISeriesPoint<Date, Double>>> simulatedInputSeries = inputSeriesStreamer.getStreamingSeries();
((ISimulatedExecutionService) executionService).setInputSeries((Collection<ISeries<Date, Double, ? extends ISeriesPoint<Date, Double>>>) simulatedInputSeries.values());
try {
executionService.addPositionListener(this);
} catch (ConnectException e) {
logger.log(Level.SEVERE, "Exception while adding position listener", e);
}
try {
executionService.addOrderStatusListener(this);
} catch (ConnectException e) {
logger.log(Level.SEVERE, "Exception while adding order status listener", e);
}
tradingAgent.wire(simulatedInputSeries, outputSeries);
tradingAgent.setOrderReceiver(this);
Thread algoThread = new Thread(new Runnable() {
@Override
public void run() {
tradingAgent.run();
try {
executionService.removeOrderStatusListener(SimulatedTradingAgentExecution.this);
} catch (ConnectException e) {
logger.log(Level.SEVERE, "Exception while removing order status listener", e);
}
try {
executionService.removePositionListener(SimulatedTradingAgentExecution.this);
} catch (ConnectException e) {
logger.log(Level.SEVERE, "Exception while removing position listener", e);
}
}
});
algoThread.start();
while (tradingAgent.getRunningStatus() == RunningStatus.NEW) {
try {
Thread.sleep(ALGO_START_WAIT_QUANTUM);
} catch (InterruptedException e) {
logger.log(Level.WARNING, "Interrupted while waiting for algo to start", e);
}
}
inputSeriesStreamer.run();
tradingAgent.inputComplete();
try {
algoThread.join();
} catch (InterruptedException e) {
logger.log(Level.SEVERE, "Algo thread interrupted", e);
}
tradingAgent.unwire();
}
@Override
protected Date getCurrentTime() {
return inputSeriesStreamer.getLastTimestamp();
}
}