public class PositionCalculatorHelper {
public static Map<String, Position> calculatePositionsFromTrades(List<Trade> trades) {
Map<String, Position> positions = new HashMap<>();
for (Trade trade : trades) {
String ticker = trade.ticker();
String tickerName = trade.tickerName();
positions.putIfAbsent(ticker, new Position(ticker, tickerName, 0L));
Position currentPosition = positions.get(ticker);
currentPosition.processTrade(trade); // 各取引を処理してポジションを更新
}
return positions;
}
}
public void displayPositions() {
Map<String, Position> positions = tradeDataLoader.calculatePositions();
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();
BigDecimal marketPrice = MarketPriceLoader.getMarketPrice(ticker);
BigDecimal valuation = marketPrice != null ? position.calculateValuation(marketPrice) : null;
BigDecimal unrealizedPnL = marketPrice != null ? position.calculateUnrealizedPnL(marketPrice) : null;
System.out.printf("| %-6s | %-29s | %10d | %,16.2f | %-14s | %-11s | %-14s |\n",
position.ticker(),
position.tickerName(),
position.quantity(),
position.getAverageUnitPrice(),
position.getRealizedPnL().compareTo(BigDecimal.ZERO) != 0 ? position.getRealizedPnL() : "N/A",
valuation != null ? valuation : "N/A",
unrealizedPnL != null ? unrealizedPnL : "N/A");
}
System.out.println("|===============================================================================================================|");
}
下記は問題なければ修正しなくて良い。
package simplex.bn25.datemasa335859.trading.a;
import simplex.bn25.datemasa335859.trading.trade.Trade;
import simplex.bn25.datemasa335859.trading.a.PositionCalculatorHelper;
import java.util.List;
import java.util.Map;
public class TradeDataLoader {
// CSVファイルをロードし、取引データをリストとして取得
public List<Trade> loadTrades() {
return TradeDisplay.loadTradesFromCSV(); // CSVファイルから取引データを取得
}
// 取引データからポジションを計算
public Map<String, Position> calculatePositions() {
List<Trade> trades = loadTrades(); // 修正箇所: 取引データを取得
return PositionCalculatorHelper.calculatePositionsFromTrades(trades);
}
}
package simplex.bn25.datemasa335859.trading;
import simplex.bn25.datemasa335859.trading.a.PositionCalculator;
import simplex.bn25.datemasa335859.trading.a.TradeDataLoader;
import simplex.bn25.datemasa335859.trading.common.ShowMenu;
import simplex.bn25.datemasa335859.trading.stock.DisplayStockMaster;
import simplex.bn25.datemasa335859.trading.stock.RegisterStock;
import simplex.bn25.datemasa335859.trading.trade.Trade;
import simplex.bn25.datemasa335859.trading.trade.TradeDisplay;
import simplex.bn25.datemasa335859.trading.trade.TradeInputHandler;
import simplex.bn25.datemasa335859.trading.trade.TradeWriter;
import java.util.Scanner;
import static simplex.bn25.datemasa335859.trading.a.MarketPriceLoader.loadMarketPrices;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean isRunning = true;
// 必要なクラスのインスタンスを初期化
TradeDataLoader tradeDataLoader = new TradeDataLoader(); // 取引データローダー
PositionCalculator positionCalculator = new PositionCalculator(tradeDataLoader); // ポジション計算機
// アプリケーション起動時に時価情報をロード
loadMarketPrices();
System.out.println("時価情報をロードしました。");
System.out.println("株式取引管理システムを開始します。");
while (isRunning) {
// メニューを表示
ShowMenu.showMenu();
String input = scanner.nextLine();
switch (input) {
case "1":
System.out.println(" >「銘柄マスタ一覧表示」が選択されました。");
DisplayStockMaster.displayStockMaster();
break;
case "2":
System.out.println(" >「銘柄マスタ新規登録」が選択されました。");
RegisterStock.registerStock();
break;
case "3":
System.out.println(" >「取引入力」が選択されました。");
try {
// 取引入力の処理
Trade trade = TradeInputHandler.registerTrade(
TickerManager.getExistingTickers(),
TickerManager.getTickerToNameMap(),
tradeDataLoader.calculatePositions());
if (trade != null) {
TradeWriter.writeTradeToCSV(trade); // 取引データをCSVに保存
System.out.println("取引データが登録されました。");
}
} catch (Exception e) {
System.out.println("エラー: 取引入力中に問題が発生しました。詳細: " + e.getMessage());
}
break;
case "4":
System.out.println(" >「取引一覧の表示」が選択されました。");
TradeDisplay.displayTradeList(); // 取引一覧を表示
break;
case "5":
System.out.println(" >「保有ポジション表示」が選択されました。");
try {
positionCalculator.displayPositions(); // ポジションを表示
} catch (Exception e) {
System.out.println("エラー: 保有ポジション表示中に問題が発生しました。詳細: " + e.getMessage());
}
break;
case "6":
System.out.println(" >「時価情報更新」が選択されました。");
loadMarketPrices(); // 時価情報を再ロード
System.out.println("時価情報を更新しました。");
break;
case "9":
System.out.println(" > アプリケーションを終了します。");
isRunning = false; // 終了フラグを設定
break;
default:
System.out.println(input + "に対応するメニューは存在しません。");
break;
}
}
scanner.close(); // スキャナーを閉じる
}
}
package simplex.bn25.datemasa335859.trading.trade;
import simplex.bn25.datemasa335859.trading.common.DisplayFormatter;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class TradeDisplay {
private static final String CSV_FILE_PATH = "trading-app/src/trades.csv";
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
public static void displayTradeList() {
List<Trade> trades = loadTradesFromCSV();
if (trades.isEmpty()) {
System.out.println("取引が登録されていません。");
return;
}
trades.sort(Comparator.comparing(Trade::tradeDate).reversed());
System.out.println("|==========================================================================================================|");
System.out.println("| Trade Date | Ticker | Ticker Name | Side | Quantity | Price |");
System.out.println("|--------------------+--------+-------------------------------+------+--------------------+----------------|");
for (Trade trade : trades) {
System.out.printf("| %-18s | %-6s | %-29s | %-4s | %,18d | %,14.2f |\n",
trade.getFormattedTradeDate(),
trade.ticker(),
DisplayFormatter.truncateString(trade.tickerName(), 27),
trade.side(),
trade.quantity(),
trade.tradePrice());
}
System.out.println("|==========================================================================================================|");
}
public static List<Trade> loadTradesFromCSV() {
List<Trade> trades = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(CSV_FILE_PATH))) {
br.readLine(); // Skip header
String line;
while ((line = br.readLine()) != null) {
String[] data = line.split(",");
if (data.length < 7) {
continue; // Ensure correct data format
}
LocalDateTime tradeDate = LocalDateTime.parse(data[0], DATE_FORMAT);
String ticker = data[1];
String tickerName = data[2];
String side = data[3];
int quantity = Integer.parseInt(data[4]);
BigDecimal tradePrice = new BigDecimal(data[5]);
LocalDateTime entryTimestamp = LocalDateTime.parse(data[6], DATE_FORMAT);
trades.add(new Trade(tradeDate, ticker, tickerName, side, quantity, tradePrice, entryTimestamp));
}
} catch (IOException e) {
System.out.println("エラー: 取引データの読み込みに失敗しました。");
}
return trades;
}
}
コメント