Exemplo n.º 1
0
		internal SeriesSymbolData(InstrumentDataRequest dataRequest, InstrumentSettings settings = null) {
			this.Id = 0x40000000 | System.Threading.Interlocked.Increment(ref __iLastSeriesId);
			this.Indexer = new SeriesIndexer();
			__cDataRequest = dataRequest;
			__cSettings = ((settings == null) ? new InstrumentSettings(ref __cDataRequest) : settings.Create(ref __cDataRequest));
			__cUpdateTime = DateTime.UtcNow.AddHours(__cSettings.TimeZone);
			
			SessionObject cSession = __cSettings.GetSessionFromToday();
			__iRealtimeCount = (cSession == null) ? 1 : (int) ((cSession.GetCloseTimeForDaylight() - cSession.GetStartTimeForDaylight()).TotalSeconds / dataRequest.Resolution.TotalSeconds + 1);

			Indexer.HistoryIndex = 0;
			Indexer.RealtimeIndex = -1;

			__cOpens = new Series<double>(__iRealtimeCount);
			__cOpens.onRequest += Series_onRequest;

			__cHighs = new Series<double>(__iRealtimeCount);
			__cHighs.onRequest += Series_onRequest;

			__cLows = new Series<double>(__iRealtimeCount);
			__cLows.onRequest += Series_onRequest;

			__cCloses = new Series<double>(__iRealtimeCount);
			__cCloses.onRequest += Series_onRequest;

			__cTimes = new Series<DateTime>(__iRealtimeCount);
			__cTimes.onRequest += Series_onRequest;

			__cVolumes = new Series<double>(__iRealtimeCount);
			__cVolumes.onRequest += Series_onRequest;

			__cDataRequest.Range.Count = 0;  //將資料筆數設定為0(因為一開始沒有請求任何資訊)
		}
Exemplo n.º 2
0
		private DataAdapter LoadAdapter(ref InstrumentDataRequest dataRequest, bool useCache = true) {
			InstrumentDataRequest cRequest = dataRequest;
			cRequest.Resolution = Resolution.GetBaseValue(dataRequest.Resolution);
			DataAdapter cAdapter = new DataAdapter(cRequest);

			InstrumentDataRequest cDataRequest = cAdapter.Series.DataRequest;
			dataRequest.Range.Count = cDataRequest.Range.Count;  //將正確的請求歷史資料數量傳入至結構

			if (useCache) {  //使用快取(true=建立完 DataAdapter 之後,將其保存至快取內以方便後續請求時使用)
				if (!cDataRequest.Range.IsAlreadyRequestAllData) {
					cAdapter.onCompleted += DataAdapter_onCompleted;

					string sLSymbolId = dataRequest.Symbol.ToLower();
					int iTotalSeconds = cDataRequest.Resolution.TotalSeconds;
					if (iTotalSeconds < Resolution.MAX_BASE_TOTALSECONDS) {
						lock (__cMinBases) {
							if (!__cMinBases.ContainsKey(sLSymbolId)) {
								__cMinBases.Add(sLSymbolId, cAdapter);
							}
						}
					} else {
						lock (__cDayBases) {
							if (!__cDayBases.ContainsKey(sLSymbolId)) {
								__cDayBases.Add(sLSymbolId, cAdapter);
							}
						}
					}
				}
			}
			return cAdapter;
		}
Exemplo n.º 3
0
		private void CreateInstrument(SeriesSymbolDataRand seriesSymbolDataRand, int dataIndex) {
			if (seriesSymbolDataRand != null) {
				if (logger.IsInfoEnabled) {
					InstrumentDataRequest cDataRequest = seriesSymbolDataRand.Source.DataRequest;
					logger.InfoFormat("[DataLoader.CreateInstrument] {0}:{1}{2} Instrument create completed...", cDataRequest.Symbol, cDataRequest.Resolution.Size, cDataRequest.Resolution.Type);
				}

				bool bCompleted = false;
				seriesSymbolDataRand.SetMaxbarsReferance(__iMaxBarsReference);
				Instrument cInstrument = new Instrument(seriesSymbolDataRand);
				
				lock (__cInstruments) {
					__cInstruments[dataIndex] = cInstrument;

					++__iMaxInstrumentCount;
					bCompleted = __iMaxInstrumentCount == __cInstruments.Count;
				}

				if (onAddInstrument != null) {
					onAddInstrument(this, new InstrumentChangeEvent(cInstrument, dataIndex));
				}

				if (bCompleted) {  //如果讀取資料都已經完成, 發出事件通知已經完成
					if (onLoadCompleted != null) {
						onLoadCompleted(this, EventArgs.Empty);
					}
				}
			}
		}
Exemplo n.º 4
0
		/// <summary>
		///   非同步模式取得序列商品資訊
		/// </summary>
		/// <param name="dataRequest">資料請求結構</param>
		/// <param name="result">序列商品資訊回報事件</param>
		/// <param name="useCache">是否使用快取 [預設:true](true=序列資料結構建立後保存在快取內,下次需要使用直接從快取拿取, false=重新建立序列資料結構,建立的序列資料需要自行移除否則會占用記憶體空間)</param>
		/// <param name="args">使用者自訂參數</param>
		/// <param name="millisecondsTimeout">回補資料 Timeout 毫秒數 [預設:System.Threading.Timeout.Infinite (永遠等待直到回補完成)]</param>
		public void AsyncGetSeries(InstrumentDataRequest dataRequest, EventHandler<SeriesResultEvent> result, bool useCache = true, object args = null, int millisecondsTimeout = Timeout.Infinite) {
			Task.Factory.StartNew(() => {
				CheckLogin(dataRequest.DataFeed);
				Complement(dataRequest, millisecondsTimeout);

				SeriesSymbolDataRand cSeries = InternalGetSeries(dataRequest, useCache);
				result(this, new SeriesResultEvent(cSeries, args));
			});
		}
Exemplo n.º 5
0
		/// <summary>
		///   根據設定資訊調整 InstrumentDataRequest 設定並回傳目前的設定類別
		/// </summary>
		/// <param name="request">InstrumentDataRequest類別</param>
		/// <returns>回傳值: 目前的 InstrumentSettings類別</returns>
		public InstrumentSettings Create(ref InstrumentDataRequest request) {
			SessionObject cSession = GetSessionFromToday();
			DataRequestType cRequestType = request.Range.RequestType;
			
			request.Resolution.CalculateRate(cSession.GetStartTimeForDaylight(), cSession.GetCloseTimeForDaylight(), __cProperty.Sessions.Count);
			if (cRequestType == DataRequestType.DaysBack || cRequestType == DataRequestType.FromTo) {
				request.Range.Count = request.Resolution.ConvertDaysToBars(request.Range.Count);
			}
			return this;
		}
Exemplo n.º 6
0
        internal DataRequestEvent(InstrumentDataRequest dataRequest)
        {
            this.Result = -1;
            __iRate     = dataRequest.Resolution.Rate;

            DataRequest cRange = dataRequest.Range;

            this.Count  = cRange.Count;
            this.Ranges = new DateTime[] { cRange.From, cRange.To };
        }
Exemplo n.º 7
0
        internal DataAdapter(InstrumentDataRequest request)
        {
            __cSeries            = new SeriesSymbolData(request);
            __cSeries.onRequest += SeriesSymbolData_onRequest;

            __cDevice = __cDeviceCreator.Create();
            __cDevice.SetSeries(__cSeries);

            __cSeries.OnRequest(new DataRequestEvent(request)); //請求歷史資料
            __cSeries.MergeTicks();                             //合併即時Tick資訊
        }
Exemplo n.º 8
0
        private void DrawTitle(Rectangle rectangle, ChartProperty property)
        {
            IQuote cQuote = __cBars.Quotes;
            IInstrumentSettings   cSettings   = __cBars.Info;
            InstrumentDataRequest cRequest    = __cBars.Request;
            Resolution            cResolution = cRequest.Resolution;
            string sTitle = string.Format("{0} {1} ({2}{3}) #{4} {5}", (cQuote == null) ? cRequest.Symbol : cQuote.SymbolId, (cQuote == null) ? cSettings.ASymbolInfo2.SymbolName : cQuote.SymbolName, cResolution.Size, cResolution.Type.ToString(), cSettings.Category.ToString(), cRequest.Exchange);

            IntPtr cOldFont = __cGDI.SelectFont(property.TitleFont);

            __cGDI.DrawString(sTitle, property.ForeColor, 5, rectangle.Top + 2);
            __cGDI.RemoveObject(__cGDI.SelectFont(cOldFont));
        }
Exemplo n.º 9
0
        private static SeriesSymbolData CreateSeries(string symbolId, EResolution type)
        {
            InstrumentDataRequest cRequest = new InstrumentDataRequest()
            {
                Exchange   = "TWSE",
                DataFeed   = "Mitake",
                Range      = DataRequest.CreateBarsBack(DateTime.Now, 1),
                Resolution = new Resolution(type, 1),
                Symbol     = symbolId
            };

            return(new SeriesSymbolData(cRequest));
        }
Exemplo n.º 10
0
        /// <summary>
        ///   請求商品歷史資料
        /// </summary>
        /// <param name="e">資料請求事件</param>
        protected internal override void Request(DataRequestEvent e)
        {
            InstrumentDataRequest cDataRequest = this.DataRequest;

            DateTime[] cRanges = e.Ranges;

            ZRequest cRequest = new ZRequest();

            cRequest.Method          = "POST";
            cRequest.Url             = __sHttpUrl;
            cRequest.Parameters      = string.Format("exchange={0}&symbolId={1}&timeFrame={2}&position={3}&startDate={4}&endDate={5}&count={6}", cDataRequest.Exchange, cDataRequest.Symbol, cDataRequest.Resolution.TotalSeconds, this.Position, cRanges[0].ToString("yyyy-MM-dd"), cRanges[1].ToString("yyyy-MM-dd"), e.Count);
            cRequest.CookieContainer = __cCookies;

            int iRet = cRequest.Request();

            if (iRet == 0)
            {
                ZReader cReader = new ZReader(cRequest.Response);
                e.Result = cReader.Result;

                if (cReader.Result == 0)
                {
                    int iCount = e.Count = cReader.Count;
                    this.AdjustSize(iCount);

                    ZBuffer cBuffer = cReader.Read();
                    while (--iCount >= 0)
                    {
                        cBuffer.Position = iCount * DATA_BLOCK_SIZE;
                        DateTime cDate   = cBuffer.GetDateTime();
                        double   dOpen   = cBuffer.GetDouble();
                        double   dHigh   = cBuffer.GetDouble();
                        double   dLow    = cBuffer.GetDouble();
                        double   dClose  = cBuffer.GetDouble();
                        double   dVolume = cBuffer.GetDouble();

                        this.AddSeries(cDate, dOpen, dHigh, dLow, dClose, dVolume);
                    }

                    this.Position = cReader.Position;
                    e.Ranges[0]   = cReader.BeginDate;
                    e.Ranges[1]   = cReader.EndDate;

                    if (this.Position == 0)
                    {
                        e.IsAlreadyRequestAllData = true;
                    }
                }
            }
        }
Exemplo n.º 11
0
		/// <summary>
		///   非同步讀取資料請求結構內的 Instrument 資料
		/// </summary>
		/// <param name="request">資料請求結構</param>
		/// <param name="result">當成功取得 Instrument 商品資料會使用此委派方法回傳資料</param>
		/// <param name="useCache">是否使用快取 [預設:false](true=序列資料結構建立後保存在快取內,下次需要使用直接從快取拿取, false=重新建立序列資料結構,建立的序列資料需要自行移除否則會占用記憶體空間)</param>
		/// <param name="args">使用者自訂參數</param>
		/// <param name="millisecondsTimeout">回補資料 Timeout 毫秒數 [預設:System.Threading.Timeout.Infinite (永遠等待直到回補完成)]</param>
		public void BeginLoadData(InstrumentDataRequest request, LoadDataCallback result, bool useCache = false, object args = null, int millisecondsTimeout = System.Threading.Timeout.Infinite) {
			SeriesManager.Manager.SetQuoteService(request.DataFeed);
			SeriesManager.Manager.AsyncGetSeries(request, (object sender, SeriesResultEvent e) => {
				SeriesSymbolDataRand cSeriesSymbolDataRand = e.Data;
				cSeriesSymbolDataRand.SetMaxbarsReferance(__iMaxBarsReference);
				Instrument cInstrument = new Instrument(cSeriesSymbolDataRand);  //建立 Instrument 商品資料
				
				Instrument cBars_0 = GetInstrument(0);  //取得目前第 0 個 Instrument 商品資料
				if (cBars_0 != null) {
					cInstrument.MoveBars(cBars_0.Time.Value);
				}

				result(new DataLoaderResult(cInstrument, cInstrument.Quotes, args));
			}, useCache, null, millisecondsTimeout);
		}
Exemplo n.º 12
0
		/// <summary>
		///   建構子
		/// </summary>
		/// <param name="source">SeriesSymbolData 商品資料類別</param>
		/// <param name="request">資料請求結構</param>
		internal SeriesSymbolDataRand(SeriesSymbolData source, InstrumentDataRequest request) {
			__cSource = source;
			__cSource.onRequestCompleted += SeriesSymbolData_onRequestCompleted;  //附掛請求歷史資料完成的事件通知

			__cIndexer = source.Indexer;
			__iBaseAdjustTotal = __cIndexer.AdjustTotalCount;
			source.Clone(out __cTimes, out __cOpens, out __cHighs, out __cLows, out __cCloses, out __cVolumes);

			__iHistoryIndex = __cCloses.Count - (request.Range.Count + source.RealtimeCount);
			this.Current = 1;  //預設值索引從 1 開始(內部會自動計算對應至 SeriesSymbolData 序列資料的正確索引位置)

			string sDataSource = source.DataRequest.DataFeed;
			AbstractQuoteService cService = QuoteManager.Manager.GetQuoteService(sDataSource);
			if (cService != null) {
				__cQuoteStorage = cService.Storage;
			}
		}
Exemplo n.º 13
0
        /// <summary>
        ///   將設定檔轉換為 InstrumentDataRequest 列表的格式
        /// </summary>
        /// <param name="requests">RequestSetting 陣列</param>
        /// <returns>返回值: InstrumentDataRequest 列表</returns>
        public static List <InstrumentDataRequest> Convert(List <RequestSetting> requests)
        {
            List <InstrumentDataRequest> cResult = new List <InstrumentDataRequest>();

            foreach (RequestSetting cRequest in requests)
            {
                string[]    sPeriods    = cRequest.DataPeriod.Split(',');
                int         iPeriodSize = int.Parse(sPeriods[0]);
                EResolution cResolution = (EResolution)Enum.Parse(typeof(EResolution), sPeriods[1]);

                InstrumentDataRequest cDataRequest = new InstrumentDataRequest()
                {
                    Exchange   = cRequest.Exchange,
                    DataFeed   = cRequest.DataFeed,
                    Resolution = new Resolution(cResolution, iPeriodSize),
                    Symbol     = cRequest.SymbolId
                };

                string[] sParams  = cRequest.Range.Split(',');
                string   sMode    = sParams[0];
                string[] sArgs    = sParams[1].Split(';');
                DateTime cEndDate = DateTime.Parse(sArgs[0]);
                if (cEndDate == MAX_REQUEST_LASTDATE)
                {
                    cEndDate = DateTime.Today;
                }

                switch (sMode)
                {
                case "barsBack":
                    cDataRequest.Range = DataRequest.CreateBarsBack(cEndDate, int.Parse(sArgs[1]));
                    break;

                case "daysBack":
                    cDataRequest.Range = DataRequest.CreateDaysBack(cEndDate, int.Parse(sArgs[1]));
                    break;

                case "fromTo":
                    cDataRequest.Range = DataRequest.CreateFromTo(DateTime.Parse(sArgs[1]), cEndDate);
                    break;
                }
                cResult.Add(cDataRequest);
            }
            return(cResult);
        }
Exemplo n.º 14
0
		private void Complement(InstrumentDataRequest request, int millisecondsTimeout) {
			string sDataSource = request.DataFeed;
			if (__cDataSources.Contains(sDataSource)) {
				AbstractQuoteService cService = QuoteManager.Manager.GetQuoteService(sDataSource);
				if (cService != null) {
					string sSymbolId = request.Symbol;
					IQuote cQuote = cService.Storage.GetQuote(sSymbolId);
					if (cQuote != null && cQuote.ComplementStatus != ComplementStatus.Complemented) {
						EventWaitHandle cWaitHandle = null;
						lock (__cAsyncArgs) {
							_AsyncEventArgs cArgs = null;
							string sHashKey = string.Format("{0}_{1}", sDataSource, sSymbolId);
							if (__cAsyncArgs.TryGetValue(sHashKey, out cArgs)) {
								cWaitHandle = cArgs.handle;
							} else {
								if (cQuote.ComplementStatus == ComplementStatus.NotComplement) {
									cArgs = new _AsyncEventArgs();
									cArgs.request = request;
									
									cWaitHandle = new ManualResetEvent(false);
									cArgs.handle = cWaitHandle;
									__cAsyncArgs.Add(sHashKey, cArgs);

									cService.AddSubscribe(sSymbolId);
									cService.Complement(sSymbolId);
								}
							}
						}

						if (cWaitHandle != null) {
							if (!cWaitHandle.WaitOne(millisecondsTimeout)) {  //等待回補資訊(如果 millisecondsTimeout 為 -1 則會無限等待, 如果有設定 Timeout 在時間到了之後還沒回補完畢就直接釋放 WaitHandle 元件並移除)
								cWaitHandle.Dispose();
								
								string sHashKey = string.Format("{0}_{1}", sDataSource, sSymbolId);
								lock (__cAsyncArgs) {
									__cAsyncArgs.Remove(sHashKey);
								}
							}
						}
					}
				}
			}
		}
Exemplo n.º 15
0
        private void SeriesSymbolData_onRequest(object sender, DataRequestEvent e)
        {
            int         iCount       = e.Count;
            DataRequest cDataRequest = __cSeries.DataRequest.Range;
            int         iBaseCount   = cDataRequest.Count;
            bool        bRequest     = e.Totals > iBaseCount;

            if (!bRequest)
            {
                bRequest = (__cDevice.Position == -1) ? true : e.CheckRequest(cDataRequest);
            }

            if (bRequest)
            {
                __cDevice.Request(e);

                if (e.Result == 0)
                {
                    e.Count += iBaseCount;

                    if (e.IsAlreadyRequestAllData)
                    {
                        __cSeries.RemoveRequest();                          //如果已經全部讀取完畢就取消事件

                        if (onCompleted != null)
                        {
                            InstrumentDataRequest cInstDataRequest = __cSeries.DataRequest;
                            onCompleted(this, new DataAdapterCompleteEvent(cInstDataRequest.Symbol, cInstDataRequest.Resolution.TotalSeconds));
                        }
                    }
                }
            }
            else
            {
                e.Result = 0;
                e.Count  = iBaseCount;
                e.Ranges = new DateTime[] { cDataRequest.From, cDataRequest.To };
                e.IsAlreadyRequestAllData = cDataRequest.IsAlreadyRequestAllData;
            }
        }
Exemplo n.º 16
0
        internal SeriesSymbolData(InstrumentDataRequest dataRequest, InstrumentSettings settings = null)
        {
            this.Indexer = new SeriesIndexer();

            __cDataRequest = dataRequest;
            __cSettings    = ((settings == null) ? new InstrumentSettings(ref __cDataRequest) : settings.Create(ref __cDataRequest));
            __cUpdateTime  = DateTime.UtcNow.AddHours(__cSettings.TimeZone);

            SessionObject cSession = __cSettings.GetSessionFromToday();

            __iRealtimeCount = (int)((cSession.EndTime - cSession.StartTime).TotalSeconds / dataRequest.Resolution.TotalSeconds + 1);

            Indexer.HistoryIndex  = 0;
            Indexer.RealtimeIndex = -1;

            __cOpens   = new Series <double>(__iRealtimeCount);
            __cHighs   = new Series <double>(__iRealtimeCount);
            __cLows    = new Series <double>(__iRealtimeCount);
            __cCloses  = new Series <double>(__iRealtimeCount);
            __cTimes   = new Series <DateTime>(__iRealtimeCount);
            __cVolumes = new Series <double>(__iRealtimeCount);

            __cDataRequest.Range.Count = 0;              //將資料筆數設定為0(因為一開始沒有請求任何資訊)
        }
Exemplo n.º 17
0
		/// <summary>
		///   建構子
		/// </summary>
		/// <param name="request">InstrumentDataRequest類別</param>
		public InstrumentSettings(ref InstrumentDataRequest request) {
			AbstractExchange cExchange = ProductManager.Manager.GetExchange(request.Exchange);

			__sSymbolId = request.Symbol;
			__sExchange = request.Exchange;
			__sDataSource = request.DataFeed;
			
			__dTimeZone = cExchange.TimeZone;
			__cProduct = cExchange.GetProduct(__sSymbolId);
			__cProperty = cExchange.GetProperty(__sSymbolId, __sDataSource);

			//如果沒有商品資訊就使用 request.Symbol 第一個字元當作搜尋條件來取代
			if (__cProduct == null) {
				List<Product> cProducts = cExchange.SearchProducts(new string(__sSymbolId[0], 1), false);
				foreach (Product cProduct in cProducts) {
					AbstractProductProperty cProperty = cExchange.GetProperty(cProduct.SymbolId);
					if (cProperty != null) {
						__cProduct = cProduct;
						__cProperty = cProperty;
						break;
					}
				}
			}

			__cOptionType = __cProperty.GetCallOrPut(__cProduct);     //取得選擇權 Call or Put 類型
			__dStrikePrice = __cProperty.GetStrikePrice(__cProduct);  //取得選擇權履約價格
				
			//取得合約到期日索引值
			IContractTime cContractTime = __cProperty.ContractRule as IContractTime;
			if (cContractTime != null) {
				__iContractIndex = cContractTime.GetContractIndex(__sSymbolId);
			}

			this.Create(ref request);
			__cResolution = request.Resolution;
		}
		private Instrument GetBars(string commodityId, char callOrPut, int targetPrice) {
			InstrumentDataRequest cRequest = new InstrumentDataRequest() {
				Exchange = "TWSE",
				DataFeed = "Mitake",
				Range = DataRequest.CreateBarsBack(DateTime.Now, MAX_LOAD_OPTIONS_COUNT),
				Resolution = new Resolution(EResolution.Day, 1),
				Symbol = string.Format("{0}{1}{2}.tw", commodityId, callOrPut, targetPrice)
			};

			__cExchange.AddProduct(new Product() {
				 Category = ESymbolCategory.IndexOption,
				 CommodityId = "TXW",
				 SymbolId = cRequest.Symbol,
				 SymbolName = cRequest.Symbol
			});
			return new Instrument(SeriesManager.Manager.GetSeries(cRequest), 0);
		}
Exemplo n.º 19
0
		internal SeriesSymbolData CreateSeries(InstrumentDataRequest dataRequest) {
			return new SeriesSymbolData(dataRequest, __cSettings);
		}
Exemplo n.º 20
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;
		}
Exemplo n.º 21
0
		/// <summary>
		///   取得序列商品資訊
		/// </summary>
		/// <param name="dataRequest">資料請求結構</param>
		/// <param name="useCache">是否使用快取 [預設:true](true=序列資料結構建立後保存在快取內,下次需要使用直接從快取拿取, false=重新建立序列資料結構,建立的序列資料需要自行移除否則會占用記憶體空間)</param>
		/// <param name="millisecondsTimeout">回補資料 Timeout 毫秒數 [預設:System.Threading.Timeout.Infinite (永遠等待直到回補完成)]</param>
		/// <returns>返回值: SeriesSymbolDataRand 類別</returns>
		public SeriesSymbolDataRand GetSeries(InstrumentDataRequest dataRequest, bool useCache = true, int millisecondsTimeout = Timeout.Infinite) {
			CheckLogin(dataRequest.DataFeed);
			Complement(dataRequest, millisecondsTimeout);
			
			return InternalGetSeries(dataRequest, useCache);
		}