/** * @expectedException Matmar10\Money\Exception\InvalidArgumentException */ public function testCannotConvertMismatchedCurrency() { $jpn = new Currency('JPY', 5, 2); $jpnAmount = new Money($jpn); $jpnAmount->setAmountFloat(100); $this->rate->convert($jpnAmount); }
/** * @dataProvider provideTestData */ public function test(CurrencyPairInterface $pair, CurrencyInterface $depthCurrency, array $bids, array $asks, $desiredRate, $desiredType, $desiredCurrency, $desiredAmountFloat, array $expectedSupported, $exception) { if ($exception) { $this->setExpectedException($exception); } $collection = new MarketDepthCollection(); $collection->setCurrencyPair($pair); foreach ($bids as $bidPrice => $bidAmount) { $amount = new Money($depthCurrency); $amount->setAmountFloat($bidAmount); $bid = new MarketDepthPrice($pair->getFromCurrency(), $pair->getToCurrency(), (double) $bidPrice, CurrencyExchangeOperationInterface::TYPE_BID, $amount); $collection->add($bid); } foreach ($asks as $askPrice => $askAmount) { $amount = new Money($depthCurrency); $amount->setAmountFloat($askAmount); $ask = new MarketDepthPrice($pair->getFromCurrency(), $pair->getToCurrency(), (double) $askPrice, CurrencyExchangeOperationInterface::TYPE_ASK, $amount); $collection->add($ask); } $desiredAmount = new Money($desiredCurrency); $desiredAmount->setAmountFloat($desiredAmountFloat); $desired = new MarketDepthPrice($pair->getFromCurrency(), $pair->getToCurrency(), $desiredRate, $desiredType, $desiredAmount); $expectedType = CurrencyExchangeOperationInterface::TYPE_ASK === $desiredType ? CurrencyExchangeOperationInterface::TYPE_BID : CurrencyExchangeOperationInterface::TYPE_ASK; $expectedSupportedDepthPrices = array(); foreach ($expectedSupported as $price => $amount) { $amountAsMoney = new Money($depthCurrency); $amountAsMoney->setAmountFloat($amount); $expectedSupportedDepthPrices[$price] = new MarketDepthPrice($pair->getFromCurrency(), $pair->getToCurrency(), (double) $price, $expectedType, $amountAsMoney); } $supported = $collection->getSupported($desired); $this->assertEquals($expectedSupportedDepthPrices, $supported); }
public static function asMoneyFromFloat($input, $currencyCode, $calculationPrecision, $displayPrecision, $symbol) { $currency = new Currency($currencyCode, $calculationPrecision, $displayPrecision, $symbol); $amount = new Money($currency); $amount->setAmountFloat($input); return $amount; }
/** * Constructs a new market depth point * * @param float $priceAsFloat The BTC:USD exchange rate * @param float $amount The amount of market supply or demand at this exchange rate */ public function __construct($priceAsFloat, $amount) { $this->fromCurrency = new Currency('BTC', 8, 8, 'B⃦'); $this->toCurrency = new Currency('USD', 2, 2, '$'); $this->multiplier = $priceAsFloat; $this->amount = new Money($this->fromCurrency); $this->amount->setAmountFloat($amount); }
/** * @dataProvider provideTestSupportsData */ public function testSupports(Currency $from, Currency $to, $rate, $type, Currency $depthCurrency, $depthAmountFloat, Currency $supportsFrom, Currency $supportsTo, $supportsRate, $supportsType, $supportsCurrency, $supportsAmountFloat, $expectedSupportsResult, $exception) { if ($exception) { $this->setExpectedException($exception); } $depth = new Money($depthCurrency); $depth->setAmountFloat($depthAmountFloat); $marketDepthPrice = new MarketDepthPrice($from, $to, $rate, $type, $depth); $desiredDepthAmount = new Money($supportsCurrency); $desiredDepthAmount->setAmountFloat($supportsAmountFloat); $desiredDepth = new MarketDepthPrice($supportsFrom, $supportsTo, $supportsRate, $supportsType, $desiredDepthAmount); $this->assertEquals($expectedSupportsResult, $marketDepthPrice->supports($desiredDepth)); }
/** * @dataProvider provideTestGetMarketDepth */ public function testGetMarketDepth($response, $expectedCurrentAskMultiplier, $expectedCurrentBidMultiplier) { $this->plugin->addResponse($response); $command = $this->client->getCommand('getMarketDepth'); $result = $this->client->execute($command); $askCollection = $result->get('ask'); $this->assertInstanceOf('\\Matmar10\\Money\\CurrencyExchange\\Entity\\MarketDepthCollectionInterface', $askCollection); $ask = current($askCollection->getAsks()); $this->assertInstanceOf('\\Matmar10\\Money\\CurrencyExchange\\Entity\\MarketDepthPrice', $ask); $this->assertInstanceOf('\\Matmar10\\Money\\Entity\\Currency', $ask->getFromCurrency()); $this->assertInstanceOf('\\Matmar10\\Money\\Entity\\Currency', $ask->getToCurrency()); $this->assertEquals($expectedCurrentAskMultiplier, $ask->getMultiplier()); $this->assertInstanceOf('\\Matmar10\\Money\\Entity\\Money', $ask->getDepth()); // test scenario when you want to buy $1234.56 USD worth of BTC $baseCurrency = new Currency('USD', 2, 2, '$'); $desiredAmountAsUsd = new Money($baseCurrency); $desiredAmountAsUsd->setAmountFloat(1234.56); $tradeCurrency = new Currency('BTC', 8, 8, 'B⃦'); $expectedAmountAsBtc = new Money($tradeCurrency); $expectedAmountAsBtc->setAmountFloat(4.93); $calculatedAmountAsBtc = $ask->convert($desiredAmountAsUsd); $this->assertInstanceOf('\\Matmar10\\Money\\Entity\\Money', $calculatedAmountAsBtc); $this->assertEquals($expectedAmountAsBtc, $calculatedAmountAsBtc); $bidCollection = $result->get('bid'); $this->assertInstanceOf('\\Matmar10\\Money\\CurrencyExchange\\Entity\\MarketDepthCollectionInterface', $bidCollection); $bid = current($bidCollection->getBids()); $this->assertInstanceOf('\\Matmar10\\Money\\CurrencyExchange\\Entity\\MarketDepthPrice', $bid); $this->assertInstanceOf('\\Matmar10\\Money\\Entity\\Currency', $bid->getFromCurrency()); $this->assertInstanceOf('\\Matmar10\\Money\\Entity\\Currency', $bid->getToCurrency()); $this->assertEquals($expectedCurrentBidMultiplier, $bid->getMultiplier()); $this->assertInstanceOf('\\Matmar10\\Money\\Entity\\Money', $bid->getDepth()); // test scenario when you want to buy $1234.56 USD worth of BTC $tradeCurrency = new Currency('BTC', 8, 8, 'B⃦'); $baseCurrency = new Currency('USD', 2, 2, '$'); $desiredSellAmountAsBtc = new Money($tradeCurrency); $desiredSellAmountAsBtc->setAmountFloat(1234.56); $expectedAmountAsUsd = new Money($baseCurrency); $expectedAmountAsUsd->setAmountFloat(302467.2); $calculatedAmountAsUsd = $bid->convert($desiredSellAmountAsBtc); $this->assertInstanceOf('\\Matmar10\\Money\\Entity\\Money', $calculatedAmountAsBtc); $this->assertEquals($expectedAmountAsUsd, $calculatedAmountAsUsd); }
/** * {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 testEasyCreateMoneyByNULL() { $eur = new Currency('EUR', 2, 2, '€'); $money = new Money($eur, null); $this->assertEquals(0, $money->getAmountInteger()); $this->assertEquals(0.0, $money->getAmountFloat()); $this->assertEquals('0.00', $money->getAmountDisplay()); }
public static function assertCurrencyCode(Money $money, $code) { if ($code !== $money->getCurrency()->getCurrencyCode()) { throw new InvalidArgumentException(sprintf("Unsupported currency '%s' provided", $money->getCurrency()->getCurrencyCode())); } }
$command = $client->getCommand('getTicker'); $response = $client->execute($command); echo "\n"; echo "Market summary:\n"; echo "------------------\n"; echo " BUY at: " . money_format($usdFormat, $response->get('bid')->getMultiplier()) . "\n"; echo "SELL at: " . money_format($usdFormat, $response->get('ask')->getMultiplier()) . "\n"; echo "\n"; if (false === array_key_exists(1, $argv)) { exit(0); } echo sprintf("Showing calculations for input amount '%s'\n", $argv[1]); echo "\n"; echo "Estimated proceeds:\n"; echo "--------------------\n"; // see how much we'd get for selling amount specified as BTC $sellBtc = new Money($response->get('bid')->getFromCurrency()); $sellBtc->setAmountFloat($argv[1]); // convert to USD based on the current going SELL rate $anticipatedProceeds = $response->get('bid')->convert($sellBtc); echo $sellBtc->getAmountFloat() . ' BTC ~ ' . money_format($usdFormat, $anticipatedProceeds->getAmountFloat()) . "\n"; echo "\n"; echo "Estimated price:\n"; echo "--------------------\n"; // see how much we'd need to pay to buy amount of BTC specified for selling amount specified as BTC $buyBtc = new Money($response->get('ask')->getFromCurrency()); $buyBtc->setAmountFloat($argv[1]); // convert to USD based on the current going SELL rate $anticipatedPrice = $response->get('ask')->convert($buyBtc); echo $buyBtc->getAmountFloat() . ' BTC ~ ' . money_format($usdFormat, $anticipatedPrice->getAmountFloat()) . "\n"; echo "\n";
public function allocate(array $ratios, $roundToPrecision = self::ROUND_TO_DEFAULT) { $total = array_sum($ratios); if (!count($ratios) || !$total) { throw new InvalidArgumentException('Invalid ratios specified: at least one ore more positive ratios must be provided.'); } if (is_integer($roundToPrecision)) { $precision = $roundToPrecision; } else { $precision = self::ROUND_TO_DEFAULT === $roundToPrecision ? $this->currency->getPrecision() : $this->currency->getDisplayPrecision(); } $currency = clone $this->currency; $currency->setPrecision($precision); $currency->setDisplayPrecision($this->currency->getDisplayPrecision()); $amount = new Money($currency); $amount->setAmountFloat($this->getAmountFloat()); $remainder = clone $amount; $results = array(); $increment = $amount->getScale() / pow(10, $currency->getPrecision()); foreach ($ratios as $ratio) { if ($ratio < 0) { throw new InvalidArgumentException("Invalid share ratio '" . $ratio . "' supplied: ratios may not be negative amounts."); } $share = $amount->multiply($ratio)->divide($total); $results[] = $share; $remainder = $remainder->subtract($share); } for ($i = 0; $remainder->isPositive(); $i++) { $amountInteger = $results[$i]->getAmountInteger(); $results[$i]->setAmountInteger($amountInteger + $increment); $increment = $amount->getScale() / pow(10, $amount->currency->getPrecision()); $remainderAmountInteger = $remainder->getAmountInteger(); $remainder->setAmountInteger($remainderAmountInteger - $increment); } $convertedResults = array(); foreach ($results as $result) { /** * @var $result Money */ $converted = new Money($this->currency); $converted->setAmountFloat($result->getAmountFloat()); $convertedResults[] = $converted; } return $convertedResults; }
/** * @dataProvider provideTestPlaceTradeOrderData */ public function testPlaceTradeOrder($type, $amount, $price, $response, $expectedTradeOrderId) { $this->plugin->addResponse($response); $command = $this->client->getCommand('placeTradeOrder'); $btc = new Currency('BTC', 8, 8); $amountBtc = new Money($btc); $amountBtc->setAmountFloat($amount); $usd = new Currency('USD', 2, 2); $priceUsd = new Money($usd); $priceUsd->setAmountFloat($price); $command->set('type', $type); $command->set('amount', $amountBtc); $command->set('price', $priceUsd); $result = $this->client->execute($command); $this->assertEquals($expectedTradeOrderId, $result->get('id')); }