/** * @param position - the ForexPosition that Open PnL should be calculated for * @param currentPrices - a map of current PriceQuotes by Instrument. Required for cases in which * the base currency of the account is not part of the instrument. * @param baseCurrency - a Currency object representing the base currency of the account the trade * is occurring under - required for when the base currency of the account is not involved in * the position. * @return a double representing the unrealized gain/loss (aka Open Profit/Loss). */ public static double calculateOpenPnL( Position position, Map<Instrument, HistoryDataKBar> currentPrices, Currency baseCurrency) { double openPnL = 0.0d; // Check to see that the instrument of the ForexPosition // contains the base currency of the brokerage account... If not - locate the intermediary // instrument. // For example: the position instrument is AUD/NZD and the account base currency is in USD. // This means in order to calculate the PnL on the position, an intermediate position // of USD/AUD will have to be calculated. if (position.getInstrument() == null) { logger.warn( "Unable to calculate Open PnL for position: " + position.getId() + " Instrument is null!"); return openPnL; } if (position.getAmount() == null) { logger.warn( "Unable to calculate Open PnL for position: " + position.getId() + " Size is null!"); return openPnL; } if (position.getDirection() == null) { logger.warn( "Unable to calculate Open PnL for position: " + position.getId() + " Direction is null!"); return openPnL; } if (position.getOpenPrice() == null) { logger.warn( "Unable to calculate Open PnL for position: " + position.getId() + " Open Price is null!"); return openPnL; } HistoryDataKBar instrumentPriceBar = currentPrices.get(position.getInstrument()); HistoryDataKBar conversionPriceBar = null; if (baseCurrency != position.getInstrument().getCurrency1() && baseCurrency != position.getInstrument().getCurrency2()) { Instrument conversionInstrument = new Instrument(baseCurrency, position.getInstrument().getCurrency2()); conversionPriceBar = currentPrices.get(conversionInstrument); } return calculateOpenPnL( position.getAmount(), position.getDirection(), position.getOpenPrice(), instrumentPriceBar, conversionPriceBar, baseCurrency); }
public static double calculateRealizedPnL( Position position, Map<Instrument, HistoryDataKBar> currentPrices, Currency baseCurrency) { Double amount = position.getAmount(); Direction direction = position.getDirection(); Double openPrice = position.getOpenPrice(); Double closePrice = position.getClosePrice(); HistoryDataKBar instrumentPriceBar = currentPrices.get(position.getInstrument()); HistoryDataKBar conversionPriceBar = null; if (baseCurrency != position.getInstrument().getCurrency1() && baseCurrency != position.getInstrument().getCurrency2()) { Instrument conversionInstrument = new Instrument(baseCurrency, position.getInstrument().getCurrency2()); conversionPriceBar = currentPrices.get(conversionInstrument); } Double realizedPnL; // Standard PnL calculation. This is in the second currency of the instrument if (direction == Direction.Long) { realizedPnL = amount * TradingUtils.getGolbalAmountUnit() * (closePrice - openPrice); } else { realizedPnL = amount * TradingUtils.getGolbalAmountUnit() * (openPrice - closePrice); } // simple case -- pips is already in base currency if (baseCurrency == instrumentPriceBar.getInstrument().getCurrency2()) return realizedPnL; // if the base currency is the first currency of the instrument, we need to // divide pips by ask price to get pips in base currency if (instrumentPriceBar.getInstrument().getCurrency1() == baseCurrency) { realizedPnL = realizedPnL / instrumentPriceBar.getOhlc().getAskClose(); return realizedPnL; } if (conversionPriceBar == null) throw new IllegalArgumentException( "need a conversion price when computing instrument " + conversionPriceBar.getInstrument() + " into P/L of base currency " + baseCurrency); if (baseCurrency == conversionPriceBar.getInstrument().getCurrency1()) { // use the 'ask' realizedPnL = realizedPnL / conversionPriceBar.getOhlc().getAskClose(); } else { // use the 'bid' realizedPnL = realizedPnL * conversionPriceBar.getOhlc().getBidClose(); } return realizedPnL; }