Beispiel #1
0
		private static void MergeSeries(SeriesSymbolData target, DateTime period, double open, double high, double low, double close, double volume, bool isNewBars, bool isRealtime) {
			if (isNewBars) {
				target.AddSeries(period, open, high, low, close, volume, isRealtime);
			} else {
				target.SetSeries(open, high, low, close, volume, isRealtime);
			}
		}
		private static int __iLastSeriesId = 0;  //存放最後一個 Series Id(此 Id 會一直遞增, 每次使用 new 產生此類別時就會自動遞增)
		private static void MergeSeries(SeriesSymbolData target, DateTime period, double open, double high, double low, double close, double volume, bool isNewBars, bool isRealtime) {
			if (isNewBars) {
				target.AddSeries(period, open, high, low, close, volume, isRealtime);
			} else {
				target.SetSeries(open, high, low, close, volume, isRealtime);
			}
		}
Beispiel #3
0
		internal DataAdapter(InstrumentDataRequest request) {
			__cCookies = new CookieContainer();
			int iCount = request.Range.Count;

			__cSeries = new SeriesSymbolData(request);
			__cSeries.onRequest += SeriesSymbolData_onRequest;

			__cSeries.OnRequest(new DataRequestEvent(iCount, iCount, 1));  //請求歷史資料
			__cSeries.MergeTicks();  //合併即時Tick資訊
		}
Beispiel #4
0
		/// <summary>
		///   取得指定的總秒數週期 SeriesSymbolData 列表
		/// </summary>
		/// <param name="hashKey">可以為時間週期總秒數或是 Identify</param>
		internal SeriesSymbolData GetSeries(int hashKey) {
			int iIndex = 0;
			SeriesSymbolData cSeries = null;
			
			lock (__cIndexs) {
				if (__cIndexs.TryGetValue(hashKey, out iIndex)) {
					cSeries = __cSeries[iIndex];
				}
			}
			return cSeries;
		}
Beispiel #5
0
		internal void MergeTick(ITick tick) {
			lock (__cIndexs) {
				int iCount = __cSeries.Count;
				
				Parallel.For(0, iCount, (i) => {
					SeriesSymbolData cSeries = __cSeries[i];
					if (cSeries.Initialized) {
						cSeries.Merge(tick);
					}
				});
			}
		}
Beispiel #6
0
		/// <summary>
		///   處理清盤重置
		/// </summary>
		/// <param name="dataSource">即時報價來源名稱</param>
		internal void Reset(string dataSource) {
			lock (__cIndexs) {
				int iCount = __cSeries.Count;
				Parallel.For(0, iCount, (i) => {
					SeriesSymbolData cSeries = __cSeries[i];
					
					string sDataFeed = cSeries.DataRequest.DataFeed;
					if (sDataFeed.Equals(dataSource)) {
						cSeries.Reset();
					}
				});
			}
		}
Beispiel #7
0
		/// <summary>
		///   加入 SeriesSymbolData 列表
		/// </summary>
		/// <param name="series">SeriesSymbolData 列表</param>
		internal void Add(SeriesSymbolData series) {
			int iTotalSeconds = series.DataRequest.Resolution.TotalSeconds;
			lock (__cIndexs) {
				if (!__cIndexs.ContainsKey(iTotalSeconds)) {
					int iIndex = __cSeries.Count;
					__cSeries.Add(series);
					__cIndexs.Add(iTotalSeconds, iIndex);

					bool bBase = (iTotalSeconds == Resolution.MIN_BASE_TOTALSECONDS || iTotalSeconds == Resolution.MAX_BASE_TOTALSECONDS);
					if (!bBase) {
						series.onRequest += SeriesSymbolData_onRequest;
					}
				}
			}
		}
Beispiel #8
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);  //合併資料
					}
				}
			}
		}
Beispiel #9
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;
			}
		}
Beispiel #10
0
		/// <summary>
		///   加入 SeriesSymbolData 列表
		/// </summary>
		/// <param name="series">SeriesSymbolData 列表</param>
		/// <param name="useIdentify">是否使用 Identify 當作 Hash 值(true=使用 Identify 作為 Hash 值, false=使用時間週期總秒數當作 Hash 值)</param>
		internal void Add(SeriesSymbolData series, bool useIdentify = false) {
			int iHash = (useIdentify) ? series.Id : series.DataRequest.Resolution.TotalSeconds;
			lock (__cIndexs) {
				if (!__cIndexs.ContainsKey(iHash)) {
					int iIndex = __cSeries.Count;
					__cSeries.Add(series);
					__cIndexs.Add(iHash, iIndex);

					if (!useIdentify) {
						series.Id = iHash;  //將 Id 改為 iHash(iHash=時間週期總秒數, 當存入 SeriesStorage 後都以 Id 當作 Hash 存取)

						bool bBase = (iHash == Resolution.MIN_BASE_TOTALSECONDS || iHash == Resolution.MAX_BASE_TOTALSECONDS);
						if (!bBase) {
							series.onRequest += SeriesSymbolData_onRequest;
						}
					}
				}
			}
		}
        internal void Merge(SeriesSymbolData target)
        {
            int iTargetCount = target.Count;
            int iFirstIndex  = target.Indexer.GetBaseIndex(__cDataRequest.Range.Count);

            DateTime        cFrom    = __cTimes[Indexer.HistoryIndex];
            DateTime        cTo      = __cTimes[iFirstIndex];
            List <DateTime> cPeriods = target.__cDataRequest.Resolution.CalculatePeriods(cFrom, cTo);

            for (int i = iFirstIndex; i >= Indexer.HistoryIndex; i--)
            {
                DateTime cBaseTime = __cTimes[i];
                bool     bNewBars  = Resolution.GetNearestPeriod(cPeriods, ref cBaseTime);
                MergeSeries(target, cBaseTime, __cTimes[i], __cOpens[i], __cHighs[i], __cLows[i], __cCloses[i], __cVolumes[i], bNewBars, false);
                if (bNewBars)
                {
                    target.Indexer.SetBaseIndex(i);
                }
            }
        }
Beispiel #12
0
		/// <summary>
		///   移除 SeriesSymbolData 列表
		/// </summary>
		/// <param name="seriesId">SeriesSymbolData id</param>
		internal void Remove(int seriesId) {
			int iIndex = 0;
			lock (__cIndexs) {
				if (__cIndexs.TryGetValue(seriesId, out iIndex)) {
					SeriesSymbolData cTarget = __cSeries[iIndex];
					cTarget.Dispose();

					int iLast = __cSeries.Count - 1;
					if (iLast > 0 && iLast > iIndex) {
						SeriesSymbolData cLast = __cSeries[iLast];

						int iLastSeriesId = cLast.Id;
						__cIndexs[iLastSeriesId] = iIndex;
						__cSeries[iIndex] = cLast;
					}

					__cIndexs.Remove(seriesId);
					__cSeries.RemoveAt(iLast);
				}
			}
		}
Beispiel #13
0
		internal void Merge(SeriesSymbolData target) {
			int iTargetCount = target.Indexer.Count;
			int iFirstIndex = target.Indexer.GetBaseIndex(__cDataRequest.Range.Count);

			DateTime cFrom = __cTimes[Indexer.HistoryIndex];
			DateTime cTo = __cTimes[iFirstIndex];
			List<DateTime> cPeriods = target.__cDataRequest.Resolution.CalculatePeriods(cFrom, cTo);

			for (int i = iFirstIndex; i >= Indexer.HistoryIndex; i--) {
				DateTime cBaseTime = __cTimes[i];
				bool bNewBars = Resolution.GetNearestPeriod(cPeriods, ref cBaseTime);
				MergeSeries(target, cBaseTime, __cOpens[i], __cHighs[i], __cLows[i], __cCloses[i], __cVolumes[i], bNewBars, false);
				
				if (bNewBars) {
					target.Indexer.SetBaseIndex(i);
				}
			}

			if (iTargetCount == 0) {
				target.__cDataRequest.Range.To = __cDataRequest.Range.To;

				Queue<DateTime> cQueue = target.CreateRealtimePeriods();
				for (int i = __cDataRequest.Range.Count; i <= Indexer.RealtimeIndex; i++) {
					DateTime cBaseTime = __cTimes[i];
					bool bCreate = Resolution.GetNearestPeriod(cQueue, ref cBaseTime);
					MergeSeries(target, cBaseTime, __cOpens[i], __cHighs[i], __cLows[i], __cCloses[i], __cVolumes[i], bCreate, true);
				}
			}

			target.__cUpdateTime = __cUpdateTime;  //更新目標資訊的最後更新時間(最後更新時間會牽涉到 Bars 的狀態 Close or Inside)
			target.Initialized = true;
		}
		internal SeriesSymbolDataRand(SeriesSymbolData source, int maxBarsReferance) {
			__cIndexer = source.Indexer;
			__iBaseAdjustTotal = __cIndexer.AdjustTotalCount;
			source.Clone(out __cTimes, out __cOpens, out __cHighs, out __cLows, out __cCloses, out __cVolumes);

			if (maxBarsReferance > 0) {
				__iIgnoreBarsCount = __cCloses.Count - source.RealtimeCount - maxBarsReferance;
				if (__iIgnoreBarsCount < 0) {
					__iIgnoreBarsCount = 0;
				}
			}
		}
Beispiel #15
0
		/// <summary>
		///   建構子
		/// </summary>
		/// <param name="source">SeriesSymbolData 類別</param>
		/// <param name="maxBarsReferance">最大 Bars count 參考值(如果不需要很多歷史資訊計算則可以設定小一點, 設定數量不可以超過歷史資料載入總數量)</param>
		public Instrument(SeriesSymbolData source, int maxBarsReferance) {
			__cSource = source;
			__cFullSymbolData = new SeriesSymbolDataRand(source, maxBarsReferance);

			this.CurrentBar = 1;  //預設值
			string sDataSource = __cSource.DataRequest.DataFeed;
			
			AbstractQuoteService cService = QuoteManager.Manager.GetQuoteService(sDataSource);
			if (cService != null) {
				__cQuoteStorage = cService.Storage;
			}
		}