예제 #1
0
  /**
   * @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);
  }
예제 #2
0
  /**
   * Assumption is the account base currency is USD
   *
   * @param accountLeverage accountLeverage
   * @param closePrice closePrice
   * @param p p
   * @param baseCurrency Now Assumption is the account base currency is USD
   * @return position margin
   */
  public static Double calculateMargin(
      Double accountLeverage, Double closePrice, Position p, Currency baseCurrency) {
    TradingUtils.assertStat(baseCurrency == Currency.USD, "\"The baseCurrency is not USD!\"");
    if (p.getInstrument().getCurrency1() != baseCurrency) {
      if (!getInterestInstrumentList()
          .contains(new Instrument(p.getInstrument().getCurrency1(), baseCurrency))) {
        throw new RuntimeException(
            "No related instrument data found! ("
                + new Instrument(p.getInstrument().getCurrency1(), baseCurrency)
                + ")");
      }

      return closePrice * p.getAmount() * TradingUtils.getGolbalAmountUnit() / accountLeverage;
    } else {
      return p.getAmount() * TradingUtils.getGolbalAmountUnit() / accountLeverage;
    }
  }
예제 #3
0
  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;
  }