예제 #1
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;
                    }
                }
            }
        }
예제 #2
0
		private void SeriesSymbolData_onRequest(object sender, DataRequestEvent e) {
			SeriesSymbolData cTargetSeries = sender as SeriesSymbolData;
			if (!cTargetSeries.DataRequest.Range.IsAlreadyRequestAllData) {
				int iTotalSeconds = cTargetSeries.DataRequest.Resolution.TotalSeconds;

				SeriesSymbolData cBaseSeries = GetSeries(((iTotalSeconds < Resolution.MAX_BASE_TOTALSECONDS) ? Resolution.MIN_BASE_TOTALSECONDS : Resolution.MAX_BASE_TOTALSECONDS));
				if (cBaseSeries.DataRequest.Range.IsAlreadyRequestAllData) {
					e.IsAlreadyRequestAllData = true;
					e.Count = cBaseSeries.DataRequest.Range.Count / e.Rate;
				} else {
					DataRequestEvent cRequestEvent = null;
					lock (__oLock) {  //需要鎖定資源(因為有可能多個策略同時請求基礎序列類別資料, 如果不鎖定會重複請求資料)
						if (e.Totals == 0) {  //檢查是否資料總個數為0(0=使用 InstrumentDataRequest 請求歷史資料)
							cRequestEvent = e.Clone();  //直接複製
						} else {  //如果不為0(表示使用者取得資料時超過目前已下載歷史資料的區間, 經過基礎週期比率計算之後再向伺服器請求歷史資料)
							int iTotals = e.Totals * e.Rate;  //資料總個數 * 縮放比率 = 基礎週期需要請求的資料總個數
							int iRequestCount = iTotals - cBaseSeries.DataRequest.Range.Count;  //計算後的資料總個數 - 基礎週期目前已下載後的資料個數 = 欲請求的的個數
							cRequestEvent = new DataRequestEvent(iRequestCount, iTotals, cBaseSeries.DataRequest.Resolution.Rate);
						}
						cBaseSeries.OnRequest(cRequestEvent);  //回補歷史資訊
					}

					if (cRequestEvent.Result == 0) {
						e.Result = cRequestEvent.Result;
						e.Ranges = cRequestEvent.Ranges;
						e.Count = cRequestEvent.Count / e.Rate;
						e.IsAlreadyRequestAllData = cRequestEvent.IsAlreadyRequestAllData;
					}
				}

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

				lock (__oLock) {  //須鎖定資源(將基礎序列資料合併至目標序列時需要鎖定, 避免合併的時候多執行緒導致合併資料產生問題)
					int iTargetCount = cTargetSeries.Indexer.Count;
					int iAllocSize = e.Count - cTargetSeries.DataRequest.Range.Count;
					if (iTargetCount == 0 || iAllocSize > 0) {
						if (iAllocSize > 0) {
							++iAllocSize;  //多預留一個空間(避免陣列空間不足)
							cTargetSeries.AdjustSize(iAllocSize, true);
						}
						cBaseSeries.Merge(cTargetSeries);  //合併資料
					}
				}
			}
		}
예제 #3
0
		internal void OnRequest(DataRequestEvent e) {
			if (onRequest != null) {
				onRequest(this, e);

				if (e.Result == 0) {
					__cDataRequest.Range.Count = e.Count;
					__cDataRequest.Range.From = e.Ranges[0];
					__cDataRequest.Range.IsAlreadyRequestAllData = e.IsAlreadyRequestAllData;

					if (!this.Initialized) {  //尚未初始化之前才需要更新(初始化之後已經併入即時報價資訊, 更新時間會是目前最新的報價時間)
						__cUpdateTime = __cTimes[this.Indexer.RealtimeIndex];  //更新最後的更新時間(如果沒有即時報價資訊, 這個就是最後一根 Bars 的時間)
					}

					if (onRequestCompleted != null) {
						onRequestCompleted(this, EventArgs.Empty);
					}
				} else {
					RemoveRequest();  //請求失敗就移除請求事件(表示可能伺服器有問題或沒有歷史報價資訊無法執行請求服務)
				}
			}
		}
예제 #4
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;
            }
        }
예제 #5
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;
		}
예제 #6
0
 /// <summary>
 ///   請求商品歷史資料
 /// </summary>
 /// <param name="e">資料請求事件</param>
 protected internal abstract void Request(DataRequestEvent e);