Java tutorial
// Copyright 2015 Ivan Popivanov // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package net.tradelib.misc; import java.io.BufferedWriter; import java.io.FileWriter; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Timestamp; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonObject; public class StrategyText { public static String build(String dbUrl, String strategy, LocalDate date, String sep) throws Exception { return build(dbUrl, strategy, date, sep, null, ','); } public static String build(String dbUrl, String strategy, LocalDate date, String sep, String csvPath, char csvSep) throws Exception { String text = ""; Connection connection = DriverManager.getConnection(dbUrl); List<InstrumentText> lit = StrategyText.buildList(connection, strategy, date, csvPath, csvSep); for (InstrumentText it : lit) { if (!it.isSection()) { text += String.format("\n%20s" + sep + "%4s" + sep + "%10s" + sep + "%s", it.getName(), it.getSymbol(), it.getExpiration(), it.getStatus()); } } connection.close(); return text; } private static final String STRATEGY_QUERY = " select c.id as cid, c.name as cname, i.comment as name, coalesce(ivar.symbol, spos.symbol) as symbol, " + " spos.position as position, date(spos.ts/1000.0, 'unixepoch') as date, spos.last_close as close, " + " spos.last_ts as close_date, " + " spos.details AS details, strftime('%m''%Y',i.current_contract/1000.0,'unixepoch') as current_contract, " + " strftime('%m''%Y',i.next_contract/1000.0,'unixepoch') as next_contract, i.trading_days as days, " + " strftime('%m''%Y',i.current_contract2/1000.0,'unixepoch') as current_contract2, i.roll_today as roll_today " + " from strategy_positions spos " + " inner join strategies s on s.id = spos.strategy_id " + " inner join instrument i on i.symbol = spos.symbol and i.provider = 'csi' " + " left join instrument_variation ivar on spos.symbol = ivar.original_symbol and ivar.original_provider = 'csi' " + " left join instrument_visiable iv on iv.instrument_id = i.id " + " left join categories c on iv.categories_id = c.id " + " WHERE s.name = ? AND strftime('%Y-%m-%d', spos.last_ts/1000.0, 'unixepoch') = strftime('%Y-%m-%d', ?/1000.0, 'unixepoch') " + " ORDER BY cid, iv.ord"; private static final String STRATEGY_QUERY_MYSQL = " select c.id as cid, c.name as cname, i.comment as name, coalesce(ivar.symbol, spos.symbol) as symbol, " + " spos.position as position, date_format(spos.ts, '%Y-%m-%d') as date, spos.last_close as close, " + " spos.last_ts as close_date, " + " spos.details AS details, date_format(i.current_contract,'%b\\'%y') as current_contract, " + " date_format(i.next_contract,'%b\\'%y') as next_contract, i.trading_days as days, " + " date_format(i.current_contract2,'%b\\'%y') as current_contract2, i.roll_today as roll_today " + " from strategy_positions spos " + " inner join strategies s on s.id = spos.strategy_id " + " inner join instrument i on i.symbol = spos.symbol and i.provider = 'csi' " + " left join instrument_variation ivar on spos.symbol = ivar.original_symbol and ivar.original_provider = 'csi' " + " left join instrument_visiable iv on iv.instrument_id = i.id " + " left join categories c on iv.categories_id = c.id " + " WHERE s.name = ? AND DATE(spos.last_ts) = DATE(?) " + " ORDER BY cid, iv.ord"; public static List<InstrumentText> buildList(Connection con, String strategy, LocalDate date, String csvPath, char csvSep) throws Exception { // public static List<InstrumentText> buildList(Connection con, String strategy, LocalDate date) throws Exception { ArrayList<InstrumentText> result = new ArrayList<InstrumentText>(); CSVPrinter printer = null; if (csvPath != null) { // Add withHeader for headers printer = CSVFormat.DEFAULT.withDelimiter(csvSep).print(new BufferedWriter(new FileWriter(csvPath))); } int numCsvColumns = 12; int rollMethod = 2; DatabaseMetaData dmd = con.getMetaData(); String driverName = dmd.getDriverName(); String query = ""; if (driverName.startsWith("MySQL")) { query = STRATEGY_QUERY_MYSQL; } else { query = STRATEGY_QUERY; } String prevCategory = ""; PreparedStatement pstmt = con.prepareStatement(query); pstmt.setString(1, strategy); pstmt.setTimestamp(2, Timestamp.valueOf(date.atStartOfDay())); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { String category = rs.getString(2); if (!category.equals(prevCategory)) { result.add(InstrumentText.makeSection(category)); prevCategory = category; if (printer != null) { printer.print(category); for (int ii = 1; ii < numCsvColumns; ++ii) { printer.print(""); } printer.println(); } } String name = rs.getString(3); String symbol = rs.getString(4); String contract = ""; if (rollMethod == 1) { // Uses current_contract and trading_days int ndays = rs.getInt(12); if (ndays > 1) { contract = rs.getString(10); } else { contract = "Roll to " + rs.getString(11); } } else if (rollMethod == 2) { // Uses current_contract2 and roll_today int rollToday = rs.getInt(14); if (rollToday == 0) { contract = rs.getString(13); } else { contract = "Roll to " + rs.getString(13); } } if (printer != null) { printer.print(name); printer.print(symbol); printer.print(contract); } String signal; long position = (long) rs.getDouble(5); JsonObject jo = new Gson().fromJson(rs.getString(9), JsonObject.class); if (position > 0.0) { BigDecimal entryPrice; double pnl; try { entryPrice = jo.get("entry_price").getAsBigDecimal(); pnl = jo.get("pnl").getAsDouble(); } catch (Exception e) { entryPrice = BigDecimal.valueOf(Double.MIN_VALUE); pnl = Double.MIN_VALUE; } signal = String.format("Long [%d] since %s [at %s].", position, rs.getString(6), formatBigDecimal(entryPrice)); if (printer != null) printer.print(signal); String openProfit = String.format("Open equity profit %,d.", (int) Math.floor(pnl)); signal += " " + openProfit; if (printer != null) printer.print(openProfit); } else if (position < 0.0) { BigDecimal entryPrice; double pnl; try { entryPrice = jo.get("entry_price").getAsBigDecimal(); pnl = jo.get("pnl").getAsDouble(); } catch (Exception e) { entryPrice = BigDecimal.valueOf(-1); pnl = -1; } signal = String.format("Short [%d] since %s [at %s].", Math.abs(position), rs.getString(6), formatBigDecimal(entryPrice)); if (printer != null) printer.print(signal); String openProfit = String.format("Open equity profit %,d.", (int) Math.floor(pnl)); signal += " " + openProfit; if (printer != null) printer.print(openProfit); } else { signal = "Out."; if (printer != null) { printer.print(signal); // An empty column follows the status if there is no position - there is no profit. printer.print(""); } } boolean hasOrder = false; JsonArray ja = jo.get("orders").getAsJsonArray(); double entryRisk; try { entryRisk = jo.get("entry_risk").getAsDouble(); } catch (Exception ee) { entryRisk = Double.NaN; } String profitTarget; Double profitTargetDbl; try { profitTarget = formatBigDecimal(jo.get("profit_target").getAsBigDecimal()); profitTargetDbl = jo.get("profit_target").getAsDouble(); } catch (Exception ee) { profitTarget = null; profitTargetDbl = null; } String stopLoss; Double stopLossDbl; try { stopLoss = formatBigDecimal(jo.get("stop_loss").getAsBigDecimal()); stopLossDbl = jo.get("stop_loss").getAsDouble(); } catch (Exception ee) { stopLoss = null; stopLossDbl = null; } Double lastClose; try { lastClose = jo.get("last_close").getAsDouble(); } catch (Exception ee) { lastClose = null; } // Currently maximum one entry and maximum one exit are supported. String entryStr = ""; String exitStr = ""; String contractRiskStr = ""; for (int ii = 0; ii < ja.size(); ++ii) { JsonObject jorder = ja.get(ii).getAsJsonObject(); switch (jorder.get("type").getAsString()) { case "EXIT_LONG_STOP": exitStr = "Exit long at stop " + formatBigDecimal(jorder.get("stop_price").getAsBigDecimal()) + "."; signal += " " + exitStr; break; case "EXIT_SHORT_STOP": exitStr = "Exit short at stop " + formatBigDecimal(jorder.get("stop_price").getAsBigDecimal()) + "."; signal += " " + exitStr; break; case "ENTER_LONG": if (!Double.isNaN(entryRisk)) { entryStr = String.format("Enter long at open. Contract risk is %s.", formatDouble(entryRisk, 0, 0)); signal += " " + entryStr; } else { entryStr = "Enter long at open."; signal += " " + entryStr; } break; case "ENTER_SHORT": if (!Double.isNaN(entryRisk)) { entryStr = String.format("Enter short at open. Contract risk is %s.", formatDouble(entryRisk, 0, 0)); signal += " " + entryStr; } else { entryStr = "Enter short at open."; signal += " " + entryStr; } break; case "ENTER_LONG_STOP": position = jorder.get("quantity").getAsLong(); entryStr = String.format("Enter long [%d] at stop %s [%s%%].", position, formatBigDecimal(jorder.get("stop_price").getAsBigDecimal()), formatPercentage(jorder.get("stop_price").getAsDouble() / lastClose * 100 - 100)); signal += " " + entryStr; if (!Double.isNaN(entryRisk)) { contractRiskStr = String.format(" Contract risk is %s.", formatDouble(entryRisk, 0, 0)); signal += " " + contractRiskStr; } break; case "ENTER_LONG_STOP_LIMIT": position = jorder.get("quantity").getAsLong(); entryStr = String.format("Enter long [%d] at limit %s, stop at %s [%s%%].", position, formatBigDecimal(jorder.get("limit_price").getAsBigDecimal()), formatBigDecimal(jorder.get("stop_price").getAsBigDecimal()), formatPercentage(jorder.get("stop_price").getAsDouble() / lastClose * 100 - 100)); signal += " " + entryStr; if (!Double.isNaN(entryRisk)) { contractRiskStr = String.format(" Contract risk is %s.", formatDouble(entryRisk, 0, 0)); signal += contractRiskStr; } break; case "ENTER_SHORT_STOP": // signal += " Enter short at stop " + formatBigDecimal(jorder.get("stop_price").getAsBigDecimal()) + "."; position = jorder.get("quantity").getAsLong(); entryStr = String.format("Enter short [%d] at stop %s [%s%%].", Math.abs(position), formatBigDecimal(jorder.get("stop_price").getAsBigDecimal()), formatPercentage(jorder.get("stop_price").getAsDouble() / lastClose * 100 - 100)); signal += " " + entryStr; if (!Double.isNaN(entryRisk)) { contractRiskStr = String.format(" Contract risk is %s.", formatDouble(entryRisk, 0, 0)); signal += " " + contractRiskStr; } break; case "ENTER_SHORT_STOP_LIMIT": position = jorder.get("quantity").getAsLong(); entryStr = String.format("Enter short [%d] at limit %s, stop at %s [%s%%].", Math.abs(position), formatBigDecimal(jorder.get("limit_price").getAsBigDecimal()), formatBigDecimal(jorder.get("stop_price").getAsBigDecimal()), formatPercentage(jorder.get("stop_price").getAsDouble() / lastClose * 100 - 100)); signal += " " + entryStr; if (!Double.isNaN(entryRisk)) { contractRiskStr = String.format(" Contract risk is %s.", formatDouble(entryRisk, 0, 0)); signal += " " + contractRiskStr; } break; case "EXIT_LONG": exitStr = "Exit long at open."; signal += " " + exitStr; break; case "EXIT_SHORT": exitStr = "Exit short at open."; signal += " " + exitStr; break; case "EXIT_SHORT_STOP_LIMIT": exitStr = "Exit short at limit " + formatBigDecimal(jorder.get("limit_price").getAsBigDecimal()) + ", stop at " + formatBigDecimal(jorder.get("stop_price").getAsBigDecimal()) + " [" + formatPercentage(jorder.get("stop_price").getAsDouble() / lastClose * 100 - 100) + "%]" + "."; signal += " " + exitStr; break; case "EXIT_LONG_STOP_LIMIT": exitStr = "Exit long at limit " + formatBigDecimal(jorder.get("limit_price").getAsBigDecimal()) + ", stop at " + formatBigDecimal(jorder.get("stop_price").getAsBigDecimal()) + " [" + formatPercentage(jorder.get("stop_price").getAsDouble() / lastClose * 100 - 100) + "%]" + "."; signal += " " + exitStr; break; } hasOrder = true; } String lastCloseStr = "Last close at " + formatBigDecimal(jo.get("last_close").getAsBigDecimal()) + "."; String stopLossStr = ""; String profitTargetStr = ""; if (hasOrder) { signal += " " + lastCloseStr; } if (stopLoss != null) { stopLossStr = "Stop loss at " + stopLoss; if (lastClose != null && stopLossDbl != null) { stopLossStr += " [" + formatPercentage(stopLossDbl / lastClose * 100 - 100) + "%]"; } stopLossStr += "."; signal += " " + stopLossStr; } if (profitTarget != null) { profitTargetStr = "Profit target at about " + profitTarget; if (profitTargetDbl != null && lastClose != null) { profitTargetStr += " [" + formatPercentage(profitTargetDbl / lastClose * 100 - 100) + "%]"; } profitTargetStr += "."; signal += " " + profitTargetStr; } if (printer != null) { printer.print(exitStr); printer.print(entryStr); printer.print(contractRiskStr); printer.print(lastCloseStr); printer.print(stopLossStr); printer.print(profitTargetStr); printer.println(); } result.add(InstrumentText.make(name, symbol, contract, signal)); } rs.close(); pstmt.close(); if (printer != null) printer.flush(); return result; } private static final String STRATEGY_ORDER_QUERY = " select c.id as cid, c.name as cname, i.comment as name, coalesce(ivar.symbol, spos.symbol) as actual_symbol, " + " spos.position as position, strftime('%Y-%m-%d', spos.ts/1000.0, 'unixepoch') as date, spos.last_close as close, " + " spos.last_ts as close_date, " + " spos.details AS details, strftime('%Y%m',i.current_contract/1000.0,'unixepoch') as current_contract, " + " strftime('%Y%m',i.next_contract/1000.0,'unixepoch') as next_contract, i.trading_days as days, " + " ie.exchange as exchange, i.type as type, " + " strftime('%Y%m',i.current_contract2/1000.0,'unixepoch') as current_contract2, i.roll_today as roll_today " + " from strategy_positions spos " + " inner join strategies s on s.id = spos.strategy_id " + " inner join instrument i on i.symbol = spos.symbol and i.provider = 'csi' " + " left join instrument_variation ivar on spos.symbol = ivar.original_symbol and ivar.original_provider = 'csi' " + " left join instrument_visiable iv on iv.instrument_id = i.id " + " left join categories c on iv.categories_id = c.id " + " left join instrument_exchange ie on coalesce(ivar.symbol, spos.symbol) = ie.symbol " + " WHERE s.name = ? AND strftime('%Y-%m-%d', spos.last_ts/1000.0, 'unixepoch') = strftime('%Y-%m-%d', ?/1000.0, 'unixepoch') " + " ORDER BY cid, iv.ord"; private static final String STRATEGY_ORDER_QUERY_MYSQL = " select c.id as cid, c.name as cname, i.comment as name, coalesce(ivar.symbol, spos.symbol) as actual_symbol, " + " spos.position as position, date_format(spos.ts, '%Y-%m-%d') as date, spos.last_close as close, " + " spos.last_ts as close_date, " + " spos.details AS details, date_format(i.current_contract,'%Y%m') as current_contract, " + " date_format(i.next_contract,'%Y%m') as next_contract, i.trading_days as days, " + " ie.exchange as exchange, i.type as type, " + " date_format(i.current_contract2,'%Y%m') as current_contract2, i.roll_today as roll_today " + " from strategy_positions spos " + " inner join strategies s on s.id = spos.strategy_id " + " inner join instrument i on i.symbol = spos.symbol and i.provider = 'csi' " + " left join instrument_variation ivar on spos.symbol = ivar.original_symbol and ivar.original_provider = 'csi' " + " left join instrument_visiable iv on iv.instrument_id = i.id " + " left join categories c on iv.categories_id = c.id " + " left join instrument_exchange ie on coalesce(ivar.symbol, spos.symbol) = ie.symbol " + " WHERE s.name = ? AND DATE(spos.last_ts) = DATE(?) " + " ORDER BY cid, iv.ord"; private static final String[] CSV_HEADER = { "Action", "Quantity", "Symbol", "SecType", "LastTradingDayOrContractMonth", "Exchange", "OrderType", "LmtPrice", "AuxPrice" }; public static void buildOrdersCsv(String dbUrl, String strategy, LocalDate date, String csvPath) throws Exception { Connection con = DriverManager.getConnection(dbUrl); CSVPrinter printer = null; if (csvPath != null) { // Add withHeader for headers printer = CSVFormat.DEFAULT.withDelimiter(',').withHeader(CSV_HEADER) .print(new BufferedWriter(new FileWriter(csvPath))); } int rollMethod = 2; DatabaseMetaData dmd = con.getMetaData(); String driverName = dmd.getDriverName(); String query = ""; if (driverName.startsWith("MySQL")) { query = STRATEGY_ORDER_QUERY_MYSQL; } else { query = STRATEGY_ORDER_QUERY; } PreparedStatement pstmt = con.prepareStatement(query); pstmt.setString(1, strategy); pstmt.setTimestamp(2, Timestamp.valueOf(date.atStartOfDay())); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { JsonObject jo = new Gson().fromJson(rs.getString(9), JsonObject.class); JsonArray ja = jo.get("orders").getAsJsonArray(); int ndays = rs.getInt(12); String contract = ""; if (rollMethod == 1) { if (ndays > 1) { contract = rs.getString(10); } else { contract = rs.getString(11); } } else if (rollMethod == 2) { contract = rs.getString(15); } for (int ii = 0; ii < ja.size(); ++ii) { JsonObject jorder = ja.get(ii).getAsJsonObject(); switch (jorder.get("type").getAsString()) { case "EXIT_LONG_STOP": // Action printer.print("SELL"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("STP"); // LmtPrice printer.print(""); // AuxPrice printer.print(formatOrderPrice(jorder.get("stop_price").getAsBigDecimal())); printer.println(); break; case "EXIT_SHORT_STOP": // Action printer.print("BUY"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("STP"); // LmtPrice printer.print(""); // AuxPrice printer.print(formatOrderPrice(jorder.get("stop_price").getAsBigDecimal())); printer.println(); break; case "ENTER_LONG": // Action printer.print("BUY"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("MKT"); // LmtPrice printer.print(""); // AuxPrice printer.print(""); printer.println(); break; case "ENTER_SHORT": // Action printer.print("SELL"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("MKT"); // LmtPrice printer.print(""); // AuxPrice printer.print(""); printer.println(); break; case "ENTER_LONG_STOP": // Action printer.print("BUY"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("STP"); // LmtPrice printer.print(""); // AuxPrice printer.print(formatOrderPrice(jorder.get("stop_price").getAsBigDecimal())); printer.println(); break; case "ENTER_LONG_STOP_LIMIT": // Action printer.print("BUY"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("STP LMT"); // LmtPrice printer.print(formatOrderPrice(jorder.get("limit_price").getAsBigDecimal())); // AuxPrice printer.print(formatOrderPrice(jorder.get("stop_price").getAsBigDecimal())); printer.println(); break; case "ENTER_SHORT_STOP": // Action printer.print("SELL"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("STP"); // LmtPrice printer.print(""); // AuxPrice printer.print(formatOrderPrice(jorder.get("stop_price").getAsBigDecimal())); printer.println(); break; case "ENTER_SHORT_STOP_LIMIT": // Action printer.print("SELL"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("STP LMT"); // LmtPrice printer.print(formatOrderPrice(jorder.get("limit_price").getAsBigDecimal())); // AuxPrice printer.print(formatOrderPrice(jorder.get("stop_price").getAsBigDecimal())); printer.println(); break; case "EXIT_LONG": // Action printer.print("SELL"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("MKT"); // LmtPrice printer.print(""); // AuxPrice printer.print(""); printer.println(); break; case "EXIT_SHORT": // Action printer.print("BUY"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("MKT"); // LmtPrice printer.print(""); // AuxPrice printer.print(""); printer.println(); break; case "EXIT_SHORT_STOP_LIMIT": // Action printer.print("BUY"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("STP LMT"); // LmtPrice printer.print(formatOrderPrice(jorder.get("limit_price").getAsBigDecimal())); // AuxPrice printer.print(formatOrderPrice(jorder.get("stop_price").getAsBigDecimal())); printer.println(); break; case "EXIT_LONG_STOP_LIMIT": // Action printer.print("SELL"); // Quantity printer.print(jorder.get("quantity").getAsLong()); // Symbol printer.print(rs.getString(4)); // SecType printer.print(rs.getString(14)); // LastTradingDayOrContractMonth printer.print(contract); // Exchange printer.print(rs.getString(13)); // OrderType printer.print("STP LMT"); // LmtPrice printer.print(formatOrderPrice(jorder.get("limit_price").getAsBigDecimal())); // AuxPrice printer.print(formatOrderPrice(jorder.get("stop_price").getAsBigDecimal())); printer.println(); break; } } if (printer != null) printer.flush(); } } static private String formatBigDecimal(BigDecimal bd, int minPrecision, int maxPrecision) { bd = bd.setScale(maxPrecision, RoundingMode.HALF_UP).stripTrailingZeros(); int scale = bd.scale() <= minPrecision ? minPrecision : bd.scale(); return String.format("%,." + Integer.toString(scale) + "f", bd); } static private String formatBigDecimal(BigDecimal bd) { return formatBigDecimal(bd, 2, 7); } static private String formatDouble(double dd, int minPrecision, int maxPrecision) { BigDecimal bd = new BigDecimal(dd, MathContext.DECIMAL128); bd = bd.setScale(maxPrecision, RoundingMode.HALF_UP); return formatBigDecimal(bd); } static private String formatDouble(double dd) { return formatDouble(dd, 2, 7); } static private String formatPercentage(double dd) { return formatDouble(dd, 2, 2); } static private String formatOrderPrice(BigDecimal bd) { bd = bd.setScale(7, RoundingMode.HALF_UP).stripTrailingZeros(); int scale = bd.scale() <= 2 ? 2 : bd.scale(); return String.format("%." + Integer.toString(scale) + "f", bd); } }