public DataEditWindow(Instrument instrument) { InitializeComponent(); DataContext = this; Data = new ObservableCollection<OHLCBar>(); //grab and update the instrument using (var context = new MyDBContext()) { context.Instruments.Attach(instrument); context.Entry(instrument).Reload(); TheInstrument = instrument; } StartTime = new DateTime(1950, 1, 1, 0, 0, 0, 0); EndTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0, 0); if (!TheInstrument.ID.HasValue) return; //grab the data info using (var localStorage = new MySQLStorage()) { var storageInfo = localStorage.GetStorageInfo(TheInstrument.ID.Value); if (storageInfo.Count == 0) //if it doesn't have any data, we just exit { MessageBox.Show("This instrument has no data."); Hide(); } else { foreach (StoredDataInfo s in storageInfo) //fill the resolution box { ResolutionComboBox.Items.Add(s.Frequency); } } } }
private void LoadDataBtn_Click(object sender, RoutedEventArgs e) { Data.Clear(); //grab the data using (var localStorage = new MySQLStorage()) { var tzInfo = TimeZoneInfo.FindSystemTimeZoneById(TheInstrument.Exchange.Timezone); var bars = localStorage.GetData(TheInstrument, StartTime, EndTime, (BarSize)ResolutionComboBox.SelectedItem); foreach (OHLCBar b in bars) { //do any required time zone coversions if (TimezoneComboBox.Text == "UTC") { b.DT = TimeZoneInfo.ConvertTimeToUtc(b.DT, tzInfo); } else if (TimezoneComboBox.Text == "Local") { b.DT = TimeZoneInfo.ConvertTime(b.DT, TimeZoneInfo.Local, tzInfo); } Data.Add(b); } _loadedFrequency = (BarSize)ResolutionComboBox.SelectedItem; } StatusLabel.Content = string.Format("Loaded {0} Bars", Data.Count); }
private void DeleteBtn_Click(object sender, RoutedEventArgs e) { //get the selected bars var rows = DataGrid.SelectedItems; if (rows.Count < 0) return; var result = MessageBox.Show(string.Format("Are you sure you want to delete {0} rows?", rows.Count), "Delete Rows", MessageBoxButton.YesNo); if (result == MessageBoxResult.No) return; var toDelete = rows.Cast<OHLCBar>().ToList(); using (var localStorage = new MySQLStorage()) { localStorage.DeleteData(TheInstrument, _loadedFrequency, toDelete); } foreach (OHLCBar bar in toDelete) { Data.Remove(bar); } }
//check the latest date we have available in local storage, then request historical data from that date to the current time 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 = new MySQLStorage()) { 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, true, false, true)); requestCount++; } } } if (_progressBar.Value >= _progressBar.Maximum) { _progressBar.Maximum = requestCount; _progressBar.Value = 0; } else { _progressBar.Maximum += requestCount; } }
//delete one or more instruments private void DeleteInstrumentBtn_ItemClick(object sender, RoutedEventArgs routedEventArgs) { using (var entityContext = new MyDBContext()) { var selectedInstruments = InstrumentsGrid.SelectedItems; if (selectedInstruments.Count == 0) return; if (selectedInstruments.Count == 1) { var inst = (Instrument)selectedInstruments[0]; MessageBoxResult res = MessageBox.Show(string.Format("Are you sure you want to delete {0} @ {1}?", inst.Symbol, inst.Datasource.Name), "Delete", MessageBoxButton.YesNo); if (res == MessageBoxResult.No) return; } else { MessageBoxResult res = MessageBox.Show(string.Format("Are you sure you want to delete {0} instruments?", selectedInstruments.Count), "Delete", MessageBoxButton.YesNo); if (res == MessageBoxResult.No) return; } List<Instrument> toRemove = new List<Instrument>(); foreach (Instrument i in InstrumentsGrid.SelectedItems) { entityContext.Instruments.Attach(i); entityContext.Instruments.Remove(i); toRemove.Add(i); } using (var localStorage = new MySQLStorage()) { localStorage.Connect(); while (toRemove.Count > 0) { Instruments.Remove(toRemove[toRemove.Count - 1]); localStorage.DeleteAllInstrumentData(toRemove[toRemove.Count - 1]); toRemove.RemoveAt(toRemove.Count - 1); } } entityContext.SaveChanges(); } }
//delete data from selected instruments private void ClearDataBtn_ItemClick(object sender, RoutedEventArgs routedEventArgs) { var selectedInstruments = InstrumentsGrid.SelectedItems; if (selectedInstruments.Count == 0) return; if (selectedInstruments.Count == 1) { var inst = (Instrument)selectedInstruments[0]; MessageBoxResult res = MessageBox.Show(string.Format("Are you sure you want to delete all data from {0} @ {1}?", inst.Symbol, inst.Datasource.Name), "Delete", MessageBoxButton.YesNo); if (res == MessageBoxResult.No) return; } else { MessageBoxResult res = MessageBox.Show(string.Format("Are you sure you want to delete all data from {0} instruments?", selectedInstruments.Count), "Delete", MessageBoxButton.YesNo); if (res == MessageBoxResult.No) return; } using (var storage = new MySQLStorage()) { foreach (Instrument i in selectedInstruments) { try { storage.DeleteAllInstrumentData(i); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } StatusBarLabel.Content = "Instrument data deleted"; }
private void ImportBtn_Click(object sender, RoutedEventArgs e) { Stopwatch 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 ((BarSize)FrequencyComboBox.SelectedItem < 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; } //todo make sure the user has picked the right frequency var tzInfo = TimeZoneInfo.FindSystemTimeZoneById(_instrument.Exchange.Timezone); //get the multipliers decimal priceMultiplier; int volumeMultiplier; bool parseWorked = decimal.TryParse(PriceMultiplier.Text, out priceMultiplier); if (!parseWorked) priceMultiplier = 1; parseWorked = int.TryParse(VolumeMultiplier.Text, out volumeMultiplier); if (!parseWorked) volumeMultiplier = 1; //lines to skip int toSkip; parseWorked = int.TryParse(StartingLine.Text, out toSkip); if(!parseWorked) toSkip = 1; //get the frequency var frequency = (BarSize)FrequencyComboBox.SelectedItem; //separator char[] separator = DelimiterBox.Text.ToCharArray(); List<OHLCBar> bars = new List<OHLCBar>(); string[] columns = new string[Data.Columns.Count]; for (int 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 Dictionary<int, TimeSpan> sessionEndTimes = new Dictionary<int, TimeSpan>(); //1 day and up: we can load it all in one go with no trouble, also may require adjustment bool periodicSaving = frequency < BarSize.OneDay; OHLCBar bar; var barsCount = 0; using (StreamReader sr = new StreamReader(FilePathTextBox.Text)) { 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.DT >= MinDT.Value && bar.DT <= MaxDT.Value) { bars.Add(bar); } 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 = new MySQLStorage()) { try { storage.AddData(bars, _instrument, frequency, OverwriteCheckbox.IsChecked.HasValue && OverwriteCheckbox.IsChecked.Value, 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 (DayOfTheWeek 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)); } } for (int i = 0; i < bars.Count; i++) { int dayOfWeek = bars[i].DT.DayOfWeek.ToInt(); bars[i].DT = bars[i].DT.Date + sessionEndTimes[dayOfWeek]; } } //if there are no dividends/splits, but there IS an adjclose column, use that to adjust data right here //if there are divs/splits, adjustment will be done by the local storage if (frequency >= BarSize.OneDay && !Data.Columns.Contains("Dividends") && !Data.Columns.Contains("Splits") && Data.Columns.Contains("AdjClose")) { //if we have an adjusted close to work off of, we just use the ratio to get the OHL for (int i = 0; i < bars.Count; i++) { if (bars[i].AdjClose == null) continue; decimal ratio = bars[i].AdjClose.Value / bars[i].Close; bars[i].AdjOpen = bars[i].Open * ratio; bars[i].AdjHigh = bars[i].High * ratio; bars[i].AdjLow = bars[i].Low * ratio; } } //sort by date if(frequency >= BarSize.OneDay) bars.Sort((x, y) => x.DT.CompareTo(y.DT)); //try to import using (var storage = new MySQLStorage()) { try { storage.AddData(bars, _instrument, frequency, OverwriteCheckbox.IsChecked.HasValue && OverwriteCheckbox.IsChecked.Value, frequency >= BarSize.OneDay); } catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); } } sw.Stop(); MessageBox.Show(string.Format("Imported {0} bars in {1} ms.", barsCount, sw.ElapsedMilliseconds)); }