package simplex.bn25.makino335926.trading.position;
import java.math.BigDecimal;
/**
* クラス: Position
* 銘柄ごとのポジションデータを管理するクラス。
* 保有数量が0(クローズ)になった場合、平均取得単価をリセットする処理を追加。
*/
public class Position {
private final String ticker; // 銘柄コード
private final String name; // 銘柄名
private long quantity; // 保有数量
private BigDecimal averageUnitPrice; // 平均取得単価
private BigDecimal realizedPnL; // 実現損益
private BigDecimal valuation; // 評価額
private BigDecimal unrealizedPnL; // 評価損益
/**
* コンストラクタ
* 初期状態では保有数量、単価、損益をすべてゼロまたは初期値で設定。
*
* @param ticker 銘柄コード
* @param name 銘柄名
*/
public Position(String ticker, String name) {
this.ticker = ticker;
this.name = name;
this.quantity = 0;
this.averageUnitPrice = BigDecimal.ZERO;
this.realizedPnL = BigDecimal.ZERO;
this.valuation = null;
this.unrealizedPnL = null;
}
// Getterメソッド: 保有データや計算済みデータを取得
public String getTicker() { return ticker; }
public String getName() { return name; }
public long getQuantity() { return quantity; }
public BigDecimal getAverageUnitPrice() { return averageUnitPrice; }
public BigDecimal getRealizedPnL() { return realizedPnL; }
public BigDecimal getValuation() { return valuation; }
public BigDecimal getUnrealizedPnL() { return unrealizedPnL; }
/**
* メソッド: updateQuantity
* 保有数量を増減し、数量が0になった場合は平均取得単価をリセット。
*
* @param delta 増減分(買いなら正、売りなら負)
*/
public void updateQuantity(long delta) {
this.quantity += delta; // 保有数量を更新
if (this.quantity == 0) {
// 保有数量が0の場合、ポジションはクローズされたとみなし、平均取得単価をリセット
this.averageUnitPrice = BigDecimal.ZERO;
}
}
/**
* メソッド: updateAverageUnitPrice
* 新たな購入単価を基に加重平均を計算し、平均取得単価を更新。
* 保有数量が0の場合、単価をリセット。
*
* @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;
}
}
/**
* メソッド: addRealizedPnL
* 実現損益を累積更新。
*
* @param amount 売却取引で得た損益額
*/
public void addRealizedPnL(BigDecimal amount) {
this.realizedPnL = this.realizedPnL.add(amount);
}
/**
* メソッド: setValuation
* 保有数量と時価データに基づき、評価額と評価損益を計算。
*
* @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 {
this.valuation = null;
this.unrealizedPnL = null;
}
}
}
コメント