public void Caculate(CurrencyRate currencyRate, Guid?accountId = null) { try { if (this.Setting.SystemParameter.DefaultQuotePolicyId != null && currencyRate.DependingInstrumentId != null) { var instrumentId = currencyRate.DependingInstrumentId.Value; var instrument = Market.MarketManager.Default[currencyRate.DependingInstrumentId.Value]; if (instrument == null) { return; } var defaultOverridedQuotation = instrument.GetQuotation(_quotePolicyProvider); if (defaultOverridedQuotation == null || defaultOverridedQuotation.Ask == null || defaultOverridedQuotation.Bid == null) { return; //maybe closed } string key = string.Format("{0}-{1}", currencyRate.SourceCurrency.Id, currencyRate.TargetCurrency.Id); DateTime lastTime; if (!this.TryGetLastUpdateTime(key, out lastTime) || defaultOverridedQuotation.Timestamp > lastTime) { decimal price = ((decimal)defaultOverridedQuotation.Ask + (decimal)defaultOverridedQuotation.Bid) / 2; int decimals = 8; if (!currencyRate.Inverted) { var settingInstrument = this.Setting.GetInstrument(instrumentId); if (settingInstrument == null) { return; } decimals = (int)Math.Log10(settingInstrument.Denominator); if (settingInstrument.Denominator != Math.Pow(10, decimals)) { decimals = 8; } } Logger.InfoFormat("calcualte currency rate, accountId = {0}", accountId); double rate = Math.Round((double)(currencyRate.Inverted ? 1 / price : price), decimals, MidpointRounding.AwayFromZero); if (rate != (double)currencyRate.RateIn || rate != (double)currencyRate.RateOut) { if (this.SaveCurrencyRate(currencyRate, rate)) { currencyRate.Update((decimal)rate, (decimal)rate); this.Boardcast(currencyRate, rate, accountId); } lock (_mutex) { this._lastCaculateTimestamps[key] = defaultOverridedQuotation.Timestamp; } Logger.InfoFormat("recalcualte currency rate success, accountId = {0}", accountId); } } } } catch (Exception exception) { Logger.Error("TransactionServer.CurrencyRateCaculaotr.Caculate", exception); } }