/** * @param CurrencyPair $currencyPair * @return Rate * @throws Exception */ public function fetchRate(CurrencyPair $currencyPair) { $providers = [$this->mainProvider => CurrencyRateProvider::getByName($this->mainProvider), $this->secondProvider => CurrencyRateProvider::getByName($this->secondProvider)]; if (count($providers) !== 2) { throw new Exception('One of providers not found'); } $rates = []; /** @var CurrencyRateProvider $provider */ foreach ($providers as $name => $provider) { if (null === $provider) { throw new Exception("Provider \"{$name}\" not found!"); } try { $providerHandler = $provider->getImplementationInstance($this->httpAdapter); if ($providerHandler !== null) { $swap = new Swap($providerHandler); $rate = $swap->quote($currencyPair->getBaseCurrency() . '/' . $currencyPair->getQuoteCurrency())->getValue(); $rates[] = floatval($rate); } else { throw new Exception('Provider "' . $provider->name . '" not found'); } } catch (\Exception $e) { throw new Exception('One or more currency providers did not return result'); } } $min = min($rates); $max = max($rates); return new Rate($max - $min >= $max * $this->criticalDifference / 100 ? $max : $rates[0], new \DateTime()); }
/** * @throws \Exception */ public function actionUpdate() { $mainCurrency = Currency::getMainCurrency(); if ($mainCurrency === null) { throw new \Exception("Main currency is not set"); } $currencies = Currency::getUpdateable(); $httpAdapter = new CurlHttpAdapter(); /** @var Currency $currency */ foreach ($currencies as $currency) { /** @var CurrencyRateProvider $providerModel */ $providerModel = $currency->rateProvider; if (null !== $providerModel) { try { $provider = $providerModel->getImplementationInstance($httpAdapter); if (null !== $provider) { $swap = new Swap($provider); $rate = $swap->quote($currency->iso_code . '/' . $mainCurrency->iso_code)->getValue(); $currency->convert_rate = floatval($rate); if ($currency->additional_rate > 0) { // additional rate is in % $currency->convert_rate *= 1 + $currency->additional_rate / 100; } if ($currency->additional_nominal !== 0) { $currency->convert_rate += $currency->additional_nominal; } $currency->save(); echo $currency->iso_code . '/' . $mainCurrency->iso_code . ': ' . $rate . " == " . $currency->convert_rate . "\n"; } } catch (\Exception $e) { echo "Error updating " . $currency->name . ': ' . $e->getMessage() . "\n\n"; } } } }
public function fetchRate(CurrencyPair $currencyPair) { $providerIds = [(int) $this->mainProvider, (int) $this->secondProvider]; /** @var CurrencyRateProvider[] $providers */ $providers = CurrencyRateProvider::find()->where(['id' => $providerIds])->orderBy(['FIELD (`id`, ' . implode(',', $providerIds) . ')' => ''])->all(); if (count($providers) !== 2) { throw new Exception('One of providers not found'); } $rates = []; foreach ($providers as $provider) { try { $providerHandler = $provider->getImplementationInstance($this->httpAdapter); if ($providerHandler !== null) { $swap = new Swap($providerHandler); $rate = $swap->quote($currencyPair->getBaseCurrency() . '/' . $currencyPair->getQuoteCurrency())->getValue(); $rates[] = floatval($rate); } else { throw new Exception('Provider "' . $provider->name . '" not found'); } } catch (\Exception $e) { throw new Exception('One or more currency providers did not return result'); } } $min = min($rates); $max = max($rates); return new Rate($max - $min >= $max * $this->criticalDifference / 100 ? $max : $rates[0], new \DateTime()); }
/** * {@inheritdoc} */ public function quote(Currency $baseCurrency, Currency $counterCurrency) { try { $rate = $this->swap->latest($baseCurrency->getCode() . '/' . $counterCurrency->getCode()); } catch (ExchangerException $e) { throw UnresolvableCurrencyPairException::createFromCurrencies($baseCurrency, $counterCurrency); } return new CurrencyPair($baseCurrency, $counterCurrency, $rate->getValue()); }
/** * @test */ public function it_caches_a_rate() { $pair = new CurrencyPair('EUR', 'USD'); $provider = $this->getMock('Swap\\ProviderInterface'); $cache = new DoctrineCache(new ArrayCache(), 3600); $provider->expects($this->once())->method('fetchRate')->with($pair)->will($this->returnValue(new Rate('1', new \DateTime()))); $swap = new Swap($provider, $cache); $rate1 = $swap->quote($pair); $rate2 = $swap->quote($pair); $rate3 = $swap->quote('EUR/USD'); $this->assertSame($rate1, $rate2); $this->assertSame($rate2, $rate3); }
public function fetchRate(CurrencyPair $currencyPair) { /** @var CurrencyRateProvider $provider */ $provider = CurrencyRateProvider::findOne($this->provider); if ($provider === null) { throw new Exception('Provider not found'); } try { $providerHandler = $provider->getImplementationInstance($this->httpAdapter); $swap = new Swap($providerHandler); $rate = $swap->quote($currencyPair->getBaseCurrency() . '/' . $currencyPair->getQuoteCurrency())->getValue(); if ($this->marginMultiplier !== null && $this->marginMultiplier > 1) { $rate *= $this->marginMultiplier; } if ($this->fixedMargin !== null && $this->fixedMargin > 0) { $rate += $this->fixedMargin; } } catch (\Exception $e) { throw new Exception('Calculating error'); } return new Rate($rate, new \DateTime()); }