Exemple #1
0
        /// <summary>Add a batch of candles</summary>
        public void Add(ETimeFrame tf, PriceCandles candles)
        {
            // Insert the candles into the database
            using (var t = m_db.NewTransaction())
                using (var query = new Sqlite.Query(m_db, SqlExpr.InsertCandle(tf)))
                {
                    foreach (var candle in candles.AllCandles.Select(x => new Candle(x)))
                    {
                        query.Reset();
                        query.BindParms(1, SqlExpr.InsertCandleParams(candle));
                        query.Run();
                    }
                    t.Commit();
                }

            // Don't bother maintaining the cache, just invalidate it
            InvalidateCachedData();

            // Record the last time data was received
            LastUpdatedUTC = Model.UtcNow;

            // Notify data added/changed
            DataChanged.Raise(this, new DataEventArgs(this, tf, null, false));
        }
Exemple #2
0
        /// <summary>Add a candle value to the data</summary>
        public void Add(ETimeFrame tf, PriceCandle price_candle)
        {
            // Sanity check
            var candle = new Candle(price_candle);

            Debug.Assert(candle.Valid());
            Debug.Assert(candle.Timestamp != 0);
            Debug.Assert(tf != ETimeFrame.None);

            // If this candle is the newest we've seen, then a new candle has started.
            // Get the latest candle before inserting 'candle' into the database
            var new_candle = tf == TimeFrame && candle.Timestamp > Latest.Timestamp;

            // Insert the candle into the database if the sim isn't running.
            // The sim draws it's data from the database, so there's no point in writing
            // the same data back in. Plus it might in the future do things to emulate sub-candle
            // updates, which I don't want to overwrite the actual data.
            if (!Model.SimActive)
            {
                m_db.Execute(SqlExpr.InsertCandle(tf), 1, SqlExpr.InsertCandleParams(candle));
            }

            // If the candle is for the current time frame and within the
            // cached data range, update the cache to avoid invalidating it.
            if (tf == TimeFrame)
            {
                // Within the currently cached data?
                // Note: this is false if 'candle' is the start of a new candle
                if (!new_candle)
                {
                    // Find the index in the cache for 'candle'. If not an existing cache item, then just reset the cache
                    var cache_idx = m_cache.BinarySearch(x => x.Timestamp.CompareTo(candle.Timestamp));
                    if (cache_idx >= 0)
                    {
                        m_cache[cache_idx].Update(candle);
                    }
                    else
                    {
                        InvalidateCachedData();
                    }
                }
                // If the cached range ends at the latest candle (excluding the new candle)
                // then we can preserve the cache and append the new candle to the cache data
                else if (m_index_range.Endi == Count)
                {
                    // If adding 'candle' will make the cache too big, just flush
                    if (m_cache.Count > MaxCacheSize)
                    {
                        InvalidateCachedData();
                    }

                    // Otherwise, append the new candle to the cache
                    else
                    {
                        m_cache.Add(candle);
                        m_index_range.End++;
                        m_impl_count = null;
                        m_impl_total = null;
                        m_latest     = null;
                    }
                }
                // Otherwise the candle is not within the cache, just invalidate
                else
                {
                    InvalidateCachedData();
                }
            }

            // Record the last time data was received
            LastUpdatedUTC = Model.UtcNow;

            // Notify data added/changed
            OnDataChanged(new DataEventArgs(this, tf, candle, new_candle));
        }