public void HistoricalDataRequestsAreForwardedToTheBroker() { var instrument = new Instrument { ID = 1, Symbol = "SPY", Datasource = new Datasource { ID = 1, Name = "MockSource" }, Exchange = new Exchange { ID = 1, Name = "Exchange", Timezone = "Eastern Standard Time" } }; var request = new HistoricalDataRequest(instrument, BarSize.OneDay, new DateTime(2012, 1, 1), new DateTime(2013, 1, 1)); _client.RequestHistoricalData(request); // TODO: Think about delay amount Thread.Sleep(1500); _historicalDataBrokerMock.Verify( x => x.RequestHistoricalData( It.Is <HistoricalDataRequest>( r => r.Instrument.ID == 1 && r.Frequency == BarSize.OneDay && r.StartingDate == new DateTime(2012, 1, 1) && r.EndingDate == new DateTime(2013, 1, 1))), Times.Once); }
public decimal?GetLastPrice(EntityModel.Instrument instrument, out DateTime lastDate) { lastDate = new DateTime(1, 1, 1); var qdmsInst = instrument.GetQDMSInstrument(_instrumentsList); if (qdmsInst == null || !qdmsInst.ID.HasValue) { return(null); } StoredDataInfo dataInfo = TryGetStorageInfo(qdmsInst); if (dataInfo == null) { return(null); } var lastAvailableDate = dataInfo.LatestDate; //Send out the request for the data var req = new HistoricalDataRequest { Instrument = qdmsInst, StartingDate = lastAvailableDate.AddDays(-1), EndingDate = lastAvailableDate, Frequency = BarSize.OneDay, DataLocation = _allowFreshData ? DataLocation.Both : DataLocation.LocalOnly, RTHOnly = true, SaveDataToStorage = false }; var id = _client.RequestHistoricalData(req); _requestIDs.Add(id, false); //Wait until the data arrives int i = 0; while (i < 100) { Thread.Sleep(20); lock (_arrivedDataLock) { if (_requestIDs[id]) { var data = _arrivedData[qdmsInst.ID.Value].Last(); _arrivedData.Remove(qdmsInst.ID.Value); lastDate = data.DT; return(data.Close); } } i++; } return(null); }
private static void Main() { //create the client, assuming the default port settings using (var client = new QDMSClient.QDMSClient("SampleClient", "127.0.0.1", 5556, 5557, 5558, 5555)) { //hook up the events needed to receive data & error messages client.HistoricalDataReceived += client_HistoricalDataReceived; client.RealTimeDataReceived += client_RealTimeDataReceived; client.LocallyAvailableDataInfoReceived += client_LocallyAvailableDataInfoReceived; client.Error += client_Error; //connect to the server client.Connect(); //make sure the connection was succesful before we continue if (!client.Connected) { Console.WriteLine("Could not connect."); Console.WriteLine("Press enter to exit."); Console.ReadLine(); return; } //request the list of available instruments var instruments = client.FindInstruments(); foreach (var i in instruments) { Console.WriteLine($"Instrument ID {i.ID}: {i.Symbol} ({i.Type}), Datasource: {i.Datasource.Name}"); } Thread.Sleep(3000); //then we grab some historical data from Yahoo //start by finding the SPY instrument var spy = instruments.FirstOrDefault(x => x.Symbol == "SPY" && x.Datasource.Name == "Yahoo"); if (spy != null) { var req = new HistoricalDataRequest( spy, BarSize.OneDay, new DateTime(2013, 1, 1), new DateTime(2013, 1, 15)); client.RequestHistoricalData(req); Thread.Sleep(3000); //now that we downloaded the data, let's make a request to see what is stored locally client.GetLocallyAvailableDataInfo(spy); Thread.Sleep(3000); //finally send a real time data request (from the simulated data datasource) spy.Datasource.Name = "SIM"; var rtReq = new RealTimeDataRequest(spy, BarSize.OneSecond); client.RequestRealTimeData(rtReq); Thread.Sleep(3000); //And then cancel the real time data stream client.CancelRealTimeData(spy); } Console.WriteLine("Press enter to exit."); Console.ReadLine(); } }
public void RequestHistoricalDataRaisesErrorEventAndReturnsMinusOneWhenDatesAreWrong() { var req = new HistoricalDataRequest { Instrument = new Instrument { ID = 1, Symbol = "SPY" }, StartingDate = new DateTime(2012, 1, 1), EndingDate = new DateTime(2011, 1, 1), Frequency = BarSize.OneDay }; bool errorTriggered = false; _client.Error += (sender, e) => errorTriggered = true; Assert.AreEqual(-1, _client.RequestHistoricalData(req)); Assert.IsTrue(errorTriggered); }
private void LoadDataBtn_Click(object sender, RoutedEventArgs e) { Data.Clear(); DateTime start = StartDate + StartTime.TimeOfDay; DateTime end = EndDate + EndTime.TimeOfDay; _client.RequestHistoricalData(new HistoricalDataRequest( TheInstrument, (BarSize)ResolutionComboBox.SelectedItem, start, end, dataLocation: (DataLocation)DataLocationComboBox.SelectedItem, saveToLocalStorage: SaveToLocalStorageCheckBox.IsChecked ?? true, rthOnly: RTHOnlyCheckBox.IsChecked ?? true)); }
//check the latest date we have available in local storage, then request historical data from that date to the current time private void UpdateHistoricalDataBtn_ItemClick(object sender, RoutedEventArgs routedEventArgs) { var frequency = (BarSize)((MenuItem)sender).Tag; List <Instrument> selectedInstruments = InstrumentsGrid.SelectedItems.Cast <Instrument>().ToList(); int requestCount = 0; using (var localStorage = DataStorageFactory.Get()) { foreach (Instrument i in selectedInstruments) { if (!i.ID.HasValue) { continue; } var storageInfo = localStorage.GetStorageInfo(i.ID.Value); if (storageInfo.Any(x => x.Frequency == frequency)) { var relevantStorageInfo = storageInfo.First(x => x.Frequency == frequency); _client.RequestHistoricalData(new HistoricalDataRequest( i, frequency, relevantStorageInfo.LatestDate + frequency.ToTimeSpan(), DateTime.Now, dataLocation: DataLocation.ExternalOnly, saveToLocalStorage: true)); requestCount++; } } } if (_progressBar.Value >= _progressBar.Maximum) { _progressBar.Maximum = requestCount; _progressBar.Value = 0; } else { _progressBar.Maximum += requestCount; } }
static void Main() { //create the client, assuming the default port settings QDMSClient.QDMSClient client = new QDMSClient.QDMSClient( "SampleClient", "127.0.0.1", 5556, 5557, 5558, 5555); //hook up the events needed to receive data & error messages client.HistoricalDataReceived += client_HistoricalDataReceived; client.RealTimeDataReceived += client_RealTimeDataReceived; client.LocallyAvailableDataInfoReceived += client_LocallyAvailableDataInfoReceived; client.Error += client_Error; //connect to the server client.Connect(); //make sure the connection was succesful before we continue if (!client.Connected) { Console.WriteLine("Could not connect."); Console.WriteLine("Press enter to exit."); Console.ReadLine(); return; } //request the list of available instruments List<Instrument> instruments = client.FindInstruments(); foreach (Instrument i in instruments) { Console.WriteLine("Instrument ID {0}: {1} ({2}), Datasource: {3}", i.ID, i.Symbol, i.Type, i.Datasource.Name); } Thread.Sleep(3000); //then we grab some historical data from Yahoo //start by finding the SPY instrument var spy = client.FindInstruments(x => x.Symbol == "SPY" && x.Datasource.Name == "Yahoo").FirstOrDefault(); if (spy != null) { var req = new HistoricalDataRequest( spy, BarSize.OneDay, new DateTime(2013, 1, 1), new DateTime(2013, 1, 15), dataLocation: DataLocation.Both, saveToLocalStorage: true, rthOnly: true); client.RequestHistoricalData(req); Thread.Sleep(3000); //now that we downloaded the data, let's make a request to see what is stored locally client.GetLocallyAvailableDataInfo(spy); Thread.Sleep(3000); //finally send a real time data request (from the simulated data datasource) spy.Datasource.Name = "SIM"; var rtReq = new RealTimeDataRequest(spy, BarSize.OneSecond); client.RequestRealTimeData(rtReq); Thread.Sleep(3000); //And then cancel the real time data stream client.CancelRealTimeData(spy); } Console.WriteLine("Press enter to exit."); Console.ReadLine(); client.Disconnect(); client.Dispose(); }
/// <summary> /// Called by the <see cref="T:Quartz.IScheduler"/> when a <see cref="T:Quartz.ITrigger"/> /// fires that is associated with the <see cref="T:Quartz.IJob"/>. /// </summary> /// <remarks> /// The implementation may wish to set a result object on the /// JobExecutionContext before this method exits. The result itself /// is meaningless to Quartz, but may be informative to /// <see cref="T:Quartz.IJobListener"/>s or /// <see cref="T:Quartz.ITriggerListener"/>s that are watching the job's /// execution. /// </remarks> /// <param name="context">The execution context.</param> public void Execute(IJobExecutionContext context) { _logger = LogManager.GetCurrentClassLogger(); JobDataMap dataMap = context.JobDetail.JobDataMap; var details = (DataUpdateJobDetails)dataMap["details"]; _jobName = details.Name; Log(LogLevel.Info, string.Format("Data Update job {0} triggered.", details.Name)); //Multiple jobs may be called simultaneously, so what we do is seed the Random based on the job name byte[] bytes = new byte[details.Name.Length * sizeof(char)]; System.Buffer.BlockCopy(details.Name.ToCharArray(), 0, bytes, 0, bytes.Length); var r = new Random((int)DateTime.Now.TimeOfDay.TotalSeconds ^ BitConverter.ToInt32(bytes, 0)); var im = new InstrumentManager(); List<Instrument> instruments = details.UseTag ? im.FindInstruments(pred: x => x.Tags.Any(y => y.ID == details.TagID)) : im.FindInstruments(pred: x => x.ID == details.InstrumentID); if (instruments.Count == 0) { Log(LogLevel.Error, string.Format("Aborting data update job {0}: no instruments found.", details.Name)); return; } using (var client = new QDMSClient.QDMSClient( "DataUpdateJobClient" + r.Next().ToString(), "127.0.0.1", Properties.Settings.Default.rtDBReqPort, Properties.Settings.Default.rtDBPubPort, Properties.Settings.Default.instrumentServerPort, Properties.Settings.Default.hDBPort)) { //try to connect try { client.Connect(); } catch (Exception ex) { Log(LogLevel.Error, string.Format("Aborting data update job {0}: connection error {1}", details.Name, ex.Message)); return; } //Hook up the error event, we want to log that stuff client.Error += client_Error; //What we do here: we check what we have available locally.. //If there is something, we send a query to grab data between the last stored time and "now" //Otherwise we send a query to grab everything since 1900 using (var localStorage = DataStorageFactory.Get()) { foreach (Instrument i in instruments) { if (!i.ID.HasValue) continue; //don't request data on expired securities unless the expiration was recent if (i.Expiration.HasValue && (DateTime.Now - i.Expiration.Value).TotalDays > 15) { Log(LogLevel.Trace, string.Format("Data update job {0}: ignored instrument w/ ID {1} due to expiration date.", details.Name, i.ID)); continue; } DateTime startingDT = new DateTime(1900, 1, 1); var storageInfo = localStorage.GetStorageInfo(i.ID.Value); if (storageInfo.Any(x => x.Frequency == details.Frequency)) { var relevantStorageInfo = storageInfo.First(x => x.Frequency == details.Frequency); startingDT = relevantStorageInfo.LatestDate; } client.RequestHistoricalData(new HistoricalDataRequest( i, details.Frequency, startingDT, DateTime.Now, //TODO this should be in the instrument's timezone... forceFreshData: true, localStorageOnly: false, saveToLocalStorage: true, rthOnly: true)); } } //Requests aren't sent immediately so wait before killing the client to make sure the request gets to the server Thread.Sleep(50); client.Disconnect(); } Log(LogLevel.Info, string.Format("Data Update job {0} completed.", details.Name)); }