/// <summary> /// Request historical prices for the specified timeframe of the specified period. /// </summary> /// <param name="communicator">The price history communicator.</param> /// <param name="instrument">The instrument.</param> /// <param name="timeframe">The timeframe.</param> /// <param name="from">From-date.</param> /// <param name="to">To-date</param> /// <param name="quotesCount">The quotes count.</param> /// <param name="responseListener">The response listener.</param> public static void GetHistoryPrices(IPriceHistoryCommunicator communicator, string instrument, string timeframe, DateTime from, DateTime to, int quotesCount, ResponseListener responseListener) { if (!communicator.isReady()) { Console.WriteLine("History communicator is not ready."); return; } // create timeframe entity ITimeframeFactory timeframeFactory = communicator.TimeframeFactory; O2GTimeframe timeframeObj = timeframeFactory.create(timeframe); // create and send a history request IPriceHistoryCommunicatorRequest request = communicator.createRequest(instrument, timeframeObj, from, to, quotesCount); responseListener.SetRequest(request); communicator.sendRequest(request); // wait results responseListener.Wait(); // print results if any IPriceHistoryCommunicatorResponse response = responseListener.GetResponse(); if (response != null) { PrintPrices(communicator, response); } }
/// <summary> /// Sends a request for the history /// </summary> public string RequestHistory(TransportHistoryRequest request) { O2GRequestFactory factory = mSession.getRequestFactory(); O2GTimeframeCollection timeframes = factory.Timeframes; O2GTimeframe timeframe = timeframes[request.Timeframe]; int count = request.Count > 300 ? 300 : request.Count; O2GRequest rq = factory.createMarketDataSnapshotRequestInstrument(request.Instrument, timeframe, count); if (request.From != factory.ZERODATE || request.To != factory.ZERODATE) { DateTime from, to; from = request.From; to = request.To; /* * if (request.From != factory.ZERODATE) * from = mTimeConverter.convert(request.From, O2GTimeConverterTimeZone.EST, O2GTimeConverterTimeZone.UTC); * else * from = factory.ZERODATE; * * if (request.To != factory.ZERODATE) * to = mTimeConverter.convert(request.To, O2GTimeConverterTimeZone.EST, O2GTimeConverterTimeZone.UTC); * else * to = factory.ZERODATE; */ factory.fillMarketDataSnapshotRequestTime(rq, from, to, false); } mHistoryRequests[rq.RequestID] = request; mSession.sendRequest(rq); return(rq.RequestID); }
/// <summary> /// Request historical prices for the specified timeframe of the specified period /// </summary> /// <param name="session"></param> /// <param name="sInstrument"></param> /// <param name="sTimeframe"></param> /// <param name="dtFrom"></param> /// <param name="dtTo"></param> /// <param name="responseListener"></param> public void GetHistoryPrices(O2GSession session, string sInstrument, string sTimeframe, DateTime dtFrom, DateTime dtTo, ResponseListener responseListener) { O2GRequestFactory factory = session.getRequestFactory(); O2GTimeframe timeframe = factory.Timeframes[sTimeframe]; if (timeframe == null) { throw new Exception(string.Format("Timeframe '{0}' is incorrect!", sTimeframe)); } O2GRequest request = factory.createMarketDataSnapshotRequestInstrument(sInstrument, timeframe, 300); DateTime dtFirst = dtTo; do // cause there is limit for returned candles amount { factory.fillMarketDataSnapshotRequestTime(request, dtFrom, dtFirst, false); responseListener.SetRequestID(request.RequestID); session.sendRequest(request); if (!responseListener.WaitEvents()) { throw new Exception("Response waiting timeout expired"); } // shift "to" bound to oldest datetime of returned data O2GResponse response = responseListener.GetResponse(); if (response != null && response.Type == O2GResponseType.MarketDataSnapshot) { O2GResponseReaderFactory readerFactory = session.getResponseReaderFactory(); if (readerFactory != null) { O2GMarketDataSnapshotResponseReader reader = readerFactory.createMarketDataSnapshotReader(response); if (reader.Count > 0) { if (DateTime.Compare(dtFirst, reader.getDate(0)) != 0) { dtFirst = reader.getDate(0); // earliest datetime of returned data } else { break; } } else { // Console.WriteLine("0 rows received"); updateLogDelegate(string.Format("0 rows received")); break; } } // PrintPrices(session, response); storeHistoryPriceToDataTable(session, response, sInstrument); // DateTime.Subtraction(dtTo, dtFirst)/ Subtraction long percent = (dtTo.Ticks - dtFirst.Ticks) * 100 / (dtTo.Ticks - dtFrom.Ticks); updateProcessDelegate((int)percent, this.InstrumentDT.Rows.Count); } else { break; } } while (dtFirst > dtFrom); }
private void btnGetHistoricPrices_Click(object sender, EventArgs e) { try { m_datetimestart = monthCalendarStart.SelectionRange.Start.Date; m_datetimeend = monthCalendarEnd.SelectionRange.Start.Date; m_instrument = cbInstrument.SelectedItem.ToString(); m_interval = cbInterval.SelectedItem.ToString(); ResponseListener responseListener = new ResponseListener(m_session); m_session.subscribeResponse(responseListener); O2GRequestFactory factory = m_session.getRequestFactory(); O2GTimeframeCollection timeframecollection = factory.Timeframes; O2GTimeframe stimeframe = timeframecollection[m_interval]; GetHistoryPrices(m_session, m_instrument, m_interval, m_datetimestart, m_datetimeend, responseListener); MessageBox.Show("Historic Data Received", "", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { LogDirector.DoAction(2, ex); MessageBox.Show("Unable to connect to server", "", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// Request historical prices for the specified timeframe of the specified period /// </summary> /// <param name="session"></param> /// <param name="sInstrument"></param> /// <param name="sTimeframe"></param> /// <param name="dtFrom"></param> /// <param name="dtTo"></param> /// <param name="responseListener"></param> public static void GetHistoryPrices(O2GSession session, string sInstrument, string sTimeframe, DateTime dtFrom, DateTime dtTo, ResponseListener responseListener) { O2GRequestFactory factory = session.getRequestFactory(); O2GTimeframe timeframe = factory.Timeframes[sTimeframe]; if (timeframe == null) { throw new Exception(string.Format("Timeframe '{0}' is incorrect!", sTimeframe)); } O2GRequest request = factory.createMarketDataSnapshotRequestInstrument(sInstrument, timeframe, 300); DateTime dtFirst = dtTo; do // cause there is limit for returned candles amount { factory.fillMarketDataSnapshotRequestTime(request, dtFrom, dtFirst, false, O2GCandleOpenPriceMode.PreviousClose); responseListener.SetRequestID(request.RequestID); session.sendRequest(request); if (!responseListener.WaitEvents()) { throw new Exception("Response waiting timeout expired"); } // shift "to" bound to oldest datetime of returned data O2GResponse response = responseListener.GetResponse(); if (response != null && response.Type == O2GResponseType.MarketDataSnapshot) { O2GResponseReaderFactory readerFactory = session.getResponseReaderFactory(); if (readerFactory != null) { O2GMarketDataSnapshotResponseReader reader = readerFactory.createMarketDataSnapshotReader(response); if (reader.Count > 0) { if (DateTime.Compare(dtFirst, reader.getDate(0)) != 0) { dtFirst = reader.getDate(0); // earliest datetime of returned data } else { break; } } else { Console.WriteLine("0 rows received"); break; } } PrintPrices(session, response); } else { break; } } while (dtFirst > dtFrom); }
/// <summary> /// Requests the historical data /// </summary> /// <param name="instrument">The instrument</param> /// <param name="timeframe">The timeframe</param> /// <param name="from">Date/time to get the data from</param> /// <param name="to">Date/time to get the data to</param> public void RequestHistory(string instrument, O2GTimeframe timeframe, DateTime from, DateTime to) { IPriceHistoryCommunicatorRequest request = mPriceHistoryCommunicator.createRequest(instrument, timeframe, from, to, -1); // We don't need a pre-created collection for pure historical data, but just lets create it // to handle the response in the same way. PeriodCollection collection = new PeriodCollection(instrument, timeframe.ID, false, this); mHistories[request] = collection; mPriceHistoryCommunicator.sendRequest(request); // ... to response handling see onRequestCompleted in Price Communicator Event handler section }
private List <FxBar> getHistoryPrices(O2GSession session, string instrument, Resolution resolution, DateTime startDateTime, DateTime endDateTime, int maxBars, GetHistoricalDataResponseListener responseListener) { O2GRequestFactory factory = session.getRequestFactory(); var tf = convert_Resolution_To_string(resolution); O2GTimeframe timeframe = factory.Timeframes[tf]; if (timeframe == null) { throw new TimeframeNotFoundException($"Timeframe '{resolution.TimeFrame}:{resolution.Size}' is incorrect!"); } O2GRequest request = factory.createMarketDataSnapshotRequestInstrument(instrument, timeframe, maxBars); factory.fillMarketDataSnapshotRequestTime(request, startDateTime, endDateTime, false); responseListener.SetRequestID(request.RequestID); session.sendRequest(request); if (!responseListener.WaitEvents()) { throw new Exception($"{responseListener.Error}"); } O2GResponse response = responseListener.GetResponse(); List <FxBar> barList = new List <FxBar>(); if (response != null && response.Type == O2GResponseType.MarketDataSnapshot) { O2GResponseReaderFactory readerFactory = session.getResponseReaderFactory(); if (readerFactory != null) { O2GMarketDataSnapshotResponseReader reader = readerFactory.createMarketDataSnapshotReader(response); if (reader.Count > 0) { for (int i = 0; i < reader.Count; i++) { barList.Add(new FxBar { Open = reader.getBidOpen(i), High = reader.getBidHigh(i), Low = reader.getBidLow(i), Close = reader.getBidClose(i), Volume = reader.getVolume(i), DateTime = reader.getDate(i) }); } } } } return(barList); }
/// <summary> /// Gets the historical data up to now and subscribe it for price updates /// </summary> /// <param name="instrument">The instrument</param> /// <param name="timeframe">The timeframe</param> /// <param name="from">The date/time to get the data from</param> public void RequestAndSubscribeHistory(string instrument, O2GTimeframe timeframe, DateTime from) { IPriceHistoryCommunicatorRequest request = mPriceHistoryCommunicator.createRequest(instrument, timeframe, from, Candleworks.PriceHistoryMgr.Constants.ZERODATE, -1); // here we create a collection right now in order to let it subscribe for all ticks (offer changes) // which may occur while the request is being executed, so no data is lost because of gap while the server // is already collected all data, but the client isn't started to update collection yet. PeriodCollection collection = new PeriodCollection(instrument, timeframe.ID, true, this); mHistories[request] = collection; mPriceHistoryCommunicator.sendRequest(request); // ... to response handling see onRequestCompleted in Price Communicator Event handler section }
// Request public void GetHistoryPrices(DateTime timeFrom, DateTime timeTo) { O2GRequestFactory factory = mSession.getRequestFactory(); O2GTimeframeCollection timeframes = factory.Timeframes; O2GTimeframe tfo = timeframes["D1"]; O2GRequest request = factory.createMarketDataSnapshotRequestInstrument("GBP/NZD", tfo, 7); timeFrom = today; timeTo = DateTime.Today; factory.fillMarketDataSnapshotRequestTime(request, timeFrom, timeTo, false); mSession.sendRequest(request); Thread.Sleep(5000); }
/// <summary> /// Constructor /// </summary> /// <param name="timeframe">ForexConnect timeframe descriptor</param> internal TimeframeItem(O2GTimeframe timeframe) { mTimeframe = timeframe; DateTime start = DateTime.Now.AddDays(-1), end = DateTime.Now; // parse the timeframe ID to get Quotes Manager timeframe descriptor if (!CandlePeriod.parsePeriod(timeframe.ID, ref mTimeframeUnit, ref mTimeframeLength)) { throw new ArgumentException("Invalide timeframe", "timeframe"); } // get a candle in that timeframe to get it length CandlePeriod.getCandle(DateTime.Now, ref start, ref end, mTimeframeUnit, mTimeframeLength, 0, 0); mLength = end.Subtract(start); }
public void GetLongHistoricPrices(string symbol, string timeframe, int ticks) { _mktData = new Quantum(); Symbol = new Symbol(symbol); session.AttachHandler(mHandler); DateTime dateNow = DateTime.Now; TimeSpan time = Timeframe.StringToTimeSpan(timeframe); DateTime startDate = dateNow.AddMinutes(-ticks * Timeframe.TimeframeToMinutes(timeframe)); O2GRequestFactory factory = session.Session.getRequestFactory(); O2GTimeframeCollection timeframes = factory.Timeframes; O2GTimeframe tfo = timeframes[timeframe]; int counter = ticks; lock (locker) { while (counter > 0) { _completeCounter++; int subticks = (counter >= QSConstants.MAX_FXCM_API_TICKS) ? QSConstants.MAX_FXCM_API_TICKS : counter; O2GRequest request = factory.createMarketDataSnapshotRequestInstrument(symbol, tfo, subticks); factory.fillMarketDataSnapshotRequestTime(request, startDate, startDate.AddMinutes(2 * subticks * Timeframe.TimeframeToMinutes(timeframe))); session.Session.sendRequest(request); startDate = startDate.AddMinutes(subticks * Timeframe.TimeframeToMinutes(timeframe)); counter -= (counter >= QSConstants.MAX_FXCM_API_TICKS) ? QSConstants.MAX_FXCM_API_TICKS : counter; } } int timeCounter = 0; while (!Complete || timeCounter++ < 3000) //max timeout 30 seconds { Thread.Sleep(100); } }
/// <summary> /// Send request to API for data /// </summary> /// <param name="adjustedStartDate"></param> /// <param name="endDate"></param> /// <param name="dataSetup"></param> public void sendRequest(DateTime adjustedStartDate, DateTime endDate, DataSetup dataSetup) { try { O2GRequestFactory factory = tss.Session.getRequestFactory(); O2GTimeframeCollection timeframes = factory.Timeframes; O2GTimeframe tfo = timeframes[timeInterval]; O2GRequest request = factory.createMarketDataSnapshotRequestInstrument(currency, tfo, 300); factory.fillMarketDataSnapshotRequestTime(request, adjustedStartDate, endDate, true); Console.WriteLine("Requesting from " + adjustedStartDate.ToString("MM/dd/yyyy HH:mm:ss") + " to " + endDate.ToString("MM/dd/yyyy HH:mm:ss")); logger.Debug("Requesting from " + adjustedStartDate.ToString("MM/dd/yyyy HH:mm:ss") + " to " + endDate.ToString("MM/dd/yyyy HH:mm:ss")); tss.Session.sendRequest(request); threadDictionary.Add(request.RequestID, dataSetup); } catch (Exception e) { MessageBox.Show("Error: " + e.Message); } }
/// <summary> /// Constructor /// </summary> /// <param name="controller">PriceHistory API controller</param> internal RequestHistoryForm(PriceAPIController controller) { InitializeComponent(); // Fills the list of the offers available for (int i = 0; i < controller.Offers.Count; i++) { comboBoxInstrument.Items.Add(controller.Offers[i].Instrument); } if (comboBoxInstrument.Items.Count > 0) { comboBoxInstrument.SelectedIndex = 0; } // Fills the list of the timeframes available except tick timeframes (as // ticks are not supported by PriceHistory API) O2GTimeframeCollection timeframes = controller.Timeframes; for (int i = 0; i < timeframes.Count; i++) { O2GTimeframe tf = timeframes[i]; if (tf.Unit == O2GTimeframeUnit.Tick) { continue; } TimeframeItem item = new TimeframeItem(tf); comboBoxTimeframe.Items.Add(item); } if (comboBoxTimeframe.Items.Count > 0) { comboBoxTimeframe.SelectedIndex = 0; } // Initialize the range for date/time controls dateTimePickerFrom.MinDate = new DateTime(1980, 1, 1); dateTimePickerFrom.MaxDate = DateTime.Now; dateTimePickerTo.MinDate = new DateTime(1980, 1, 1); }
private void GetHistoryPrices(O2GSession O2GSession, string Instrument, string Interval, DateTime DtFrom, DateTime DtTo) { m_responseListener = new ResponseListener(O2GSession); O2GSession.subscribeResponse(m_responseListener); O2GRequestFactory factory = O2GSession.getRequestFactory(); O2GTimeframeCollection timeframecollection = factory.Timeframes; O2GTimeframe Timeframe = timeframecollection[Interval]; if (Timeframe == null) { throw new Exception(string.Format("Timeframe '{0}' is incorrect!", Timeframe)); } O2GRequest request = factory.createMarketDataSnapshotRequestInstrument(Instrument, Timeframe, 300); DateTime DtFirst = DtTo; DateTime DatePrec = System.DateTime.MinValue; //TimeSpan PricesTimeSpan = System.TimeSpan.MinValue; //if (Interval == "m5") //{ // PricesTimeSpan = new TimeSpan(0, 0, 5, 0, 0); //} do // cause there is limit for returned candles amount { factory.fillMarketDataSnapshotRequestTime(request, DtFrom, DtFirst, false); m_responseListener.SetRequestID(request.RequestID); O2GSession.sendRequest(request); if (!m_responseListener.WaitEvents()) { throw new Exception("Response waiting timeout expired"); } // shift "to" bound to oldest datetime of returned data O2GResponse response = m_responseListener.GetResponse(); if (response != null && response.Type == O2GResponseType.MarketDataSnapshot) { O2GResponseReaderFactory readerFactory = O2GSession.getResponseReaderFactory(); if (readerFactory != null) { O2GMarketDataSnapshotResponseReader reader = readerFactory.createMarketDataSnapshotReader(response); if (reader.Count > 0) { if (DateTime.Compare(DtFirst, reader.getDate(0)) != 0) { DtFirst = reader.getDate(0); // earliest datetime of returned data for (int nData = reader.Count - 1; nData > -1; nData--) { if (reader.getDate(nData) != DatePrec) { m_datetime.Add(reader.getDate(nData)); m_ask.Add(reader.getAsk(nData)); m_askopen.Add(reader.getAskOpen(nData)); m_askclose.Add(reader.getAskClose(nData)); m_askhigh.Add(reader.getAskHigh(nData)); m_asklow.Add(reader.getAskLow(nData)); m_bid.Add(reader.getBid(nData)); m_bidopen.Add(reader.getBidOpen(nData)); m_bidclose.Add(reader.getBidClose(nData)); m_bidhigh.Add(reader.getBidHigh(nData)); m_bidlow.Add(reader.getBidLow(nData)); } //else //{ // break; //} DatePrec = reader.getDate(nData); } } else { break; } } else { Console.WriteLine("0 rows received"); break; } } // PrintPrices(session, response); } else { break; } } while (DtFirst > DtFrom); m_datetime.Reverse(); m_ask.Reverse(); m_askopen.Reverse(); m_askclose.Reverse(); m_askhigh.Reverse(); m_asklow.Reverse(); m_bid.Reverse(); m_bidopen.Reverse(); m_bidclose.Reverse(); m_bidhigh.Reverse(); m_bidlow.Reverse(); }
/// <summary> /// Request historical prices for the specified timeframe of the specified period /// and then show live prices. /// </summary> /// <param name="communicator">The price history communicator.</param> /// <param name="instrument">The instrument.</param> /// <param name="timeframe">The timeframe.</param> /// <param name="from">From-date.</param> /// <param name="to">To-date</param> /// <param name="quotesCount">The quotes count.</param> /// <param name="responseListener">The response listener.</param> /// <param name="session">The trading session.</param> /// <param name="sessionListener">The trading session listener.</param> public static void GetLivePrices(IPriceHistoryCommunicator communicator, string instrument, string timeframe, DateTime from, DateTime to, int quotesCount, ResponseListener responseListener, O2GSession session, SessionStatusListener sessionListener) { if (!communicator.isReady()) { Console.WriteLine("History communicator is not ready."); return; } // create timeframe entity ITimeframeFactory timeframeFactory = communicator.TimeframeFactory; O2GTimeframe timeframeObj = timeframeFactory.create(timeframe); // check timeframe for ticks if (O2GTimeframeUnit.Tick == timeframeObj.Unit) { throw new Exception("Application works only for bars. Don't use tick as timeframe."); } // load Offers table and start ticks listening PriceUpdateController priceUpdateController = new PriceUpdateController(session, instrument); if (!priceUpdateController.Wait()) { return; } // create period collection bool alive = true; PeriodCollection periods = new PeriodCollection(instrument, timeframe, alive, priceUpdateController); PeriodCollectionUpdateObserver livePriceViewer = new PeriodCollectionUpdateObserver(periods); // create and send a history request IPriceHistoryCommunicatorRequest request = communicator.createRequest(instrument, timeframeObj, from, to, quotesCount); responseListener.SetRequest(request); communicator.sendRequest(request); // wait results responseListener.Wait(); IPriceHistoryCommunicatorResponse response = responseListener.GetResponse(); O2GMarketDataSnapshotResponseReader reader = communicator.createResponseReader(response); if (response != null) { ProcessHistoricalPrices(communicator, response, ref periods); } // finally notify the collection that all bars are added, so it can // add all ticks collected while the request was being executed // and start update the data by forthcoming ticks periods.Finish(reader.getLastBarTime(), reader.getLastBarVolume()); // continue update the data until cancelled by a user Console.WriteLine("\nPress ENTER to cancel.\n\n"); Console.ReadKey(); livePriceViewer.Unsubscribe(); priceUpdateController.Unsubscribe(); }
private static void GetHistoryPrices(O2GSession session, string sInstrument, string sTimeframe, DateTime dtFrom, DateTime dtTo, ResponseListener responseListener) { try { StreamWriter m_data = new StreamWriter(OutData); string m_string_to_write = ""; O2GRequestFactory factory = session.getRequestFactory(); O2GTimeframe timeframe = factory.Timeframes[sTimeframe]; if (timeframe == null) { throw new Exception(string.Format("Timeframe '{0}' is incorrect!", sTimeframe)); } O2GRequest request = factory.createMarketDataSnapshotRequestInstrument(sInstrument, timeframe, 300); DateTime dtFirst = dtTo; do // cause there is limit for returned candles amount { factory.fillMarketDataSnapshotRequestTime(request, dtFrom, dtFirst, false); responseListener.SetRequestID(request.RequestID); session.sendRequest(request); if (!responseListener.WaitEvents()) { throw new Exception("Response waiting timeout expired"); } // shift "to" bound to oldest datetime of returned data O2GResponse response = responseListener.GetResponse(); if (response != null && response.Type == O2GResponseType.MarketDataSnapshot) { O2GResponseReaderFactory readerFactory = session.getResponseReaderFactory(); if (readerFactory != null) { O2GMarketDataSnapshotResponseReader reader = readerFactory.createMarketDataSnapshotReader(response); if (reader.Count > 0) { if (DateTime.Compare(dtFirst, reader.getDate(0)) != 0) { dtFirst = reader.getDate(0); // earliest datetime of returned data for (int nData = reader.Count - 1; nData > -1; nData--) { // reader.getDate(0); m_string_to_write = reader.getDate(nData).ToString() + ";" + reader.getAsk(nData).ToString() + ";" + reader.getAskOpen(nData).ToString() + ";" + reader.getAskClose(nData).ToString() + ";" + reader.getAskLow(nData).ToString() + ";" + reader.getAskHigh(nData).ToString() + ";" + reader.getBid(nData).ToString() + ";" + reader.getBidOpen(nData).ToString() + ";" + reader.getBidClose(nData).ToString() + ";" + reader.getBidLow(nData).ToString() + ";" + reader.getBidHigh(nData).ToString() + ";" + reader.getVolume(nData).ToString() + ";" + reader.getLastBarTime().ToString() + ";" + reader.getLastBarVolume().ToString(); m_data.WriteLine(m_string_to_write); } } else { break; } } else { Console.WriteLine("0 rows received"); break; } } // PrintPrices(session, response); } else { break; } } while (dtFirst > dtFrom); m_data.Close(); } catch (Exception e) { int ErrorCounter = 0; if (ErrorCounter > 5) { LogDirector.DoAction(4, e); } else { ErrorCounter++; LogDirector.DoAction(2, e); GetHistoryPrices(session, sInstrument, sTimeframe, dtFrom, dtTo, responseListener); } } }
/// <summary> /// Fetches historical data from FXCM server /// </summary> /// <param name="historicDataRequest"></param> public void GetHistoricalData(HistoricDataRequest historicDataRequest) { // Create a new factory O2GRequestFactory factory = _session.getRequestFactory(); // Get time frame O2GTimeframe timeframe = factory.Timeframes[GetFxcmTimeFrame(historicDataRequest)]; if (timeframe == null) { _logger.Error("Invalid time format", _type.FullName, "GetHistoricalData"); return; } // Clear any existing data _barCollection.Clear(); // Request historical snapshot O2GRequest request = factory.createMarketDataSnapshotRequestInstrument(historicDataRequest.Security.Symbol, timeframe, 300); DateTime endTime = historicDataRequest.EndTime; do // cause there is limit for returned candles amount { factory.fillMarketDataSnapshotRequestTime(request, historicDataRequest.StartTime, endTime, false); SetRequestId(request.RequestID); _session.sendRequest(request); if (!WaitEvents()) { _logger.Error("Response waiting timeout expired", _type.FullName, "GetHistoricalData"); return; } // Shift "to" bound to oldest datetime of returned data O2GResponse response = GetResponse(); if (response != null && response.Type == O2GResponseType.MarketDataSnapshot) { O2GResponseReaderFactory readerFactory = _session.getResponseReaderFactory(); if (readerFactory != null) { O2GMarketDataSnapshotResponseReader reader = readerFactory.createMarketDataSnapshotReader(response); if (reader.Count > 0) { if (DateTime.Compare(endTime, reader.getDate(0)) != 0) { endTime = reader.getDate(0); // earliest datetime of returned data } else { break; } } else { if (_logger.IsInfoEnabled) { _logger.Info("Response waiting timeout expired", _type.FullName, "GetHistoricalData"); } break; } } ExtractPrices(_session, response, historicDataRequest); } else { break; } } while (endTime > historicDataRequest.StartTime); if (_barCollection.Count > 0) { if (_historicalDataEvent != null) { _barCollection.Reverse(); // Create historical data object var historicalData = new HistoricBarData(historicDataRequest.Security, historicDataRequest.MarketDataProvider, DateTime.UtcNow); historicalData.Bars = _barCollection.ToArray(); historicalData.ReqId = historicDataRequest.Id; // Raise Event _historicalDataEvent(historicalData); } _barCollection.Clear(); } }