private void Save() { using (var localStorage = DataStorageFactory.Get()) { try { localStorage.UpdateData(Data.ToList(), TheInstrument, loadedBarsize, true); MessageBox.Show("Successfully updated data."); } catch (Exception ex) { MessageBox.Show("Error while updating data: " + ex.Message); } } }
public DataEditViewModel(Instrument instrument) { TheInstrument = instrument; var timezone = TheInstrument.Exchange == null ? "UTC" : TheInstrument.Exchange.Timezone; timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(timezone); //grab the data info using (var localStorage = DataStorageFactory.Get()) { var storageInfo = localStorage.GetStoredDataInfo(TheInstrument.ID); if (storageInfo.Count == 0) //if it doesn't have any data, we just exit { MessageBox.Show("This instrument has no data."); CloseCommand.Execute(); } else { BarSizes = new ReactiveList <BarSize>(); foreach (var s in storageInfo) { BarSizes.Add(s.Frequency); } } } Data = new ReactiveList <OHLCBar>(); TheInstrument = instrument; StartTime = new DateTime(DateTime.Now.AddYears(-5).Year, 1, 1, 0, 0, 0, 0); StartDate = new DateTime(DateTime.Now.AddYears(-5).Year, 1, 1, 0, 0, 0, 0); EndTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0, 0); EndDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0, 0); LoadDataCommand = ReactiveCommand.Create(LoadData); ExportCommand = ReactiveCommand.Create(ExportData); DeleteCommand = ReactiveCommand.Create(Delete); SaveCommand = ReactiveCommand.Create(Save); }
private void ClearData() { if (selectedInstruments.Count == 0) { return; } if (selectedInstruments.Count == 1) { var inst = selectedInstruments[0]; MessageBoxResult res = MessageBox.Show( $"Are you sure you want to delete all data from {inst.Symbol} @ {inst.Datasource.Name}?", "Delete", MessageBoxButton.YesNo); if (res == MessageBoxResult.No) { return; } } else { MessageBoxResult res = MessageBox.Show( $"Are you sure you want to delete all data from {selectedInstruments.Count} instruments?", "Delete", MessageBoxButton.YesNo); if (res == MessageBoxResult.No) { return; } } using (var storage = DataStorageFactory.Get()) { foreach (Instrument i in selectedInstruments) { try { storage.DeleteAllInstrumentData(i); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } StatusBarLabel = "Instrument data deleted"; }
private void Delete() { //get the selected bars var rows = SelectedBars; if (rows == null || rows.Count == 0) { return; } var result = MessageBox.Show($"Are you sure you want to delete {rows.Count} rows?", "Delete Rows", MessageBoxButtons.YesNo); if (result == DialogResult.No) { return; } var toDelete = rows.ToList(); //data is stored in the db at exchange time. But we may have loaded it at UTC or local. //If so, we must convert it back. foreach (var b in toDelete) { if (loadedTimeZone == Timezone.Utc) { b.DateTimeClose = TimeZoneInfo.ConvertTimeFromUtc(b.DateTimeClose, timeZoneInfo); } else if (loadedTimeZone == Timezone.Local) { b.DateTimeClose = TimeZoneInfo.ConvertTime(b.DateTimeClose, TimeZoneInfo.Local, timeZoneInfo); } } using (var localStorage = DataStorageFactory.Get()) { localStorage.DeleteData(TheInstrument, loadedBarsize, toDelete); } foreach (var bar in toDelete) { Data.Remove(bar); } }
private void LoadData() { Data.Clear(); //grab the data using (var localStorage = DataStorageFactory.Get()) { if (BarSizes.Count == 1) { SelectedBarsize = BarSizes.FirstOrDefault(); } var bars = localStorage.GetData(TheInstrument, StartTime, EndTime, SelectedBarsize); //find largest significant decimal by sampling the prices at the start and end of the series var decPlaces = new List <int>(); for (var i = 0; i < Math.Min(bars.Count, 20); i++) { decPlaces.Add(bars[i].Open.CountDecimalPlaces()); decPlaces.Add(bars[bars.Count - 1 - i].Close.CountDecimalPlaces()); } foreach (var bar in bars) { //do any required time zone coversions if (SelectedTimezone == Timezone.Utc) { bar.DateTimeClose = TimeZoneInfo.ConvertTimeToUtc(bar.DateTimeClose, timeZoneInfo); } else if (SelectedTimezone == Timezone.Local) { bar.DateTimeClose = TimeZoneInfo.ConvertTime(bar.DateTimeClose, timeZoneInfo, TimeZoneInfo.Local); } var newBar = DataUtils.BarWithRoundedPrices(bar, decPlaces.Max()); Data.Add(newBar); } loadedBarsize = SelectedBarsize; loadedTimeZone = SelectedTimezone; } StatusLabelText = $"Loaded {Data.Count} Bars"; }
private void CreateBrokers() { var localStorage = DataStorageFactory.Get(); RealTimeBroker = new RealTimeDataBroker(localStorage, new IRealTimeDataSource[] { new IB(Settings.Default.ibClientHost, Settings.Default.ibClientPort, Settings.Default.rtdClientIBID) }); HistoricalBroker = new HistoricalDataBroker(localStorage, new IHistoricalDataSource[] { new IB(Settings.Default.ibClientHost, Settings.Default.ibClientPort, Settings.Default.histClientIBID), }); }
private void UpdateHistoricalData(BarSize barSize) { var frequency = barSize; //(BarSize) ((MenuItem) sender).Tag; int requestCount = 0; using (var localStorage = DataStorageFactory.Get()) { foreach (var instrument in selectedInstruments) { var storageInfo = localStorage.GetStoredDataInfo(instrument.ID); if (storageInfo.Any(x => x.Frequency == frequency)) { var relevantStorageInfo = storageInfo.First(x => x.Frequency == frequency); Client.RequestHistoricalData(new HistoricalDataRequest( instrument, frequency, relevantStorageInfo.LatestDate + frequency.ToTimeSpan(), DateTime.Now, DataLocation.ExternalOnly, true)); requestCount++; } } } if (ProgressBarValue >= ProgressBarMaximum) { ProgressBarMaximum = requestCount; ProgressBarValue = 0; } else { ProgressBarMaximum += requestCount; } }
private void ImportBtn_Click() { var sw = new Stopwatch(); sw.Start(); //check that we've got the relevant data needed if (!Data.Columns.Contains("Date") && !Data.Columns.Contains("DateTime")) { MessageBox.Show("Must have a date column."); return; } if (SelectedBarSize < BarSize.OneDay && !Data.Columns.Contains("DateTime") && !Data.Columns.Contains("Time")) { MessageBox.Show("Must have time column at this frequency"); return; } if (!Data.Columns.Contains("Open") || !Data.Columns.Contains("High") || !Data.Columns.Contains("Low") || !Data.Columns.Contains("Close")) { MessageBox.Show("Must have all OHLC columns."); return; } //make sure the timezone is set, and get it if (string.IsNullOrEmpty(_instrument.Exchange.Timezone)) { MessageBox.Show("Instrument's exchange has no set timezone, can't import."); return; } var tzInfo = TimeZoneInfo.FindSystemTimeZoneById(_instrument.Exchange.Timezone); //get the multipliers var parseWorked = decimal.TryParse(PriceMultiplier, out decimal priceMultiplier); if (!parseWorked) { priceMultiplier = 1; } parseWorked = int.TryParse(VolumeMultiplier, out int volumeMultiplier); if (!parseWorked) { volumeMultiplier = 1; } //lines to skip parseWorked = int.TryParse(StartingLine, out int toSkip); if (!parseWorked) { toSkip = 1; } //get the frequency var frequency = SelectedBarSize; //separator var separator = SelectedDelimeter.ToCharArray(); var bars = new List <OHLCBar>(); var columns = new string[Data.Columns.Count]; for (var i = 0; i < Data.Columns.Count; i++) { columns[i] = Data.Columns[i].ColumnName; } //determining time: if the freq is >= one day, then the time is simply the session end for this day var sessionEndTimes = new Dictionary <int, TimeSpan>(); //1 day and up: we can load it all in one go with no trouble, also may require adjustment var periodicSaving = frequency < BarSize.OneDay; OHLCBar bar; var barsCount = 0; using (var sr = new StreamReader(FilePath)) { string line; while ((line = sr.ReadLine()) != null) { barsCount++; if (barsCount < toSkip) { continue; } try { bar = ParseLine(line.Split(separator), columns, priceMultiplier, volumeMultiplier); } catch (Exception ex) { MessageBox.Show("Importing error: " + ex.Message); return; } //only add the bar if it falls within the specified date range if (bar.DateTimeClose >= MinDT && bar.DateTimeClose <= MaxDT) { bars.Add(bar); } //with 30 bars, we make a check to ensure that the user has entered the correct frequency if (bars.Count == 30) { //the reason we have to use a bunch of bars and look for the most frequent timespan between them //is that session breaks, daily breaks, weekends, etc. can have different timespans despite the //correct frequency being chosen var secDiffs = new List <int>(); for (var i = 1; i < bars.Count; i++) { secDiffs.Add( (int)Math.Round((bars[i].DateTimeClose - bars[i - 1].DateTimeClose).TotalSeconds)); } var mostFrequent = secDiffs.MostFrequent(); if ((int)Math.Round(frequency.ToTimeSpan().TotalSeconds) != mostFrequent) { MessageBox.Show("You appear to have selected the wrong frequency."); return; } } if (periodicSaving && bars.Count > 1000) { //convert to exchange timezone ConvertTimeZone(bars, tzInfo); //low frequencies, < 1 day. No adjustment required and inserting data at intervals instead of all at once using (var storage = DataStorageFactory.Get()) { try { storage.AddData(bars, _instrument, frequency, IsOverwrite, false); } catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); } } bars.Clear(); } } } if (bars.Count == 0) { return; } //convert to exchange timezone ConvertTimeZone(bars, tzInfo); //if only the date column is set, we need to get the session info and generate the closing time ourselves if (frequency >= BarSize.OneDay && !Data.Columns.Contains("Time") && !Data.Columns.Contains("DateTime")) { //get the closing time for every day of the week var dotwValues = MyUtils.GetEnumValues <DayOfTheWeek>(); foreach (var d in dotwValues) { if (_instrument.Sessions.Any(x => x.ClosingDay == d && x.IsSessionEnd)) { var endTime = _instrument.Sessions.First(x => x.ClosingDay == d && x.IsSessionEnd) .ClosingTime; sessionEndTimes.Add((int)d, endTime); } else { sessionEndTimes.Add((int)d, TimeSpan.FromSeconds(0)); } } foreach (var t in bars) { var dayOfWeek = t.DateTimeClose.DayOfWeek.ToInt(); t.DateTimeClose = t.DateTimeClose.Date + sessionEndTimes[dayOfWeek]; } } //sort by date if (frequency >= BarSize.OneDay) { bars.Sort((x, y) => x.DateTimeClose.CompareTo(y.DateTimeClose)); } //try to import using (var storage = DataStorageFactory.Get()) { try { storage.AddData(bars, _instrument, frequency, IsOverwrite, frequency >= BarSize.OneDay); } catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); } } sw.Stop(); MessageBox.Show($"Imported {barsCount} bars in {sw.ElapsedMilliseconds} ms."); }