/** * {inheritDoc} */ public function supports(MarketDepthPriceInterface $requestedDepth) { // need to match BID -> ASK and ASK -> BID to be satisfied if ($requestedDepth->getType() === $this->type) { $errorMessage = "Cannot check if market depth price of type '%s' supports market depth price of type '%s' (only %s orders can satisfy %s orders)"; throw new InvalidArgumentException(sprintf($errorMessage, $requestedDepth->getType(), $this->type, CurrencyExchangeOperationInterface::TYPE_BID, CurrencyExchangeOperationInterface::TYPE_ASK)); } // must be equal or inverse if (!$this->equals($requestedDepth) && !$this->isInverse($requestedDepth)) { $errorMessage = "Cannot check if market depth price is supported: fromCurrency and toCurrency must match."; throw new InvalidArgumentException($errorMessage); } $thisAmountCurrency = $this->depth->getCurrency(); $requestedAmountCurrency = $requestedDepth->getDepth()->getCurrency(); $requestedAmount = $requestedDepth->getDepth(); if (!$thisAmountCurrency->equals($requestedAmountCurrency)) { $requestedAmount = $requestedDepth->convert($requestedAmount); } if (CurrencyExchangeOperationInterface::TYPE_ASK === $this->type) { // request is BID (to buy), so they must outbid or match our asking price if ($requestedDepth->getMultiplier() >= $this->multiplier && $requestedAmount->isLessOrEqual($this->depth)) { return true; } return false; } // CurrencyExchangeOperationInterface::TYPE_BID === $this->type // request is ASK (to sell), so their selling price must be less or matching our buy price if ($requestedDepth->getMultiplier() <= $this->multiplier && $this->depth->isLessOrEqual($requestedAmount)) { return true; } return false; }
/** * {inheritDoc} */ public function convert(MoneyInterface $amount) { if ($amount->getCurrency()->equals($this->getFromCurrency())) { $totalPrecision = $this->fromCurrency->getPrecision() + $this->toCurrency->getPrecision(); $targetPrecision = $this->toCurrency->getPrecision(); $newAmount = bcmul((string) $amount->getAmountFloat(), (string) $this->getMultiplier(), $totalPrecision); $roundedAmount = round($newAmount, $targetPrecision); $newMoney = new Money($this->toCurrency); $newMoney->setAmountFloat($roundedAmount); return $newMoney; } // rate represents inverse, so treat "from" and "to" reversed if ($amount->getCurrency()->equals($this->getToCurrency())) { $totalPrecision = $this->fromCurrency->getPrecision() + $this->toCurrency->getPrecision(); $targetPrecision = $this->fromCurrency->getPrecision(); $newAmount = bcdiv((string) $amount->getAmountFloat(), (string) $this->getMultiplier(), $totalPrecision); $roundedAmount = round($newAmount, $targetPrecision); $newMoney = new Money($this->fromCurrency); $newMoney->setAmountFloat($roundedAmount); return $newMoney; } throw new InvalidArgumentException("Cannot convert from " . $amount->getCurrency()->getCurrencyCode() . " using CurrencyRate of " . $this->getFromCurrency()->getCurrencyCode() . " to " . $this->getToCurrency()->getCurrencyCode() . ": CurrencyRate must include the base currency " . $amount->getCurrency()->getCurrencyCode()); }
public function isSameCurrency(MoneyInterface $rightHandValue) { return $this->currency->equals($rightHandValue->getCurrency()); }