Beispiel #1
0
        public void CouldWriteToStorage()
        {
            var repo = new SeriesStorage(SeriesStorage.GetDefaultConnectionString("../StorageTests.db"));
            var test = new SortedMap <DateTime, double>();

            for (int i = 0; i < 10; i++)
            {
                test.Add(DateTime.UtcNow.Date.AddSeconds(i), i);
            }
            test.Complete();
            foreach (var kvp in test.Map(x => (decimal)x))
            {
                Console.WriteLine($"{kvp.Key} - {kvp.Key.Kind} - {kvp.Value}");
            }

            var storageSeries = repo.GetPersistentOrderedMap <DateTime, decimal>("test_series_CouldWriteToStorage");
            var test2         = storageSeries.ToSortedMap();

            foreach (var kvp in test2)
            {
                Console.WriteLine($"{kvp.Key} - {kvp.Key.Kind} - {kvp.Value}");
            }
            storageSeries.Append(test.Map(x => (decimal)x), AppendOption.RequireEqualOverlap);
            storageSeries.Flush();
        }
Beispiel #2
0
		private void AsyncMergeTick() {
			bool bBusy = false;
			lock (__oLock) {
				bBusy = __bBusy;
				if (!bBusy) {
					__bBusy = true;
				}
			}

			if (!bBusy) {
				Task.Factory.StartNew(() => {
					while (__cQueue.Count > 0) {
						QuoteEvent cQuoteEvent = null;
						lock (__cQueue) {
							cQuoteEvent = __cQueue.Dequeue();
						}

						SeriesStorage cStorage = null;
						string sLSymbolId = cQuoteEvent.Quote.SymbolId.ToLower();
						lock (__cStorages) {
							__cStorages.TryGetValue(sLSymbolId, out cStorage);
						}

						if (cStorage != null) {
							cStorage.MergeTick(cQuoteEvent.Tick);
						}
					}

					lock (__oLock) {
						__bBusy = false;
					}
				});
			}
		}
Beispiel #3
0
		/// <summary>
		///   移除商品資訊(如果 GetSeries 不是使用 useCache 模式都需要移除)
		/// </summary>
		/// <param name="seriesSymbolDataRand">商品資訊類別</param>
		internal void RemoveSeries(SeriesSymbolDataRand seriesSymbolDataRand) {
			SeriesSymbolData cSeries = seriesSymbolDataRand.Source;

			SeriesStorage cStorage = null;
			string sLSymbolId = cSeries.DataRequest.Symbol.ToLower();
			lock (__cStorages) {
				__cStorages.TryGetValue(sLSymbolId, out cStorage);
			}

			if (cStorage != null) {
				if (cSeries.Id > 0x40000000) {  //Id 編號從 0x40000001 開始編號(如果低於表示使用時間週期總秒數當作 Hash, 使用時間週期總秒數都是 Cache 資料所以不能移除) 
					cStorage.Remove(cSeries.Id);
				}
			}
		}
Beispiel #4
0
        public void CouldCreateSeriesStorage()
        {
            var folder = Bootstrap.Bootstrapper.Instance.DataFolder;

            Console.WriteLine(folder);
            var storage = SeriesStorage.GetDefault("storage_test.db");

            storage.GetPersistentOrderedMap <int, int>("int_map");

            Assert.Throws(typeof(ArgumentException), () => {
                try {
                    var map = storage.GetPersistentOrderedMap <int, double>("int_map");
                } catch (Exception e) {
                    Console.WriteLine(e.Message);
                    throw;
                }
            });
        }
Beispiel #5
0
        private static void Main2(string[] args)
        {
            // from Ractor.Persistence
            var store = new SeriesStorage(SeriesStorage.GetDefaultConnectionString("TAQSample.db"));

            var aapl = store.GetPersistentOrderedMap <DateTime, TaqTrade>("aapl").Map(t => t.TradePrice / 10000.0);

            Console.WriteLine("Count: " + aapl.Count());
            Console.WriteLine("Open: " + aapl.First.Value);
            Console.WriteLine("High: " + aapl.Values.Max());
            Console.WriteLine("Low: " + aapl.Values.Min());
            Console.WriteLine("Close: " + aapl.Last.Value);
            Console.WriteLine("Average price: " + aapl.Values.Average());
            Console.WriteLine("Total volume: " + aapl.Values.Sum());
            //https://uk.finance.yahoo.com/q/hp?s=AAPL&b=5&a=07&c=2015&e=5&d=07&f=2015&g=d

            var msft   = store.GetPersistentOrderedMap <DateTime, TaqTrade>("msft").Map(t => t.TradePrice / 10000.0);;
            var spread = (aapl.Repeat() / msft.Repeat() - 1.0).ToSortedMap();

            Console.ReadLine();
        }
Beispiel #6
0
        public void CouldAddValuesByKey()
        {
            var repo   = new SeriesStorage(SeriesStorage.GetDefaultConnectionString("../StorageTests.db"));
            var series = repo.GetPersistentOrderedMap <DateTime, decimal>("test_series_CouldAddValuesByKey");
            var test2  = series.Map(x => (double)x);

            series.RemoveAll();
            //series.RemoveMany(DateTime.Today.AddHours(-6), Lookup.GE);
            for (int i = 0; i < 10; i++)
            {
                series.Add(DateTime.Today.AddMinutes(i), i);
            }
            series.Flush();
            for (int i = 10; i < 100; i++)
            {
                series[DateTime.Today.AddMinutes(i)] = i;
            }
            series.Flush();
            series[DateTime.Today.AddMinutes(100)] = 100;
            Console.WriteLine(test2.Last.Key + " " + test2.Last.Key);
            series[DateTime.Today.AddMinutes(1000)] = 1000;
        }
Beispiel #7
0
        static unsafe void Main(string[] args)
        {
            GC.Collect(3, GCCollectionMode.Forced, true);
            var store = new SeriesStorage(SeriesStorage.GetDefaultConnectionString("TAQSample2.db"));


            var date = new DateTime(2015, 8, 5);

            var tsize = Marshal.SizeOf(typeof(TaqTrade));

            Console.WriteLine(tsize);

            var zip    = ZipFile.OpenRead(path);
            var stream = zip.Entries.Single().Open();

            var seriesDictionary = new Dictionary <string, IPersistentOrderedMap <DateTime, TaqTrade> >();

            using (BufferedStream bs = new BufferedStream(stream, 2 * 1024 * 1024))
                using (var reader = new StreamReader(bs, Encoding.ASCII)) {
                    byte[] compressedBuffer = null;
                    var    byteBuffer       = new byte[106];
                    int    len;
                    var    line = reader.ReadLine();
                    len = bs.ReadLineIntoBuffer(byteBuffer);
                    Console.WriteLine(line);
                    Console.WriteLine("Press enter to continue");
                    Console.ReadLine();
                    var sw = new Stopwatch();
                    sw.Start();
                    var c = 0;
                    while ((len = bs.ReadLineIntoBuffer(byteBuffer)) != 0) // && c < 100
                    {
                        var fb    = new FixedBuffer(byteBuffer, 0, len);
                        var trade = new TaqTrade(date, fb);

                        var symbol = trade.Symbol.ToLowerInvariant().Trim();

                        IPersistentOrderedMap <DateTime, TaqTrade> series;
                        if (!seriesDictionary.TryGetValue(symbol, out series))
                        {
                            series = store.GetPersistentOrderedMap <DateTime, TaqTrade>(symbol);
                            seriesDictionary[symbol] = series;
                        }

                        series[trade.Time] = trade;

                        c++;
                        if (c % 100000 == 0)
                        {
                            Console.WriteLine($"Read so far: {c}");
                            foreach (var s in seriesDictionary)
                            {
                                s.Value.Flush();
                            }
                        }
                    }
                    sw.Stop();
                    foreach (var series in seriesDictionary)
                    {
                        series.Value.Flush();
                    }
                    Console.WriteLine($"Lines read: ${c} in msecs: {sw.ElapsedMilliseconds}");
                }

            Console.WriteLine("Finished");
            GC.Collect(3, GCCollectionMode.Forced, true);
            Console.WriteLine($"Total memory: {GC.GetTotalMemory(true)}");
            Console.ReadLine();
        }
Beispiel #8
0
        public void CouldCRUDSeriesStorage()
        {
            var storage    = new SeriesStorage("Filename=../benchmark.db"); // SeriesStorage.Default;
            var timeseries = storage.GetPersistentOrderedMap <DateTime, double>("test_timeseries");

            Console.WriteLine(storage.Connection.DataSource);
            var start = DateTime.UtcNow;

            Console.WriteLine($"Started at: {start}");

            if (!timeseries.IsEmpty)
            {
                // Remove all values
                timeseries.RemoveMany(timeseries.First.Key, Lookup.GE);
            }

            var sw    = new Stopwatch();
            var count = 10000000L;

            Console.WriteLine($"Count: {count}");

            var date = DateTime.UtcNow.Date;
            var rng  = new Random();

            sw.Start();
            for (long i = 0; i < count; i++)
            {
                timeseries.Add(date, Math.Round(i + rng.NextDouble(), 2));
                date = date.AddTicks(rng.Next(1, 100));
                if (i % 1000000 == 0)
                {
                    var msec = (DateTime.UtcNow - start).TotalMilliseconds;
                    var mops = i * 0.001 / msec;
                    Console.WriteLine($"Wrote: {i} - {Math.Round((i * 1.0) / (count * 1.0), 4) * 100.0}% in {msec/1000} sec, Mops: {mops}");
                }
            }
            timeseries.Flush();
            Console.WriteLine($"Wrote: {count} - 100%");
            Console.WriteLine($"Finished at: {DateTime.UtcNow}");
            sw.Stop();
            Console.WriteLine($"Writes, Mops: {count * 0.001 / sw.ElapsedMilliseconds}");


            sw.Restart();
            var sum         = 0.0;
            var storage2    = new SeriesStorage("Filename=../benchmark.db"); // $"Filename={Path.Combine(Bootstrap.Bootstrapper.Instance.DataFolder, "default.db")}");
            var timeseries2 = storage2.GetPersistentOrderedMap <DateTime, double>("test_timeseries");

            foreach (var kvp in timeseries2)
            {
                sum += kvp.Value;
            }
            Assert.IsTrue(sum > 0);
            sw.Stop();
            Console.WriteLine($"Reads, Mops: {count * 0.001 / sw.ElapsedMilliseconds}");

            var _connection =
                new SqliteConnection("Filename=../benchmark.db");
            //$"Filename={Path.Combine(Bootstrap.Bootstrapper.Instance.DataFolder, "default.db")}");

            var sqlCount = _connection.ExecuteScalar <long>($"SELECT sum(count) FROM {storage.ChunkTableName} where id = (SELECT id from {storage.IdTableName} where TextId = 'test_timeseries'); ");

            Console.WriteLine($"Count in SQLite: {sqlCount}");
            Assert.AreEqual(count, sqlCount);
            var sqlSize = _connection.ExecuteScalar <long>($"SELECT sum(length(ChunkValue)) FROM {storage.ChunkTableName} where id = (SELECT id from {storage.IdTableName} where TextId = 'test_timeseries'); ");

            Console.WriteLine($"Memory size: {count * 16L}; SQLite net blob size: {sqlSize}; comp ratio: {Math.Round(count * 16.0 / sqlSize * 1.0, 2)}");
        }
Beispiel #9
0
		private SeriesSymbolDataRand InternalGetSeries(InstrumentDataRequest dataRequest, bool useCache) {
			SeriesStorage cStorage = null;
			string sLSymbolId = dataRequest.Symbol.ToLower();
			lock (__cStorages) {
				if (!__cStorages.TryGetValue(sLSymbolId, out cStorage)) {
					cStorage = new SeriesStorage(16);
					__cStorages.Add(sLSymbolId, cStorage);
				}
			}

			SeriesSymbolDataRand cSeriesRand = null;
			int iTotalSeconds = dataRequest.Resolution.TotalSeconds;
			if (useCache) {  //是否使用快取
				lock (cStorage) {  //需要 lock 這個區塊(避免非同步讀取資料時發生問題)
					int iBaseSeconds = (iTotalSeconds < Resolution.MAX_BASE_TOTALSECONDS) ? Resolution.MIN_BASE_TOTALSECONDS : Resolution.MAX_BASE_TOTALSECONDS;
					SeriesSymbolData cSeries = cStorage.GetSeries(iTotalSeconds);
					if (cSeries == null) {
						cSeries = cStorage.GetSeries(iBaseSeconds);
						if (cSeries == null) {
							DataAdapter cAdapter = LoadAdapter(ref dataRequest);
							cSeries = cAdapter.Series;
							cStorage.Add(cSeries);
						}
					}

					if (iBaseSeconds == iTotalSeconds) {
						dataRequest = cSeries.DataRequest;
						goto exit;
					} else {
						cSeries = cSeries.CreateSeries(dataRequest); //利用基礎周期建立其他的資料周期
						cStorage.Add(cSeries);  //加入至 SeriesStorage
					}

					dataRequest.Resolution = cSeries.DataRequest.Resolution;  //將目標的週期結構更新至傳入的 InstrumentDataRequest 週期結構
					
					DataRequestEvent cRequestEvent = new DataRequestEvent(dataRequest);
					cSeries.OnRequest(cRequestEvent);  //如果已經存在則請求使用者需要的歷史資料區間(請求方法會檢查目前已下載的歷史資料區間是否足夠, 如果使用者需要的歷史資料區間比較大會向伺服器請求)
					dataRequest.Range.Count = cRequestEvent.Count;  //將請求後的正確數量傳入至結構內
				exit:
					cSeriesRand = new SeriesSymbolDataRand(cSeries, dataRequest);
				}
			} else {
				DataAdapter cAdapter = LoadAdapter(ref dataRequest, false);  //重新建立新的基礎週期序列資料(不使用快取, 不保存至快取內, 使用完畢之後立即 Dispose)
				SeriesSymbolData cSeries = cAdapter.Series;  //取得新的基礎周期序列資料

				int iBaseSeconds = (iTotalSeconds < Resolution.MAX_BASE_TOTALSECONDS) ? Resolution.MIN_BASE_TOTALSECONDS : Resolution.MAX_BASE_TOTALSECONDS;
				if (iBaseSeconds == iTotalSeconds) {
					dataRequest = cSeries.DataRequest;
				} else {
					SeriesSymbolData cTargetSeries = cSeries.CreateSeries(dataRequest);  //使用 InstrumentDataRequest 建立新的其他週期序列資料
					cSeries.Merge(cTargetSeries);  //將基礎周期序列資料合併至新的其他週期序列資料
					cSeries.Dispose();  //釋放基礎周期序列資料

					cSeries = cTargetSeries;
				}

				cSeriesRand = new SeriesSymbolDataRand(cSeries, dataRequest);
				cStorage.Add(cSeries, true);  //保存序列資料(存放在 SeriesStorage 內的序列資料才會自動合併最新的即時資訊報價)
				cAdapter.Dispose();  //釋放資料配置者類別
			}
			return cSeriesRand;
		}