package simplex.bn25.makino335926.trading.position;
import java.math.BigDecimal;
/**
* クラス: Position
* 銘柄ごとのポジションデータを管理するクラス。
* - 各銘柄の保有数量、平均取得単価、評価額、損益データ(実現損益、評価損益)を管理。
* - 取引情報に基づき、これらのデータを計算および更新する機能を提供。
*
* 主な用途:
* - 保有している株式や銘柄のデータを保存・計算・取得する。
*/
public class Position {
// === インスタンス変数 ===
private final String ticker; // 銘柄コード (例: "7203"などのユニークな識別子)
private final String name; // 銘柄名 (例: "Toyota")
private long quantity; // 保有数量 (現在保有している株数)
private BigDecimal averageUnitPrice; // 平均取得単価 (買い付けた価格の加重平均)
private BigDecimal realizedPnL; // 実現損益 (売却済み取引で確定した損益)
private BigDecimal valuation; // 評価額 (現在の時価に基づく全保有株式の評価額)
private BigDecimal unrealizedPnL; // 評価損益 (未売却分の損益: 評価額 - 平均取得単価 * 保有数量)
// === コンストラクタ ===
/**
* コンストラクタ: Position
* 各インスタンス変数を初期化する。
*
* @param ticker 銘柄コード
* @param name 銘柄名
*/
public Position(String ticker, String name) {
this.ticker = ticker; // 銘柄コードの初期化
this.name = name; // 銘柄名の初期化
this.quantity = 0; // 初期状態の保有数量は0
this.averageUnitPrice = BigDecimal.ZERO; // 平均取得単価は初期値0
this.realizedPnL = BigDecimal.ZERO; // 実現損益は初期値0
this.valuation = null; // 評価額は時価データがない場合はnull
this.unrealizedPnL = null; // 評価損益も初期状態ではnull
}
// === Getterメソッド ===
/**
* 銘柄コードを取得する。
* @return 銘柄コード
*/
public String getTicker() {
return ticker;
}
/**
* 銘柄名を取得する。
* @return 銘柄名
*/
public String getName() {
return name;
}
/**
* 現在の保有数量を取得する。
* @return 保有数量
*/
public long getQuantity() {
return quantity;
}
/**
* 平均取得単価を取得する。
* @return 平均取得単価
*/
public BigDecimal getAverageUnitPrice() {
return averageUnitPrice;
}
/**
* 実現損益を取得する。
* @return 実現損益
*/
public BigDecimal getRealizedPnL() {
return realizedPnL;
}
/**
* 評価額を取得する。
* @return 評価額
*/
public BigDecimal getValuation() {
return valuation;
}
/**
* 評価損益を取得する。
* @return 評価損益
*/
public BigDecimal getUnrealizedPnL() {
return unrealizedPnL;
}
// === Setterおよび更新メソッド ===
/**
* 保有数量を更新する。
* 取引の増減に応じて数量を加算または減算。
*
* @param delta 増減分(買いの場合は正の値、売りの場合は負の値)
*/
public void updateQuantity(long delta) {
this.quantity += delta;
}
/**
* 平均取得単価を更新する。
* 新たな購入データ(価格と数量)を基に、加重平均を再計算。
*
* @param newPrice 新たに購入した株式の単価
* @param deltaQuantity 新たに購入した株式の数量
*/
public void updateAverageUnitPrice(BigDecimal newPrice, long deltaQuantity) {
// 現在の総コストを計算
BigDecimal totalCost = this.averageUnitPrice.multiply(BigDecimal.valueOf(this.quantity))
.add(newPrice.multiply(BigDecimal.valueOf(deltaQuantity)));
// 保有数量を更新
this.quantity += deltaQuantity;
// 平均取得単価を再計算
if (this.quantity > 0) {
// 現在の総コストを新しい数量で割る
this.averageUnitPrice = totalCost.divide(BigDecimal.valueOf(this.quantity), 2, BigDecimal.ROUND_HALF_UP);
} else {
// 保有数量が0になった場合、平均取得単価をリセット
this.averageUnitPrice = BigDecimal.ZERO;
}
}
/**
* 実現損益を追加する。
* 売却取引で得た損益を累積損益に加算。
*
* @param amount 売却取引で得た損益額
*/
public void addRealizedPnL(BigDecimal amount) {
this.realizedPnL = this.realizedPnL.add(amount);
}
/**
* 評価額と評価損益を設定する。
* 現在の保有数量と時価データを基に計算。
*
* @param marketPrice 現在の時価
*/
public void setValuation(BigDecimal marketPrice) {
if (marketPrice != null) {
// 評価額 = 時価 × 保有数量
this.valuation = marketPrice.multiply(BigDecimal.valueOf(this.quantity));
// 評価損益 = 評価額 - (平均取得単価 × 保有数量)
this.unrealizedPnL = this.valuation.subtract(this.averageUnitPrice.multiply(BigDecimal.valueOf(this.quantity)));
} else {
// 時価データがない場合、評価額と評価損益はnull
this.valuation = null;
this.unrealizedPnL = null;
}
}
}
コメント