package org.marketcetera.photon.actions;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.Callable;
import org.apache.commons.lang.StringUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.marketcetera.client.Client;
import org.marketcetera.client.ClientManager;
import org.marketcetera.core.instruments.UnderlyingSymbolSupport;
import org.marketcetera.core.position.ImmutablePositionSupport;
import org.marketcetera.core.position.PositionEngine;
import org.marketcetera.core.position.PositionEngineFactory;
import org.marketcetera.core.position.PositionKey;
import org.marketcetera.marketdata.core.manager.NoMarketDataProvidersAvailable;
import org.marketcetera.messagehistory.ReportHolder;
import org.marketcetera.messagehistory.TradeReportsHistory;
import org.marketcetera.photon.*;
import org.marketcetera.photon.marketdata.IMarketDataManager;
import org.marketcetera.trade.ReportBase;
import org.marketcetera.trade.ReportBaseImpl;
import org.marketcetera.util.log.SLF4JLoggerProxy;
import org.marketcetera.util.misc.ClassVersion;
import ca.odell.glazedlists.EventList;
import com.google.common.collect.Maps;
/* $License$ */
/**
* Job that retrieves trading history from ORS.
*
* @author <a href="mailto:will@marketcetera.com">Will Horn</a>
* @version $Id: RetrieveTradingHistoryJob.java 16880 2014-04-15 22:32:14Z colin $
* @since 1.5.0
*/
@ClassVersion("$Id: RetrieveTradingHistoryJob.java 16880 2014-04-15 22:32:14Z colin $")
public class RetrieveTradingHistoryJob
extends Job
{
/**
* Constructor.
*/
public RetrieveTradingHistoryJob() {
super(Messages.RETRIEVE_TRADING_HISTORY_JOB_NAME.getText());
}
@Override
protected IStatus run(IProgressMonitor monitor)
{
try {
String timeString = StringUtils.trimToNull(PhotonPlugin.getDefault().getPreferenceStore().getString(PhotonPreferences.TRADING_HISTORY_START_TIME));
// this collection will hold the reports that we're going to return - the goal is to collect all reports
// since the lastOccurrence date plus any open orders that predate the lastOccurrence
final Set<ReportBase> allReports = new LinkedHashSet<ReportBase>();
TradeReportsHistory tradeReportsHistory = PhotonPlugin.getDefault().getTradeReportsHistory();
Client client = ClientManager.getInstance();
List<ReportBaseImpl> openReports = client.getOpenOrders();
Date positionDate = new Date();
if(timeString != null) {
TimeOfDay time = TimeOfDay.create(timeString);
if(time != null) {
// trade history is enabled, fetch reports since last occurrence
Date lastOccurrence = time.getLastOccurrence();
ReportBase[] reports = client.getReportsSince(lastOccurrence);
if(reports != null) {
allReports.addAll(Arrays.asList(reports));
}
// see if any of the openReports don't appear in the current list. if so, add them
if(openReports != null) {
for(ReportBase openReport : openReports) {
if(!allReports.contains(openReport)) {
allReports.add(openReport);
}
}
}
PhotonPlugin.getDefault().setSessionStartTime(lastOccurrence);
positionDate = lastOccurrence;
}
} else {
if(openReports != null) {
// Photon trade history is disabled, but we still need open orders
allReports.addAll(openReports);
}
}
tradeReportsHistory.resetMessages(new Callable<ReportBase[]>() {
@Override
public ReportBase[] call()
throws Exception
{
return allReports.toArray(new ReportBase[0]);
}
});
if(positionDate != null) {
Map<PositionKey<?>,BigDecimal> positions = Maps.<PositionKey<?>,BigDecimal> newHashMap(ClientManager.getInstance().getAllEquityPositionsAsOf(positionDate));
positions.putAll(ClientManager.getInstance().getAllOptionPositionsAsOf(positionDate));
positions.putAll(ClientManager.getInstance().getAllFuturePositionsAsOf(positionDate));
positions.putAll(ClientManager.getInstance().getAllCurrencyPositionsAsOf(positionDate));
EventList<ReportHolder> messages = tradeReportsHistory.getAllMessagesList();
ImmutablePositionSupport positionSupport = new ImmutablePositionSupport(positions);
IMarketDataManager marketDataManager = PhotonPlugin.getDefault().getMarketDataManager();
if(!marketDataManager.isRunning() && marketDataManager.isReconnecting()) {
long startTime = System.currentTimeMillis();
while(!marketDataManager.isRunning()) {
Thread.sleep(250);
if(System.currentTimeMillis()-60000>startTime) {
// forget it, I (kinda) quietly give up
break;
}
}
}
if(!marketDataManager.isRunning()) {
SLF4JLoggerProxy.warn(org.marketcetera.core.Messages.USER_MSG_CATEGORY,
"Position market data unavailable from the Market Data Nexus");
SLF4JLoggerProxy.warn(this,
"Position market data unavailable from the Market Data Nexus");
}
PhotonPositionMarketData positionMarketData = new PhotonPositionMarketData(marketDataManager.getMarketData());
UnderlyingSymbolSupport underlyingSymbolSupport = PhotonPlugin.getDefault().getUnderlyingSymbolSupport();
PositionEngine engine = PositionEngineFactory.createFromReportHolders(messages,
positionSupport,
positionMarketData,
underlyingSymbolSupport);
PhotonPlugin.getDefault().registerPositionEngine(engine);
}
} catch (Exception e) {
Messages.RETRIEVE_TRADING_HISTORY_JOB_ERROR.error(org.marketcetera.core.Messages.USER_MSG_CATEGORY);
Messages.RETRIEVE_TRADING_HISTORY_JOB_ERROR.error(this,
e);
if(e instanceof NoMarketDataProvidersAvailable) {
return Status.CANCEL_STATUS;
}
if(e instanceof RuntimeException) {
throw (RuntimeException)e;
} else {
// The callable above doesn't throw checked exceptions
throw new RuntimeException(e);
}
}
return Status.OK_STATUS;
}
}