package simplex.bn25.datemasa335859.trading.common;
import java.math.BigDecimal;
import java.text.NumberFormat;
public class DisplayFormatter {
// 文字列を最大長に切り詰め、必要に応じて”…”を追加する
public static String truncateString(String str, int maxLength) {
if (str.length() > maxLength) {
return str.substring(0, maxLength – 3) + “…”; // 最大長から3文字分を引いて”…”を追加
}
return str; // 短縮不要の場合はそのまま返す
}
// 数字をカンマ区切りでフォーマットする
public static String formatNumber(long number) {
return NumberFormat.getNumberInstance().format(number);
}
public static String formatDecimal(BigDecimal number) {
return NumberFormat.getNumberInstance().format(number);
}
}
package simplex.bn25.datemasa335859.trading.a;
import simplex.bn25.datemasa335859.trading.common.DisplayFormatter;
import simplex.bn25.datemasa335859.trading.stock.TickerManager;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.TreeMap;
public class PositionCalculator {
private final TradeDataLoader tradeDataLoader;
public PositionCalculator(TradeDataLoader tradeDataLoader) {
this.tradeDataLoader = tradeDataLoader;
}
public void displayPositions() {
Map<String, Position> positions = new TreeMap<>(tradeDataLoader.calculatePositions()); // Tickerで昇順ソート
if (positions.isEmpty()) {
System.out.println("取引データが登録されていません。");
return;
}
// 表のヘッダーを表示
System.out.println("|===============================================================================================================|");
System.out.println("| Ticker | Product Name | Quantity | Avg Unit Price | Realized PnL | Valuation | Unrealized PnL |");
System.out.println("|--------+-------------------------------+------------+------------------+----------------+-------------+----------------|");
// 各ポジションについて情報を表示
for (Map.Entry<String, Position> entry : positions.entrySet()) {
String ticker = entry.getKey();
Position position = entry.getValue();
// Ticker Nameの取得
String tickerName = TickerManager.getTickerToNameMap().getOrDefault(ticker, "Unknown");
// 時価情報を取得
BigDecimal marketPrice = MarketPriceLoader.getMarketPrice(ticker);
// 各項目の計算
BigDecimal valuation = marketPrice != null
? position.calculateValuation(marketPrice).setScale(2, RoundingMode.HALF_UP)
: null;
BigDecimal unrealizedPnL = marketPrice != null
? position.calculateUnrealizedPnL(marketPrice).setScale(2, RoundingMode.HALF_UP)
: null;
BigDecimal realizedPnL = position.getRealizedPnL().setScale(2, RoundingMode.HALF_UP);
// 表形式で出力
System.out.printf("| %-6s | %-29s | %10s | %,16.2f | %,14.2f | %-11s | %-14s |\n",
ticker,
DisplayFormatter.truncateString(tickerName, 25),
DisplayFormatter.formatNumber(position.quantity()),
position.getAverageUnitPrice(),
realizedPnL,
valuation != null ? DisplayFormatter.formatDecimal(valuation) : "N/A",
unrealizedPnL != null ? DisplayFormatter.formatDecimal(unrealizedPnL) : "N/A");
}
// 表のフッターを表示
System.out.println("|===============================================================================================================|");
}
}
コメント