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()); }