/// <summary> /// Read the next line of data to import. /// </summary> /// <returns>TRUE: line read successfully. FALSE: stop reading data from that file, move to next import file.</returns> public override bool NextDataPoint() { if (reader == null) { return(false); } while (true) { CurrentData = reader.ReadLine(); if (CurrentData == null) { try { reader.Close(); } catch {}; reader = null; return(false); } CurrentData = CurrentData.Trim(); if (CurrentData.Length == 0) { continue; } if (firstLine) { separator = string.Empty; foreach (string separatorTmp in new string[] { ";", "," }) { if (new Regex(separatorTmp + "\"?[^" + separatorTmp + "]+\"?" + separatorTmp).Match(CurrentData).Success) { separator = separatorTmp; break; } } if (separator.Length == 0) { Cbi.LogEventArgs.ProcessEventArgs(new Cbi.LogEventArgs(Instrument.FullName + ": Import field separator could not be identified.", Cbi.LogLevel.Error)); try { reader.Close(); } catch {}; reader = null; throw new ApplicationException(); } regex = new Regex("\"?[^" + separator + "]+\"?"); firstLine = false; } MatchCollection matches = regex.Matches(CurrentData); if (matches.Count == 0) // skip to next lines if current line is empty { continue; } // skip to next line if first char is not a digit string timeField = matches[0].Value.Trim(quotes).Trim().Replace("-", string.Empty).Replace(":", string.Empty).Replace(" ", string.Empty); if (timeField.Length == 0 || !char.IsDigit(timeField[0])) { continue; } if (matches.Count < 6 && matches.Count != 3) { Cbi.LogEventArgs.ProcessEventArgs(new Cbi.LogEventArgs(Instrument.FullName + ": Unexpected number of fields in line '" + (DataPoints + 1) + "', should be 6 or 3", Cbi.LogLevel.Error)); try { reader.Close(); } catch {}; reader = null; throw new ApplicationException(); } // set actual PeriodType on reading the first line of data if (DataPoints == 0) { if (matches.Count >= 6 && timeField.Length == 8) { PeriodType = Data.PeriodType.Day; } else if (matches.Count >= 6 && (timeField.Length == 12 || timeField.Length == 14)) { PeriodType = Data.PeriodType.Minute; } else if (matches.Count == 3 && timeField.Length == 14) { PeriodType = Data.PeriodType.Tick; } } Time = Cbi.Globals.MinDate; try { if (PeriodType == Data.PeriodType.Day) { Time = new DateTime(Convert.ToInt32(timeField.Substring(0, 4)), Convert.ToInt32(timeField.Substring(4, 2)), Convert.ToInt32(timeField.Substring(6, 2))); } else if (PeriodType == Data.PeriodType.Minute) { Time = new DateTime(Convert.ToInt32(timeField.Substring(0, 4)), Convert.ToInt32(timeField.Substring(4, 2)), Convert.ToInt32(timeField.Substring(6, 2)), Convert.ToInt32(timeField.Substring(8, 2)), Convert.ToInt32(timeField.Substring(10, 2)), 0); if (!EndOfBarTimestamps) { Time = Time.AddMinutes(1); } } else if (PeriodType == Data.PeriodType.Tick) { Time = new DateTime(Convert.ToInt32(timeField.Substring(0, 4)), Convert.ToInt32(timeField.Substring(4, 2)), Convert.ToInt32(timeField.Substring(6, 2)), Convert.ToInt32(timeField.Substring(8, 2)), Convert.ToInt32(timeField.Substring(10, 2)), Convert.ToInt32(timeField.Substring(12, 2))); } } catch (Exception exp) { Cbi.LogEventArgs.ProcessEventArgs(new Cbi.LogEventArgs(Instrument.FullName + ": Time/Time format error in line " + (DataPoints + 1) + ": " + exp.Message + ": '" + CurrentData + "'", Cbi.LogLevel.Error)); try { reader.Close(); } catch {}; reader = null; throw new ApplicationException(); } if (cultureInfo == null) { ArrayList cultureInfos = new ArrayList(); CultureInfo tmp = null; try { tmp = new CultureInfo("en-US"); cultureInfos.Add(tmp); } catch {}; try { tmp = (CultureInfo)Cbi.Globals.CurrentCulture.Clone(); cultureInfos.Add(tmp); } catch {}; try { tmp = new CultureInfo("de-DE"); cultureInfos.Add(tmp); } catch {}; foreach (CultureInfo cultureInfoTmp in cultureInfos) { // turn of number grouping, since the number grouping character could be a decimal separator for a different culture cultureInfoTmp.NumberFormat.NumberGroupSeparator = string.Empty; try { Open = Convert.ToDouble(matches[1].Value.Trim(quotes).Trim(), cultureInfoTmp); cultureInfo = cultureInfoTmp; break; } catch {} } if (cultureInfo == null) { Cbi.LogEventArgs.ProcessEventArgs(new Cbi.LogEventArgs(Instrument.FullName + ": Numeric price format not supported.", Cbi.LogLevel.Error)); try { reader.Close(); } catch {}; reader = null; throw new ApplicationException(); } } try { Open = Convert.ToDouble(matches[1].Value.Trim(quotes).Trim(), cultureInfo); High = (PeriodType == Data.PeriodType.Tick ? Open : Convert.ToDouble(matches[2].Value.Trim(quotes).Trim(), cultureInfo)); Low = (PeriodType == Data.PeriodType.Tick ? Open : Convert.ToDouble(matches[3].Value.Trim(quotes).Trim(), cultureInfo)); Close = (PeriodType == Data.PeriodType.Tick ? Open : Convert.ToDouble(matches[4].Value.Trim(quotes).Trim(), cultureInfo)); Volume = Convert.ToInt64(matches[PeriodType == Data.PeriodType.Tick ? 2 : 5].Value.Trim(quotes).Trim(), cultureInfo); return(true); } catch (Exception exp) { Cbi.LogEventArgs.ProcessEventArgs(new Cbi.LogEventArgs(Instrument.FullName + ": Format error in line " + (DataPoints + 1) + ": " + exp.Message + ": '" + CurrentData + "'", Cbi.LogLevel.Error)); try { reader.Close(); } catch {}; reader = null; throw new ApplicationException(); } // keep going until finally 1 line of data was read } }