PositionDisplay.java
'''java
import java.io.;
import java.util.;
public class PositionDisplay {
public static void displayPositions() {
System.out.println("保有ポジションを表示します。");
try {
// 取引データから保有数量を算出
Map<String, Integer> positionMap = calculatePositions();
if (positionMap.isEmpty()) {
System.out.println("保有ポジションがありません。");
return;
}
// 銘柄マスターから銘柄名を取得するマップを作成
Map<String, String> tickerToNameMap = createTickerToNameMap();
// 表形式で表示
displayPositionTable(positionMap, tickerToNameMap);
} catch (FileNotFoundException e) {
System.out.println("エラー: 取引データファイルが見つかりません: transactions.csv");
} catch (Exception e) {
System.out.println("エラー: " + e.getMessage());
}
}
private static Map<String, Integer> calculatePositions() throws IOException {
Map<String, Integer> positionMap = new HashMap<>();
try (BufferedReader reader = new BufferedReader(new FileReader("transactions.csv"))) {
String headerLine = reader.readLine();
if (headerLine == null) {
return positionMap;
}
String line;
while ((line = reader.readLine()) != null) {
String[] fields = line.split(",");
if (fields.length >= 4) {
String ticker = fields[1].trim(); // ticker
String side = fields[2].trim(); // side
int quantity = Integer.parseInt(fields[3].trim()); // quantity
// 現在の保有数量を取得(なければ0)
int currentPosition = positionMap.getOrDefault(ticker, 0);
// B(買い)の場合は加算、S(売り)の場合は減算
if ("B".equals(side)) {
positionMap.put(ticker, currentPosition + quantity);
} else if ("S".equals(side)) {
positionMap.put(ticker, currentPosition - quantity);
}
}
}
}
// 保有数量が0の銘柄を除外
positionMap.entrySet().removeIf(entry -> entry.getValue() == 0);
return positionMap;
}
private static Map<String, String> createTickerToNameMap() {
Map<String, String> tickerToNameMap = new HashMap<>();
try (BufferedReader reader = new BufferedReader(new FileReader("Masterdata.csv"))) {
reader.readLine(); // ヘッダー行をスキップ
String line;
while ((line = reader.readLine()) != null) {
String[] fields = line.split(",");
if (fields.length >= 2) {
String ticker = fields[0].trim();
String productName = fields[1].trim();
tickerToNameMap.put(ticker, productName);
}
}
} catch (IOException e) {
// 銘柄マスターが見つからない場合は空のマップを返す
}
return tickerToNameMap;
}
private static void displayPositionTable(Map<String, Integer> positionMap, Map<String, String> tickerToNameMap) {
// 銘柄コードでソートされたリストを作成
List<Map.Entry<String, Integer>> sortedPositions = new ArrayList<>(positionMap.entrySet());
Collections.sort(sortedPositions, (e1, e2) -> e1.getKey().compareTo(e2.getKey()));
System.out.println();
System.out.println("+------+----------------------+------------+");
System.out.println("| 銘柄コード | 銘柄名 | 保有数量 |");
System.out.println("+------+----------------------+------------+");
for (Map.Entry<String, Integer> entry : sortedPositions) {
String ticker = entry.getKey();
int position = entry.getValue();
String productName = tickerToNameMap.getOrDefault(ticker, "不明");
// 銘柄名が20文字以上の場合は省略
if (productName.length() > 20) {
productName = productName.substring(0, 17) + "...";
}
// 保有数量は右詰め、3桁ごとのカンマ区切りで表示
System.out.printf("| %-10s | %-20s | %10s |%n",
ticker,
productName,
String.format("%,d", position));
}
System.out.println("+------+----------------------+------------+");
}
}
'''