Exemple #1
0
        public virtual void Append(IQuoteCapture q)
        {
            if (q == null || q.Count <= 0 || this.Symbol != q.Symbol)
            {
                return;
            }

            var sindex = q.Count - 1;

            while (sindex >= 0 && q.Time[sindex] > this.LastTime)
            {
                --sindex;
            }

            if (sindex == -1)
            {
                this.Time.AddRange(q.Time);
                this.Price.AddRange(q.Price);
                this.Volume.AddRange(q.Volume);
            }
            else if (sindex < q.Count - 1)
            {
                ++sindex;
                this.Time.AddRange(q.Time.GetRange(sindex, q.Count - sindex));
                this.Price.AddRange(q.Price.GetRange(sindex, q.Count - sindex));
                this.Volume.AddRange(q.Volume.GetRange(sindex, q.Count - sindex));
            }
        }
Exemple #2
0
 private void Create(IQuoteCapture q)
 {
     if (q != null)
     {
         this.Create(q.Symbol, q.PipFactor, q.Time, q.Price, q.Volume);
     }
 }
Exemple #3
0
        static public IQuoteCapture Uncompress(IQuoteCapture qc)
        {
            if (qc == null)
            {
                throw new ArgumentNullException();
            }

            IQuoteCapture result = new QuoteCapture(qc.Symbol);

            if (qc.Count == 0)
            {
                return(result);
            }

            //qc中至少有1个数据
            bool isSegment = false;

            result.Add(qc.FirstTime, qc.Price[0]);

            //true则认为此时在处理分段 每处理完一次分段时置为false
            isSegment = true;
            for (var i = 1; i < qc.Count; ++i)
            {//
             //通常NO_USED_PRICE不会被使用

                if (qc.Price[i] == NO_USED_PRICE && isSegment)
                {//这是重复数据 要展开
                    var endTime    = qc.Time[i];
                    var endPrice   = qc.Price[i];
                    var startTime  = qc.Time[i - 1];
                    var startPrice = qc.Price[i - 1];

                    var j = startTime + MIN_INTERVAL;
                    //用startPrice生成start到end之间的数据
                    while (j < endTime)
                    {
                        result.Add(j, startPrice);
                        j += MIN_INTERVAL;
                    }
                    //生成end数据(endtime 大则代表是正确的分段 小则意味不正确的分段 插入原来的数据
                    result.Add(endTime, endTime > startTime ? startPrice : endPrice);
                    //分段解压缩结束
                    isSegment = false;
                }
                else//非重复数据或者数据起始点 直接插入
                {
                    result.Add(qc.Time[i], qc.Price[i]);
                    isSegment = true;
                }
            }
            return(result);
        }
Exemple #4
0
        static public IQuoteCapture Compress(IQuoteCapture qc)
        {
            if (qc == null)
            {
                throw new ArgumentNullException();
            }

            IQuoteCapture result = new QuoteCapture(qc.Symbol);

            if (qc.Count == 0)
            {
                return(result);
            }


            //此时qc有值 先插入一个数据
            result.Add(qc.Time[0], qc.Price[0]);
            bool tail = false;

            for (int i = 1; i < qc.Count; i++)
            {
                var time  = qc.Time[i];
                var price = qc.Price[i];

                var lastTime  = qc.Time[i - 1];
                var lastPrice = qc.Price[i - 1];

                if (time - lastTime == MIN_INTERVAL && price == lastPrice)
                {//价格重复且时间递增那么该数据可以压缩
                    tail = true;
                }
                else
                {//本次数据不能被压缩那么把该数据当作分段新的起始点
                    //添加上一个分段的末尾如果分段数据只有1个那么不需要添加结尾
                    //[start: price, start+1:price,..., end:price]=>[start : price, end:-1]
                    if (tail)
                    {
                        result.Add(lastTime, NO_USED_PRICE);
                    }
                    //分段新的起始点
                    result.Add(time, price);
                    tail = false;
                }
            }
            //可能qc末尾是个分段但是此时还没能添加分段尾
            if (tail)
            {
                result.Add(qc.Time.Last(), NO_USED_PRICE);
            }

            return(result);
        }
Exemple #5
0
        private int AddItemByQuoteCapture(IQuoteCapture q, int sindex, int eindex)
        {
            var len        = eindex - sindex + 1;
            var price      = q.Price.GetRange(sindex, len);
            var volumnList = q.Volume.GetRange(sindex, len);
            var time       = q.Time[sindex] / this.Interval * this.Interval;
            var open       = this.Count > 0 ? this.Close.Last() : q.Price[sindex];
            var close      = q.Price[eindex];
            var high       = price.Max();
            var low        = price.Min();
            var volumn     = volumnList.Sum();

            return(this.AddUpdate(time, open, high, low, close, volumn));  //add the data
        }
 public void AddQuoteCapture(IQuoteCapture qc, bool isTriggerEvent)
 {
     lock (this)
     {
         var interval = this.Intervals[0];
         var quoteId  = this.CreateQuote(qc.Symbol, interval);
         var num      = Quotes[quoteId].Append(qc, false);
         if (num >= 0)
         {
             var d = this.AddToOtherQuotes(Quotes[quoteId], 1, isTriggerEvent);
             //QuoteStore_OnDataAddedOrUpdated(this, this.Quotes[quoteId], num);
             //foreach (var id in d.Keys) QuoteStore_OnDataAddedOrUpdated(this, this.Quotes[id], d[id]);
         }
     }
 }
Exemple #7
0
        public void TestAppend()
        {
            IQuoteCapture qc = null;

            // 测试null
            _quoteCapture.Append(qc);
            Assert.AreEqual(0, _quoteCapture.Count);

            // 测试空
            qc = new QuoteCapture();
            _quoteCapture.Append(qc);
            Assert.AreEqual(0, _quoteCapture.Count);

            // 测试不同的symbol
            qc = new QuoteCapture("symbol1");
            qc.Add(10, 20, 30);
            _quoteCapture.Append(qc);
            Assert.AreEqual(0, _quoteCapture.Count);

            // 测试_quoteCapter.LastTime < qc.LastTime
            qc = new QuoteCapture("symbol0");
            _quoteCapture.Add(10, 20, 15);
            qc.Add(5, 20);
            _quoteCapture.Append(qc);
            Assert.AreEqual(1, _quoteCapture.Count);
            Assert.AreEqual(10, _quoteCapture.Time[0]);
            Assert.AreEqual(20, _quoteCapture.Price[0]);
            Assert.AreEqual(15, _quoteCapture.Volume[0]);

            // 测试不添加小于LastTime的数据
            qc.Add(10, 18, 18);
            qc.Add(20, 30, 17);
            _quoteCapture.Append(qc);
            Assert.AreEqual(2, _quoteCapture.Count);
            Assert.AreEqual(10, _quoteCapture.Time[0]);
            Assert.AreEqual(20, _quoteCapture.Time[1]);
            Assert.AreEqual(20, _quoteCapture.Price[0]);
            Assert.AreEqual(30, _quoteCapture.Price[1]);
            Assert.AreEqual(15, _quoteCapture.Volume[0]);
            Assert.AreEqual(17, _quoteCapture.Volume[1]);
        }
Exemple #8
0
        public void TestExtract_LongLong()
        {
            _quoteCapture.Add(100, 10, 21);
            _quoteCapture.Add(200, 20, 22);
            _quoteCapture.Add(300, 30, 23);
            _quoteCapture.Add(400, 40, 24);
            _quoteCapture.Add(500, 50, 26);

            IQuoteCapture qc = _quoteCapture.Extract(150L, 350L);

            Assert.AreEqual(2, qc.Count);
            Assert.AreEqual(200, qc.Time[0]);
            Assert.AreEqual(300, qc.Time[1]);
            Assert.AreEqual(20, qc.Price[0]);
            Assert.AreEqual(30, qc.Price[1]);
            Assert.AreEqual(30, qc.Price[1]);
            Assert.AreEqual(22, qc.Volume[0]);
            Assert.AreEqual(23, qc.Volume[1]);
            qc = _quoteCapture.Extract(10L, 110L);
            Assert.AreEqual(1, qc.Count);
            Assert.AreEqual(100, qc.Time[0]);

            qc = _quoteCapture.Extract(10L, 20L);
            Assert.AreEqual(0, qc.Count);

            qc = _quoteCapture.Extract(600L, 900L);
            Assert.AreEqual(0, qc.Count);

            qc = _quoteCapture.Extract(0L, 900L);
            Assert.AreEqual(5, qc.Count);

            _quoteCapture.Clear();
            _quoteCapture.Add(100, 10);

            qc = _quoteCapture.Extract(80L, 110L);
            Assert.AreEqual(1, qc.Count);
        }
Exemple #9
0
        public void TestExtract_IntInt()
        {
            IQuoteCapture qc = null;

            // 测试sindex > eindex
            TestHelper.AssertException(() => _quoteCapture.Extract(1, 0), typeof(ArgumentException));

            // 测试sindex < 0
            TestHelper.AssertException(() => _quoteCapture.Extract(-1, 0), typeof(ArgumentException));

            // 测试eindex < 0
            TestHelper.AssertException(() => _quoteCapture.Extract(0, -1), typeof(ArgumentException));

            // 测试eindex > _quoteCapture.Count - 1;
            _quoteCapture.Add(10, 12);
            TestHelper.AssertException(() => _quoteCapture.Extract(0, 5), typeof(ArgumentException));

            _quoteCapture = new QuoteCapture("xyz");
            _quoteCapture.Add(100, 10, 23);
            _quoteCapture.Add(200, 20, 24);
            _quoteCapture.Add(300, 30, 26);
            _quoteCapture.Add(400, 40, 27);
            _quoteCapture.Add(500, 50, 28);

            qc = _quoteCapture.Extract(1, 3);
            Assert.AreEqual(3, qc.Count);
            Assert.AreEqual(200, qc.Time[0]);
            Assert.AreEqual(300, qc.Time[1]);
            Assert.AreEqual(400, qc.Time[2]);
            Assert.AreEqual(20, qc.Price[0]);
            Assert.AreEqual(30, qc.Price[1]);
            Assert.AreEqual(40, qc.Price[2]);
            Assert.AreEqual(24, qc.Volume[0]);
            Assert.AreEqual(26, qc.Volume[1]);
            Assert.AreEqual(27, qc.Volume[2]);
        }
Exemple #10
0
 public void Assign(IQuoteCapture q)
 {
     this.Create(q);
 }
Exemple #11
0
 public QuoteCapture(IQuoteCapture q)
 {
     Create(q);
 }
Exemple #12
0
 private async void _qcStore_OnQuoteCaptureDataAdded(object sender, string exchange, IQuoteCapture quote, int numAppended)
 {
     try
     {
         var symbol = quote.Symbol;
         if (_symbolsInitialized.Contains(symbol))
         {
             _qbStore.AddQuoteCapture(quote, true);
         }
         else   //initialize IQuoteBasicBase
         {
             this.InitQuoteBasic(symbol);
         }
     }
     catch (Exception ex)
     {
         OnExceptionOccured?.Invoke(this, this.Exchange, ex);
     }
 }
Exemple #13
0
        public int Append(IQuoteCapture q, bool isTriggerDataUpdated = false)
        {
            if (q == null || q.Count <= 0 || q.LastTime <= this.LastTime || this.Symbol != q.Symbol)
            {
                return(0);
            }

            //search backward for the quotes. the found time should be >= lastTime
            int indexStartSearch = -1;

            for (int i = q.Count - 1; i >= 0; i--)
            {
                if (q.Time[i] < this.LastTime)               //for basic quote we include price at previous interval for calculation
                {
                    break;
                }

                indexStartSearch = i;
            }
            if (indexStartSearch == -1)
            {
                return(0);
            }

            ////////////////////////////////////////////////////////////////////////////
            var isDataChanged   = false;
            var numAddedElement = 0;

            int sindex  = indexStartSearch;                                               // interval区间的开始索引
            var eindex  = -1;
            var endTime = q.Time[sindex] / this.Interval * this.Interval + this.Interval; //use the first time as the data bar time

            for (int i = indexStartSearch; i <= q.Count - 1; i++)
            {
                if (q.Time[i] >= endTime)
                {
                    eindex = i - 1;        // interval区间的结束索引
                    var num = this.AddItemByQuoteCapture(q, sindex, eindex);
                    if (num >= 0)
                    {
                        numAddedElement += num;
                        isDataChanged    = true;
                    }
                    sindex  = i;
                    endTime = q.Time[sindex] / this.Interval * this.Interval + this.Interval;
                }
            }

            //add last element
            if (sindex > eindex)
            {
                var num = this.AddItemByQuoteCapture(q, sindex, q.Count - 1);
                if (num >= 0)
                {
                    numAddedElement += num;
                    isDataChanged    = true;
                }
            }

            if (isTriggerDataUpdated && isDataChanged)
            {
                OnDataAddedOrUpdated?.Invoke(this, this, numAddedElement);
            }

            return(isDataChanged ? numAddedElement : -1);  //-1 means nothing changed, 0 means updated, >=1 means added
        }