package com.activequant.backtesting.reporting;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.TimeZone;
import org.jfree.chart.ChartUtilities;
import com.activequant.archive.hbase.HBaseArchiveFactory;
import com.activequant.backtesting.ArchiveStreamToOHLCIterator;
import com.activequant.backtesting.FastStreamer;
import com.activequant.backtesting.IBFXFeeCalculator;
import com.activequant.backtesting.OrderEventListener;
import com.activequant.domainmodel.AlgoConfig;
import com.activequant.domainmodel.OHLCV;
import com.activequant.domainmodel.TimeFrame;
import com.activequant.domainmodel.TimeStamp;
import com.activequant.domainmodel.streaming.PNLChangeEvent;
import com.activequant.domainmodel.streaming.StreamEvent;
import com.activequant.domainmodel.streaming.StreamEventIterator;
import com.activequant.domainmodel.trade.event.OrderFillEvent;
import com.activequant.domainmodel.trade.order.OrderSide;
import com.activequant.interfaces.archive.IArchiveFactory;
import com.activequant.interfaces.archive.IArchiveReader;
import com.activequant.interfaces.transport.ITransportFactory;
import com.activequant.timeseries.CSVExporter;
import com.activequant.timeseries.ChartUtils;
import com.activequant.timeseries.DoubleColumn;
import com.activequant.timeseries.TSContainer2;
import com.activequant.timeseries.TSContainerMethods;
import com.activequant.timeseries.TypedColumn;
import com.activequant.trading.PositionRiskCalculator;
import com.activequant.transport.memory.InMemoryTransportFactory;
import com.activequant.utils.CsvMapWriter;
import com.activequant.utils.FileUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
/**
* This is a very narrow implementation at the moment. As it is written in a
* client project, this might or might not work for your use case.
*
* @author GhostRider
*
*/
public class TransactionInputToReport {
private String fileName;
private String targetFolder = "./reports2";
private String reportCurrency;
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
private Properties transactionCount = new Properties();
private void increaseTransactionCount(String tid) {
int value = 0;
if (transactionCount.containsKey(tid))
value = Integer.parseInt(transactionCount.getProperty(tid));
transactionCount.put(tid, "" + (value + 1));
}
public TransactionInputToReport(String transactionsFile, String configFile, String tgt, String archiveServer)
throws Exception {
if (tgt != null)
targetFolder = tgt;
this.fileName = transactionsFile;
Properties properties = new Properties();
if (configFile != null)
properties.load(new FileInputStream(configFile));
IArchiveFactory archFac = new HBaseArchiveFactory(archiveServer);
IArchiveReader archReader = archFac.getReader(TimeFrame.MINUTES_1);
System.out.println("ArchiveReader fetched.");
String instrumentsInSim = properties.getProperty("instrumentsInSim", "PI_EURUSD,PI_EURGBP");
TimeFrame timeFrame = TimeFrame.valueOf(properties.getProperty("resolution", "HOURS_1"));
String simStart = properties.getProperty("simStart", "20120101");
String simEnd = properties.getProperty("simEnd", "20120205");
String reportId = properties.getProperty("reportId", "NOT-SET-IN-CONFIG-FILE");
//
TimeStamp startTimeStamp = new TimeStamp(sdf.parse(simStart));
TimeStamp endTimeStamp = new TimeStamp(sdf.parse(simEnd));
//
TSContainerMethods tcm = new TSContainerMethods();
@SuppressWarnings("rawtypes")
List<StreamEventIterator> streamIters = new ArrayList<StreamEventIterator>();
// initialize the market data replay streams.
List<String> tidList = new ArrayList<String>();
List<TypedColumn> colList = new ArrayList<TypedColumn>();
String[] tids = instrumentsInSim.split(",");
for (String tid : tids) {
if (!tid.startsWith("PI_")) {
tid = "PI_" + tid;
}
tidList.add(tid);
colList.add(new DoubleColumn());
ArchiveStreamToOHLCIterator a = new ArchiveStreamToOHLCIterator(tid, TimeFrame.MINUTES_1, startTimeStamp,
endTimeStamp, archReader);
// no shifting, as PiTrading's candles are timestamped with end of
// minute instead of beginning of minute like proper
a.setOffset(0L);
streamIters.add(a);
}
TSContainer2 refRates = new TSContainer2("REFRATES", tidList, colList, timeFrame.getNanoseconds());
// initialize the transaction file streamer.
TransactionFileStreamIterator tfsi = new TransactionFileStreamIterator(transactionsFile);
streamIters.add(tfsi);
//
// initialize the fast streamer
@SuppressWarnings("unchecked")
FastStreamer fs = new FastStreamer(streamIters.toArray(new StreamEventIterator[] {}));
//
CSVFileFillExporter fillExporter = new CSVFileFillExporter();
//
ITransportFactory transFac = new InMemoryTransportFactory();
//
// pos risk calc listens to executions and price events.
PositionRiskCalculator prc = new PositionRiskCalculator(null);
prc.setTransportFactory(transFac);
// pnl monitor listens to risk events .. these come from the position
// risk calculator
PNLMonitor pnlMonitor = new PNLMonitor(transFac, timeFrame);
OrderEventListener oel = new OrderEventListener();
IBFXFeeCalculator feeCalculator = new IBFXFeeCalculator();
oel.setFeeCalculator(feeCalculator);
//
// //////////////////
while (fs.moreDataInPipe()) {
StreamEvent se = fs.getOneFromPipes();
System.out.println(se.getTimeStamp().getDate());
if (se instanceof OrderFillEvent) {
OrderFillEvent ofe = (OrderFillEvent) se;
ofe.setOptionalInstId("PI_"+ofe.getOptionalInstId());
feeCalculator.updateRefRate(ofe.getOptionalInstId().substring(3), ofe.getFillPrice());
// order event listener also holds the fee calculator
oel.eventFired(ofe);
PNLChangeEvent pce = prc.execution(ofe.getTimeStamp(), ofe.getOptionalInstId(),
ofe.getFillPrice(), ofe.getSide().getSide() * ofe.getFillAmount());
increaseTransactionCount(ofe.getOptionalInstId());
} else if (se instanceof OHLCV) {
OHLCV o = (OHLCV) se;
System.out.println(o.toString());
// use a zero-change execution to push in the price.
PNLChangeEvent pce = prc.execution(o.getTimeStamp(), o.getMdiId(), o.getClose(), 0.0);
// create a fake order fill event, so that we have a valuation
// price ...
OrderFillEvent ofe = new OrderFillEvent();
ofe.setOptionalInstId(o.getMdiId());
ofe.setFillAmount(0.0);
// just set something.
ofe.setSide(OrderSide.BUY);
ofe.setFillPrice(o.getClose());
ofe.setTimeStamp(o.getTimeStamp());
oel.eventFired(ofe);
refRates.setValue(o.getMdiId(), o.getTimeStamp(), o.getClose());
//
}
// track the pnl change in USD.
//
}
List<String> enrichedTransactions = feeCalculator.getRows();
FileUtils.writeLines(enrichedTransactions, new FileOutputStream(targetFolder + File.separator
+ "enriched_transactions.csv"));
System.out.println("*************** REPLAY DONE ");
// ///////////////////
TSContainer2 tsc = pnlMonitor.getCumulatedTSContainer();
// //////////////
new File(targetFolder).mkdirs();
fillExporter.export(targetFolder, oel.getFillEvents());
// generate PNL report
TSContainer2 pnlContainer = pnlMonitor.getCumulatedTSContainer();
FileOutputStream fout;
fout = new FileOutputStream(targetFolder + File.separator + "refrates.csv");
CSVExporter c = new CSVExporter(fout, refRates);
c.write();
fout.close();
fout = new FileOutputStream(targetFolder + File.separator + "pnl.csv");
c = new CSVExporter(fout, pnlContainer);
c.write();
fout.close();
// generate a PNL chart.
ChartUtilities.saveChartAsPNG(new File(targetFolder + File.separator + "pnl.png"), pnlMonitor.getStaticChart(),
800, 600);
// calculate the cash positions ... beware: for currency pairs, we have
// two cash positions!
TSContainer2 posDeltaOverTime = oel.getChangeOverTime();
TSContainer2 executionPricesOverTime = oel.getExecutionOverTime();
TSContainer2 deltaCashPositionsOverTime = calcCashPositions(posDeltaOverTime, executionPricesOverTime);
fout = new FileOutputStream(targetFolder + File.separator + "cash_positions_delta.csv");
c = new CSVExporter(fout, deltaCashPositionsOverTime);
c.write();
fout.close();
//
TSContainer2 inflatedCashPositionSeries = resampleSeries(deltaCashPositionsOverTime, TimeFrame.HOURS_1,
startTimeStamp, endTimeStamp);
// have to cumsum
for (int i = 0; i < inflatedCashPositionSeries.getNumColumns(); i++) {
DoubleColumn dc = (DoubleColumn) inflatedCashPositionSeries.getColumns().get(i);
dc = dc.cumsum();
inflatedCashPositionSeries.getColumns().set(i, dc);
}
inflatedCashPositionSeries = tcm.overwriteNull(inflatedCashPositionSeries);
inflatedCashPositionSeries = tcm.overwriteNull(inflatedCashPositionSeries, 0.0);
// create borrowing and lending payments.
TSContainer2 borrowingAndLendingContainer = calcInterestChanges(startTimeStamp, endTimeStamp,
TimeFrame.HOURS_1, inflatedCashPositionSeries);
fout = new FileOutputStream(targetFolder + File.separator + "cash_positions_bef_resampling.csv");
c = new CSVExporter(fout, inflatedCashPositionSeries);
c.write();
fout.close();
fout = new FileOutputStream(targetFolder + File.separator + "interest_before_resampling.csv");
c = new CSVExporter(fout, borrowingAndLendingContainer);
c.write();
fout.close();
// resample from high resolution to report resolution
inflatedCashPositionSeries = resampleSeries(inflatedCashPositionSeries, timeFrame, startTimeStamp, endTimeStamp);
borrowingAndLendingContainer = tcm.resampleWithSum(borrowingAndLendingContainer, timeFrame.getNanoseconds());
// dump the inflated cash positions
fout = new FileOutputStream(targetFolder + File.separator + "inflated_cash_positions.csv");
c = new CSVExporter(fout, inflatedCashPositionSeries);
c.write();
fout.close();
// dump the interest charges/earnings
fout = new FileOutputStream(targetFolder + File.separator + "interest.csv");
c = new CSVExporter(fout, borrowingAndLendingContainer);
c.write();
fout.close();
// dump out the fees.
if (oel.getFeeCalculator() != null) {
//
fout = new FileOutputStream(targetFolder + File.separator + "fees.csv");
c = new CSVExporter(fout, oel.getFeeCalculator().feesSeries());
c.write();
fout.close();
TSContainer2 feesPerRepUnit = tcm.resampleWithSum(oel.getFeeCalculator().feesSeries(),
timeFrame.getNanoseconds());
// dump the inflated cash positions
fout = new FileOutputStream(targetFolder + File.separator + "fees_resampled_to_timeframe.csv");
c = new CSVExporter(fout, feesPerRepUnit);
c.write();
fout.close();
}
// generate a position chart.
ChartUtilities.saveChartAsPNG(new File(targetFolder + File.separator + "position.png"),
ChartUtils.getStepChart("Position", oel.getPositionOverTime()), 800, 600);
fout = new FileOutputStream(targetFolder + File.separator + "positions.csv");
c = new CSVExporter(fout, oel.getPositionOverTime());
c.write();
fout.close();
TSContainer2 inflatedPositionSeries = resampleSeries(oel.getPositionOverTime(), timeFrame, startTimeStamp,
endTimeStamp);
inflatedPositionSeries = tcm.overwriteNull(inflatedPositionSeries);
inflatedPositionSeries = tcm.overwriteNull(inflatedPositionSeries, 0.0);
fout = new FileOutputStream(targetFolder + File.separator + "inflated_positions.csv");
c = new CSVExporter(fout, inflatedPositionSeries);
c.write();
fout.close();
// calculate some statistics.
BacktestStatistics bs = new BacktestStatistics();
bs.setReportId(new SimpleDateFormat("yyyyMMdd").format(new Date()));
pnlContainer = tcm.overwriteNull(pnlContainer);
pnlContainer = tcm.overwriteNull(pnlContainer, 0.0);
bs.calcPNLStats(pnlContainer);
TSContainer2 posOverTime = oel.getPositionOverTime();
posOverTime = tcm.overwriteNull(posOverTime);
posOverTime = tcm.overwriteNull(posOverTime, 0.0);
bs.calcPosStats(posOverTime);
bs.populateOrderStats(oel);
// dump the stats
fout = new FileOutputStream(targetFolder + File.separator + "statistics.csv");
new CsvMapWriter().write(bs.getStatistics(), fout);
fout.close();
// dump out transaction count.
transactionCount.store(new FileOutputStream(targetFolder + File.separator + "transactionCount.properties"), "");
//
if (!targetFolder.endsWith("/"))
targetFolder = targetFolder + "/";
// generate the html report.
File dir = new File(".");
String dirPath = dir.getAbsolutePath().substring(0, dir.getAbsolutePath().length() - 1);
HTMLReportGen h = new HTMLReportGen(targetFolder, dirPath + "/templates");
h.genReport(new AlgoConfig[] {}, oel, pnlMonitor, null);
// run R.
new RExec(dirPath + "r/perfreport.r", new String[] { targetFolder + "pnl.csv",
targetFolder + "inflated_cash_positions.csv", targetFolder, timeFrame.toString() });
// run the freemarker wrapper.
Configuration cfg = new Configuration();
Template tpl = cfg.getTemplate("templates/perfreport.tpl");
OutputStreamWriter output = new OutputStreamWriter(new FileOutputStream(targetFolder + "report.html"));
// Add the values in the datamodel
Map datamodel = new HashMap();
datamodel.put("REPORTID", reportId);
datamodel.put("RESOLUTION", timeFrame.toString());
datamodel.put("TIMESTAMPSTART", simStart);
datamodel.put("TIMESTAMPEND", simEnd);
datamodel.put("MDIS", instrumentsInSim);
datamodel.put("TDIS", "-");
List<String> instruments = new ArrayList<String>();
instruments.add("TOTAL");
for (String s : tids)
instruments.add("PI_" + s);
datamodel.put("instruments", instruments);
Iterator<Entry<Object, Object>> it = properties.entrySet().iterator();
List<String> configDump = new ArrayList<String>();
while(it.hasNext()){
Entry<Object, Object> e = it.next();
configDump.add(e.getKey()+" = " + e.getValue());
}
datamodel.put("configdump", configDump);
// should also put the different calculated measures into that report
// ...
String[] rows = FileUtils.readLines(targetFolder + "PNL_characteristics.csv");
String[][] cells = new String[rows.length][];
for (int i = 0; i < rows.length; i++) {
rows[i] = rows[i].replaceAll("\"", "");
cells[i] = rows[i].split(",");
}
//
datamodel.put("PNL_CHARACTERISTICS", cells);
//
datamodel.put("CASH_INSTS", inflatedCashPositionSeries.getColumnHeaders());
List<String[][]> monthlyReturnTables = new ArrayList<String[][]>();
for (String s : tids) {
s = "PI_" + s;
try {
String[] lines = FileUtils.readLines(targetFolder + "PNL_" + s + "_TABULARRETS.csv");
String[][] monthlyRets = new String[lines.length][];
for (int i = 0; i < lines.length; i++) {
String l = lines[i];
l = l.replaceAll("\"", "");
monthlyRets[i] = l.split(",");
}
monthlyReturnTables.add(monthlyRets);
} catch (IOException ex) {
}
}
datamodel.put("MONTHLY_RETS", monthlyReturnTables);
//
tpl.process(datamodel, output);
}
/**
* this one can do only one-hop conversions. The columnnames in the series
* container must be the currency pair.
*
* @param seriesContainer
* @param seriesCurrency
* @param timeFrame
* @param startTimeStamp
* @param endTimeStamp
* @return
*/
private TSContainer2 convertSeriesToUSD(String[] inputSeries, TSContainer2 seriesContainer, TimeFrame timeFrame,
TimeStamp startTimeStamp, TimeStamp endTimeStamp) {
List<String> colHeaders = seriesContainer.getColumnHeaders();
List<TypedColumn> columns = new ArrayList<TypedColumn>();
for (String s : colHeaders) {
columns.add(new DoubleColumn());
}
TSContainer2 converted = new TSContainer2("CONVERTEDTOUSD", colHeaders, columns, timeFrame.getNanoseconds());
//
//
// //
// ArchiveStreamToOHLCIterator a = new ArchiveStreamToOHLCIterator(tid,
// TimeFrame.MINUTES_1, startTimeStamp,
// endTimeStamp, archReader);
// while(a.hasNext()){
// OHLCV o = a.next();
// }
//
//
// //
// String tid = ofe.getOptionalInstId();
//
//
// double volume = ofe.getFillAmount();
// double execPrice = ofe.getFillPrice();
// //
// double tradedValueInQuotee = volume * execPrice;
// String base = tid.substring(0,3);
// String quotee = tid.substring(3);
//
// double conversionRate = 1.0;
// if(base.equals("USD")){
// conversionRate = 1.0/execPrice;
// }
// else if(quotee.equals("USD")){
// conversionRate = 1.0;
// }
// else{
// conversionRate = getConversionRate(base, quotee, execPrice);
// }
//
// double tradedValueInUsd = conversionRate * tradedValueInQuotee;
// double commission = Math.max((0.2 * tickSizeAcctCurrency *
// tradedValueInUsd), 2.50);
//
//
//
return null;
}
private TSContainer2 resampleSeries(TSContainer2 container, TimeFrame timeFrame, TimeStamp startTimeStamp,
TimeStamp endTimeStamp) {
// resample the position series.
TSContainer2 resampled = getEmptyContainer(container.getColumnHeaders(), startTimeStamp, endTimeStamp,
timeFrame);
List<String> headers = container.getColumnHeaders();
for (int i = 0; i < container.getTimeStamps().size(); i++) {
TimeStamp ts = container.getTimeStamps().get(i);
Object[] o = container.getRow(ts);
for (int j = 0; j < o.length; j++) {
if (o[j] != null) {
resampled.setValue(headers.get(j), ts, (Double) o[j]);
}
}
}
return resampled;
}
private TSContainer2 calcCashPositions(TSContainer2 posDeltaOverTime, TSContainer2 executionPricesOverTime) {
TSContainer2 cashPositionsOverTime = new TSContainer2("CASH", new ArrayList<String>(),
new ArrayList<TypedColumn>());
// calculating cash positions.
List<String> instruments = posDeltaOverTime.getColumnHeaders();
for (String tdiId : instruments) {
// skip the instrument lookup for now - as this is mostly a custom
// development at the moment, I just assume we have only FX.
String base, quotee;
if (tdiId.startsWith("PI_")) {
base = tdiId.substring(3, 6);
quotee = tdiId.substring(6);
System.out.println("Calculating cash position for " + base + "/" + quotee);
DoubleColumn posDeltaColumn = (DoubleColumn) posDeltaOverTime.getColumn(tdiId);
DoubleColumn execPriceColumn = (DoubleColumn) executionPricesOverTime.getColumn(tdiId);
//
List<TimeStamp> timeStamps = posDeltaOverTime.getTimeStamps();
cashPositionsOverTime.setTimeStamps(timeStamps);
// check if we already have the cash columns
addColAndInit(cashPositionsOverTime, base, timeStamps);
addColAndInit(cashPositionsOverTime, quotee, timeStamps);
// get the two columns and keep track of the stuff.
DoubleColumn baseCol = (DoubleColumn) cashPositionsOverTime.getColumn(base);
DoubleColumn quoteeCol = (DoubleColumn) cashPositionsOverTime.getColumn(quotee);
for (int i = 0; i < timeStamps.size(); i++) {
//
Double posDelta = posDeltaColumn.get(i);
if (posDelta != null) {
//
Double execPrice = execPriceColumn.get(i);
Double presentBasePos = baseCol.get(i);
Double presentQuoteePos = quoteeCol.get(i);
//
presentBasePos += posDelta;
presentQuoteePos -= posDelta * execPrice;
//
baseCol.set(i, presentBasePos);
quoteeCol.set(i, presentQuoteePos);
}
//
}
}
}
return cashPositionsOverTime;
}
private void addColAndInit(TSContainer2 container, String colName, List<TimeStamp> timeStamps) {
if (!container.getColumnHeaders().contains(colName)) {
DoubleColumn col = new DoubleColumn();
container.addColumn(colName, col);
col.clear();
// initialize the column.
for (TimeStamp ts : timeStamps)
col.add(0.0);
}
}
private class ChargedInterestRates {
private Map<String, Double[]> rates = new HashMap<String, Double[]>();
ChargedInterestRates() throws IOException {
File directory = new File(".");
File f1 = new File(directory.getAbsolutePath() + "/ib/ib_charged_9_july_2012.csv");
BufferedReader br = new BufferedReader(new FileReader(f1));
String l = br.readLine();
// skipping header.
l = br.readLine();
while (l != null) {
String[] parts = l.split(",");
String cncy = parts[0];
Double[] data = new Double[8];
for (int i = 1; i < parts.length; i++) {
if (parts[i].length() > 0) {
data[i - 1] = Double.parseDouble(parts[i]);
}
}
rates.put(cncy, data);
l = br.readLine();
}
}
Double getOvernightChange(String currency, Double balance) {
if (rates.containsKey(currency)) {
Double[] d = rates.get(currency);
double days = d[0];
double refRate = 0.0;
if (balance < d[1])
refRate = d[2];
if (balance >= d[1])
refRate = d[3];
if (balance >= d[4])
refRate = d[5];
if (d[6] != null && balance >= d[6])
refRate = d[7];
return balance * (refRate / 100.0) / days;
} else
return 0.0;
}
}
private class EarnedInterestRates {
private Map<String, Double[]> rates = new HashMap<String, Double[]>();
EarnedInterestRates() throws IOException {
File directory = new File(".");
File f1 = new File(directory.getAbsolutePath() + "/ib/ib_earned_9_july_2012.csv");
BufferedReader br = new BufferedReader(new FileReader(f1));
String l = br.readLine();
// skipping header.
l = br.readLine();
while (l != null) {
String[] parts = l.split(",");
String cncy = parts[0];
Double[] data = new Double[7];
for (int i = 1; i < parts.length; i++) {
if (parts[i].length() > 0) {
data[i - 1] = Double.parseDouble(parts[i]);
}
}
rates.put(cncy, data);
l = br.readLine();
}
}
Double getOvernightChange(String currency, Double balance) {
if (rates.containsKey(currency)) {
Double[] d = rates.get(currency);
double days = d[0];
double refRate = 0.0;
if (balance >= d[1])
refRate = d[2];
if (balance >= d[3])
refRate = d[4];
if (d[5] != null && balance >= d[5])
refRate = d[6];
return balance * (refRate / 100.0) / days;
} else
return 0.0;
}
}
private TSContainer2 getEmptyContainer(List<String> headers, TimeStamp startTimeStamp, TimeStamp endTimeStamp,
TimeFrame reportResolution) {
List<TypedColumn> columns = new ArrayList<TypedColumn>();
for (int i = 0; i < headers.size(); i++)
columns.add(new DoubleColumn());
TSContainer2 tsc = new TSContainer2("-", headers, columns);
tsc.setResolutionInNanoseconds(reportResolution.getNanoseconds());
List<TimeStamp> markStamps = new TSContainerMethods().getListOfTimeStamps(startTimeStamp, endTimeStamp,
reportResolution);
Double[] naRow = new Double[columns.size()];
for (TimeStamp ts : markStamps) {
tsc.setRow(ts, naRow);
}
return tsc;
}
private TSContainer2 calcInterestChanges(TimeStamp startTimeStamp, TimeStamp endTimeStamp,
TimeFrame reportResolution, TSContainer2 cashPositionsOverTime) throws IOException {
// load the borrowing and lending reference rates.
ChargedInterestRates chargedIr = new ChargedInterestRates();
EarnedInterestRates earnedIr = new EarnedInterestRates();
// iterate over the days.
List<TypedColumn> columns = new ArrayList<TypedColumn>();
for (int i = 0; i < cashPositionsOverTime.getColumns().size(); i++)
columns.add(new DoubleColumn());
//
TSContainer2 tsc = new TSContainer2("INTEREST", cashPositionsOverTime.getColumnHeaders(), columns);
List<TimeStamp> markStamps = new TSContainerMethods().getListOfTimeStamps(startTimeStamp, endTimeStamp,
reportResolution);
//
SimpleDateFormat newYorkTimeFormatter = new SimpleDateFormat("HH");
newYorkTimeFormatter.setTimeZone(TimeZone.getTimeZone("America/New_York"));
// ib specific: daily accruals at 5 PM EST.
//
//
int currentHour = Integer.parseInt(newYorkTimeFormatter.format(markStamps.get(0).getCalendar().getTime()));
Double[] zeroRow = new Double[columns.size()];
for (int i = 0; i < zeroRow.length; i++)
zeroRow[i] = 0.0;
for (TimeStamp ts : markStamps) {
tsc.setRow(ts, zeroRow);
int hour = Integer.parseInt(newYorkTimeFormatter.format(ts.getCalendar().getTime()));
if (hour != currentHour) {
if (hour == 17) {
int indexBefore = cashPositionsOverTime.getIndexBeforeOrEqual(ts);
if (indexBefore > -1) {
// ok, new day, let's book the accruals, based on
// yesterday's cash positions.
for (int i = 0; i < cashPositionsOverTime.getColumns().size(); i++) {
DoubleColumn dc = (DoubleColumn) cashPositionsOverTime.getColumns().get(i);
Double val = dc.get(indexBefore);
String cncy = cashPositionsOverTime.getColumnHeaders().get(i);
if (val != null) {
if (val < 0.0) {
Double charge = chargedIr.getOvernightChange(cncy, val);
tsc.setValue(cncy, ts, charge);
} else if (val > 0.0) {
Double earnings = earnedIr.getOvernightChange(cncy, val);
tsc.setValue(cncy, ts, earnings);
}
}
}
}
}
currentHour = hour;
}
}
//
return tsc;
}
/**
* @param args
* @throws FileNotFoundException
*/
public static void main(String[] args) throws Exception {
/* new TransactionInputToReport(
"/home/ustaudinger/work/activequant/trunk/src/test/resources/transactions/transactions.csv",
"/home/ustaudinger/work/activequant/trunk/src/test/resources/transactions/report.config",
"/home/ustaudinger/work/activequant/trunk/src/test/resources/transactions/",
"reporting.pecoracapital.com");
*/
new TransactionInputToReport(args[0], args[1], args[2], args[3]);
// //
// SimpleDateFormat newYorkTimeFormatter = new SimpleDateFormat("HH");
// newYorkTimeFormatter.setTimeZone(TimeZone.getTimeZone("America/New_York"));
//
// //
// SimpleDateFormat localTimeFormatter = new SimpleDateFormat("HH");
//
// System.out.println(newYorkTimeFormatter.format(new Date()) + " -- " +
// localTimeFormatter.format(new Date()));
}
}