public void AddPendingItem(SourceQuotation quotation) { lock (this._WaitQueue) { this._WaitQueue.Enqueue(quotation); } }
public AbnormalInstrument(SourceQuotation firstAbnormalItem, AbnormalQuotationManager abnormalQuotationManager, PriceRangeCheckRule priceRangeCheckRule) { this._InstrumentId = firstAbnormalItem.InstrumentId; this._TimeoutCount = 0; this._WaitQueue = new Queue<SourceQuotation>(); this._WaitQueue.Enqueue(firstAbnormalItem); this._AbnormalQuotationManager = abnormalQuotationManager; this._PriceRangeCheckRule = priceRangeCheckRule; }
public bool AppendPendingItem(SourceQuotation quotation) { lock (this._WaitQueue) { if (this._WaitQueue.Count > 0) { this._WaitQueue.Enqueue(quotation); return true; } } return false; }
public void SetAbnormalInfo(SourceQuotation quotation) { GeneralQuotation last; quotation.IsAbnormal = false; if (this._LastQuotationManager.LastAccepted.TryGetLastQuotation(quotation.InstrumentId, out last)) { PriceRangeCheckRule rule = this._PriceRangeCheckRules[quotation.InstrumentId]; double diff = 0; double oldPrice = 0; switch (rule.OutOfRangeType) { case OutOfRangeType.Ask: diff = Math.Abs(quotation.Ask - last.Ask); oldPrice = last.Ask; break; case OutOfRangeType.Bid: diff = Math.Abs(quotation.Bid - last.Bid); oldPrice = last.Bid; break; default: Logger.AddEvent(TraceEventType.Error, "AbnormalQuotationManager.IsNormalPrice unknown OutOfRangeType:{0}", rule.OutOfRangeType.ToString()); break; } // diff to diffPoints int decimalPlace = MainService.QuotationManager.ConfigMetadata.Instruments[quotation.PrimitiveQuotation.InstrumentId].DecimalPlace; int diffPoints = (int)(Math.Round(diff * Math.Pow(10, decimalPlace), 0)); quotation.IsAbnormal = diffPoints > rule.ValidVariation; if (quotation.IsAbnormal) { quotation.DiffPoints = diffPoints; quotation.OldPrice = oldPrice; quotation.OutOfRangeType = rule.OutOfRangeType; quotation.WaitSeconds = rule.OutOfRangeWaitTime; quotation.ConfirmId = this.GetNextConfirmId(); } } }
public void Set(SourceQuotation quotation) { Dictionary<int, SourceQuotation> sourceQuotations; if (!this._LastReceivedQuotations.TryGetValue(quotation.SourceId, out sourceQuotations)) { sourceQuotations = new Dictionary<int, SourceQuotation>(); this._LastReceivedQuotations.Add(quotation.SourceId, sourceQuotations); } sourceQuotations[quotation.InstrumentId] = quotation; }
public bool SetQuotation(SourceQuotation quotation) { bool isNormalAndNotWaiting = false; AbnormalInstrument abnormalInstrument; bool hasAbnormalInstrument = this._AbnormalInstruments.TryGetValue(quotation.InstrumentId, out abnormalInstrument); if (hasAbnormalInstrument) { if (abnormalInstrument.AppendPendingItem(quotation)) { return false; } } this.SetAbnormalInfo(quotation); if (quotation.IsAbnormal) { if (!this._PriceRangeCheckRules[quotation.InstrumentId].DiscardOutOfRangePrice) { MainService.ExchangeManager.SwitchPriceEnableState(quotation.InstrumentId, false); if (hasAbnormalInstrument) { abnormalInstrument.AddPendingItem(quotation); } else { abnormalInstrument = new AbnormalInstrument(quotation, this, this._PriceRangeCheckRules[quotation.InstrumentId]); this._AbnormalInstruments.Add(quotation.InstrumentId, abnormalInstrument); } this.StartConfirm(quotation); } } else { isNormalAndNotWaiting = true; } return isNormalAndNotWaiting; }
public void StartConfirm(SourceQuotation quotation) { string format = "F" + MainService.QuotationManager.ConfigMetadata.Instruments[quotation.InstrumentId].DecimalPlace; AbnormalQuotationMessage message = new AbnormalQuotationMessage(); message.ConfirmId = quotation.ConfirmId; message.InstrumentId = quotation.InstrumentId; message.InstrumentCode = quotation.InstrumentCode; message.NewPrice = quotation.OutOfRangeType == OutOfRangeType.Ask ? quotation.Ask.ToString(format) : quotation.Bid.ToString(format); message.OldPrice = quotation.OldPrice; message.OutOfRangeType = quotation.OutOfRangeType; message.DiffPoints = quotation.DiffPoints; message.WaitSeconds = quotation.WaitSeconds; MainService.ClientManager.Dispatch(message); quotation.WaitEndTime = DateTime.Now.AddSeconds(quotation.WaitSeconds + 1); // Add one sencond at server side. this.ChangeWaitTime(quotation.WaitEndTime); }
public void ProcessQuotation(PrimitiveQuotation primitiveQuotation) { bool inverted; if (this._ConfigMetadata.EnsureIsKnownQuotation(primitiveQuotation, out inverted)) { double ask, bid; if (this._LastQuotationManager.LastReceived.Fix(primitiveQuotation, out ask, out bid)) { if (this._LastQuotationManager.LastReceived.IsNotSame(primitiveQuotation)) { MainService.ClientManager.Dispatch(new PrimitiveQuotationMessage() { Quotation = primitiveQuotation }); string instrumentCode = this._ConfigMetadata.Instruments[primitiveQuotation.InstrumentId].Code; SourceQuotation quotation = new SourceQuotation(primitiveQuotation, ask, bid, instrumentCode, inverted); if (this._SourceController.QuotationArrived(quotation)) { // quotation come from Active Source and adjusted if (this._AbnormalQuotationManager.SetQuotation(quotation)) { // quotation is normal this.ProcessNormalQuotation(quotation); } } this._LastQuotationManager.LastReceived.Set(quotation); } } } else { Logger.AddEvent(TraceEventType.Warning, "Discarded price:[ask={0}, bid={1}] got for {2} from {3}", primitiveQuotation.Ask, primitiveQuotation.Bid, primitiveQuotation.Symbol, primitiveQuotation.SourceName); } }
public void ProcessNormalQuotation(SourceQuotation quotation) { List<GeneralQuotation> quotations = new List<GeneralQuotation>(); this._DerivativeController.Derive(quotation.Quotation, quotations); for (int i = 0; i < quotations.Count; i++) { quotations[i].OriginCode = this._ConfigMetadata.Instruments[quotations[i].InstrumentId].Code; } quotations.Add(quotation.Quotation); // adjust quotation according to adjuestment on instrument foreach (GeneralQuotation gq in quotations) { Instrument instrument = this._ConfigMetadata.Instruments[gq.InstrumentId]; gq.Ask += CommonHelper.GetAdjustValue(instrument.AdjustPoints, instrument.DecimalPlace); gq.Bid += CommonHelper.GetAdjustValue(instrument.AdjustPoints, instrument.DecimalPlace); } this._LastQuotationManager.LastAccepted.Accept(quotations); MainService.ExchangeManager.AddQuotations(quotations); MainService.ClientManager.Dispatch(new QuotationsMessage() { Quotations = quotations }); }
//public TimeSpan ActiveSourceTimeoutSpan //{ // get // { // return this._ActiveSource.TimeoutSpan; // } //} //public DateTime ActiveSourceTimeoutTime //{ // get // { // return this._ActiveSource.TimeoutTime; // } //} public bool QuotationArrived(SourceQuotation quotation) { if (this._Instrument.IsSwitchUseAgio.Value) { this._AgioCalculator.QuotationArrived(quotation); } if (quotation.SourceId == this._ActiveSource.Id) { this._ActiveSource.QuotationArrived(); } else { if (this._Relations[quotation.SourceId].IsDefault || !this._Relations[this._ActiveSource.Id].IsDefault && this._Relations[quotation.SourceId].Priority > this._Relations[this._ActiveSource.Id].Priority) { // 如果价格来自优先级高的源,则切换到该源; this.SwitchActiveSource(quotation.SourceId); } else if (this._ActiveSource.IsTimeout) { // 如果当前源Timeout,来一个价格就向该源切换; this.SwitchActiveSource(quotation.SourceId); } } if (quotation.SourceId == this._ActiveSource.Id) { // calculate price and adjust if (this._Instrument.UseWeightedPrice.Value) { WeightedPriceRule rule = MainService.QuotationManager.ConfigMetadata.WeightedPriceRules[this._Instrument.Id]; quotation.Ask = (quotation.Ask * rule.AskAskWeight + quotation.Bid * rule.BidAskWeight + (quotation.Last.HasValue ? quotation.Last.Value * rule.AskLastWeight : 0) + (quotation.Ask + quotation.Bid) / 2 * rule.AskAverageWeight + (double)rule.AskAdjust) * (double)rule.Multiplier; quotation.Bid = (quotation.Ask * rule.BidAskWeight + quotation.Bid * rule.BidBidWeight + (quotation.Last.HasValue ? quotation.Last.Value * rule.BidLastWeight : 0) + (quotation.Ask + quotation.Bid) / 2 * rule.BidAverageWeight + (double)rule.BidAdjust) * (double)rule.Multiplier; } quotation.Ask += this._Agio + CommonHelper.GetAdjustValue(this._Relations[quotation.SourceId].AdjustPoints, this._Instrument.DecimalPlace); quotation.Bid += this._Agio + CommonHelper.GetAdjustValue(this._Relations[quotation.SourceId].AdjustPoints, this._Instrument.DecimalPlace); this._LastActiveTime = DateTime.Now; if (!this.IsActive) { MainService.ExchangeManager.SwitchPriceEnableState(this._Instrument.Id, true); this.IsActive = true; } return true; } else { return false; } }
public bool QuotationArrived(SourceQuotation quotation) { // do not lock _SourceInstruments here for performance, so we should judge if the instrument existed in _SourceInstruments. because of maybe in adding Instrument progress. if (this._SourceInstruments.ContainsKey(quotation.InstrumentId)) { return this._SourceInstruments[quotation.InstrumentId].QuotationArrived(quotation); } else { return false; } }
public void QuotationArrived(SourceQuotation quotation) { // remove expired sample data DateTime cutOffTime = DateTime.Now - this._MonitorTimeSpan; Queue<SourceQuotation> sampleQueue = this._QuotationSamples[quotation.SourceId]; while (sampleQueue.Count > 0) { SourceQuotation q = sampleQueue.Peek(); if (q.Timestamp < cutOffTime) { sampleQueue.Dequeue(); } else { break; } } // add new sample sampleQueue.Enqueue(quotation); // calculate average price lock (this._AveragePrices) { if (sampleQueue.Count > this._LeastTicks) { this._AveragePrices[quotation.SourceId] = sampleQueue.Average(q => q.Bid); } else { this._AveragePrices[quotation.SourceId] = null; } } }