package simplex.bn25.makino335926.trading.Position;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
/**
* クラス: CsvReader
* 時価情報をCSVファイルから読み込むクラス。
*/
public class CsvReader {
private static final String MARKET_PRICE_FILE = "market_prices.csv"; // 時価データのCSVファイル名
/**
* CSVファイルから時価情報を読み込む。
*
* @return 銘柄コードと時価情報のマップ
* @throws IllegalArgumentException 不正なデータが含まれている場合
*/
public static Map<String, BigDecimal> loadMarketPrices() throws IllegalArgumentException {
Map<String, BigDecimal> marketPrices = new HashMap<>();
try (BufferedReader br = new BufferedReader(new FileReader(MARKET_PRICE_FILE))) {
String line;
// ヘッダー行をスキップ
if ((line = br.readLine()) == null) {
throw new IllegalArgumentException("エラー: CSVファイルが空です。");
}
// データ行を処理
int lineNumber = 1;
while ((line = br.readLine()) != null) {
lineNumber++;
String[] parts = line.split(",");
if (parts.length != 2) {
throw new IllegalArgumentException("エラー: CSVの形式が不正です(行番号: " + lineNumber + ")。" +
"正しい形式: ticker,market_price");
}
String ticker = parts[0];
String priceStr = parts[1];
try {
BigDecimal price = new BigDecimal(priceStr); // 時価を数値に変換
marketPrices.put(ticker, price); // マップに登録
} catch (NumberFormatException e) {
throw new IllegalArgumentException("エラー: 時価データが不正です(行番号: " + lineNumber + "、値: " + priceStr + ")。");
}
}
} catch (IOException e) {
throw new IllegalArgumentException("エラー: 時価データのファイル読み込み中に問題が発生しました: " + e.getMessage());
}
return marketPrices;
}
}
package simplex.bn25.makino335926.trading.Position;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
* クラス: DisplayPosition
* 保有ポジションを表形式で表示するクラス。
*/
public class DisplayPosition {
/**
* 保有ポジションを表示するメインメソッド。
*
* @param positions 保有ポジションのリスト
*/
public static void displayPositions(List<Position> positions) {
// 時価データをCSVファイルから読み込む
Map<String, BigDecimal> marketPrices;
try {
marketPrices = CsvReader.loadMarketPrices();
} catch (IllegalArgumentException e) {
// CSVファイルのエラーを表示して処理を中断
System.out.println(e.getMessage());
return; // 表示処理を中止
}
// 表ヘッダーを出力
System.out.println("|==============================================================================================|");
System.out.println("| Ticker | Name | Quantity | Avg Unit Price | Realized PnL | Valuation | Unrealized PnL |");
System.out.println("|--------+----------------------------+----------+----------------+---------------+------------+----------------|");
// 各ポジションのデータを計算・表示
for (Position position : positions) {
String ticker = position.getTicker();
String name = position.getName();
long quantity = position.getQuantity();
BigDecimal avgUnitPrice = position.getAverageUnitPrice();
BigDecimal realizedPnL = position.getRealizedPnL();
// Valuation(評価額)とUnrealized PnL(評価損益)の計算
BigDecimal marketPrice = marketPrices.get(ticker); // 時価データを取得
String valuation;
String unrealizedPnL;
if (marketPrice != null) {
// 時価データが存在する場合
BigDecimal valuationValue = marketPrice.multiply(BigDecimal.valueOf(quantity));
BigDecimal unrealizedPnLValue = valuationValue.subtract(avgUnitPrice.multiply(BigDecimal.valueOf(quantity)));
valuation = formatCurrency(valuationValue);
unrealizedPnL = formatCurrency(unrealizedPnLValue);
} else {
// 時価データが存在しない場合
valuation = "N/A";
unrealizedPnL = "N/A";
}
// 表示フォーマットに従い出力
System.out.printf("| %-6s | %-26s | %8s | %14s | %13s | %10s | %14s |\n",
ticker,
name,
String.format("%,d", quantity),
formatCurrency(avgUnitPrice),
formatCurrency(realizedPnL),
valuation,
unrealizedPnL);
}
System.out.println("|==============================================================================================|");
}
/**
* 金額データをフォーマット(3桁区切り、小数点以下2桁)。
*
* @param value フォーマット対象の金額
* @return フォーマット済みの文字列
*/
private static String formatCurrency(BigDecimal value) {
return value != null ? String.format("%,.2f", value) : "N/A";
}
}
コメント