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); } } } }
/// <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)); }); }
private void SeriesSymbolData_onReset(object sender, EventArgs e) { SeriesSymbolDataRand cSeriesRand = __cBars.FullSymbolData as SeriesSymbolDataRand; int iSize = cSeriesRand.BarsSize - this.Count; if (iSize > 0) { this.AdjustSize(iSize); //調整容量 } }
/// <summary> /// 建構子 /// </summary> /// <param name="master">CStudyControl 類別</param> /// <param name="defaultVal">預設值</param> /// <param name="dataStream">資料串流編號</param> public VariableSeries(IStudyControl master, T defaultVal, int dataStream) { __cDefault = defaultVal; this.DataStream = dataStream; __cBars = master.BarsOfData(dataStream) as Instrument; __cBars.BindResetEvent(SeriesSymbolData_onReset); //設定清盤重置事件 SeriesSymbolDataRand cSeriesRand = __cBars.FullSymbolData as SeriesSymbolDataRand; this.Initialize(cSeriesRand.BarsSize); master.AddVariable(this); }
/// <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); } } }
/// <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); }
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; }
internal SeriesResultEvent(SeriesSymbolDataRand seriesSymbolDataRand, object parameters) { __cSeriesRand = seriesSymbolDataRand; __oParameters = parameters; }