package org.cryptocoinpartners.module;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.lang.StringUtils;
import org.cryptocoinpartners.esper.annotation.When;
import org.cryptocoinpartners.schema.Asset;
import org.cryptocoinpartners.schema.Book;
import org.cryptocoinpartners.schema.Market;
import org.cryptocoinpartners.schema.Offer;
import org.cryptocoinpartners.schema.Tick;
import org.slf4j.Logger;
import au.com.bytecode.opencsv.CSVWriter;
@SuppressWarnings("UnusedDeclaration")
@Singleton
public class SaveTicksCsv {
public static List<String> headers = new ArrayList<>(Arrays.asList(new String[] { "listing", "exchange", "base", "quote", "time", "last", "vol" }));
@Inject
public SaveTicksCsv(Context context, Configuration config) {
final String filename = config.getString("savetickscsv.filename");
if (!StringUtils.isNotBlank(filename))
throw new ConfigurationError("You must set the property savetickscsv.filename");
allowNa = config.getBoolean("savetickscsv.na", false);
String timeFormatStr = config.getString("savetickscsv.timeFormat", "yyMMddHHmmss");
try {
timeFormat = new SimpleDateFormat(timeFormatStr);
} catch (NullPointerException e) {
throw new ConfigurationError("The output date format must be specified in the property savetickscsv.timeFormat");
} catch (IllegalArgumentException e) {
throw new ConfigurationError("The format is invalid: savetickscsv.timeFormat=" + timeFormatStr + "\n" + e.getMessage());
}
bookDepth = config.getInt("savetickscsv.bookDepth", 100);
for (int i = 0; i < bookDepth; i++) {
int num = i + 1;
headers.add("bidprice" + num);
headers.add("bidvol" + num);
headers.add("askprice" + num);
headers.add("askvol" + num);
}
try {
writer = new CSVWriter(new FileWriter(filename));
String[] row = new String[headers.size()];
writer.writeNext(headers.toArray(row));
writer.flush();
} catch (IOException e) {
throw new ConfigurationError("Could not write file " + filename);
}
}
@SuppressWarnings("ConstantConditions")
@When("select * from Tick")
public void saveTick(Tick t) {
if (!allowNa) {
if (t.getLastBook() == null)
return;
}
final Market listing = t.getMarket();
final String exchange = listing.getExchange().getSymbol();
final Asset base = listing.getBase();
final Asset quote = listing.getQuote();
final String timeStr = timeFormat.format(t.getTime().toDate());
if (t.getPriceCount() != null) {
ArrayList<String> row = new ArrayList<>(Arrays.asList(listing.toString(), exchange, base.getSymbol(), quote.getSymbol(), timeStr,
String.valueOf(t.getPriceAsDouble()), String.valueOf(t.getVolumeAsDouble())));
addBookToRow(t, row);
writer.writeNext(row.toArray(new String[row.size()]));
try {
writer.flush();
} catch (IOException e) {
log.warn(e.getMessage(), e);
}
}
}
private void addBookToRow(Tick t, ArrayList<String> row) {
Book book = t.getLastBook();
List<Offer> bids = book.getBids();
List<Offer> asks = book.getAsks();
for (int i = 0; i < bookDepth; i++) {
if (bids.size() > i) {
Offer bid = bids.get(i);
row.add(String.valueOf(bid.getPriceAsDouble()));
row.add(String.valueOf(bid.getVolumeAsDouble()));
} else {
row.add("");
row.add("");
}
if (asks.size() > i) {
Offer ask = asks.get(i);
row.add(String.valueOf(ask.getPriceAsDouble()));
row.add(String.valueOf(ask.getVolumeAsDouble()));
} else {
row.add("");
row.add("");
}
}
}
@Inject
public Logger log;
private final int bookDepth;
private SimpleDateFormat timeFormat;
private CSVWriter writer;
private final boolean allowNa;
}