public void Should_Parse(string cultureName) { // Arrange TestHelper.SetThreadCulture(cultureName); var csv = "2020-01-01 09:30:00,1.21,1.22,1.23,1.24,1000,1,100,1,12345.12345"; // Act var parsed = HistoricalBar.Parse(csv); // Assert Assert.AreEqual(parsed, _historicalBar); }
private static IEnumerable <HistoricalBar> ToHistoricalBarsUncompressedAscending(this IEnumerable <ITickMessage> tickMessages, TimeSpan interval) { var intervalTicks = interval.Ticks; var nextTimestamp = new DateTime(); HistoricalBar previousBar = null; foreach (var bar in tickMessages.ToHistoricalBars(interval, DataDirection.Oldest)) { if (bar.Timestamp != nextTimestamp && previousBar != null) { while (bar.Timestamp != nextTimestamp) { yield return(new HistoricalBar() { Timestamp = nextTimestamp, Open = previousBar.Close, High = previousBar.Close, Low = previousBar.Close, Close = previousBar.Close, PeriodVolume = 0, PeriodTrade = 0, TotalVolume = previousBar.TotalVolume, TotalTrade = previousBar.TotalTrade, VWAP = previousBar.Close }); nextTimestamp = nextTimestamp.AddTicks(intervalTicks); } } previousBar = bar; nextTimestamp = bar.Timestamp.AddTicks(intervalTicks); yield return(bar); } }
private static IEnumerable <HistoricalBar <double> > ToHistoricalBarsAscending(this IEnumerable <IIntervalMessage <double> > intervalMessages, TimeSpan timeInterval) { var intervalTicks = timeInterval.Ticks; DateTime?nextTimestamp = null; HistoricalBar <double> currentBar = null; var totalTrade = 0; foreach (var interval in intervalMessages) { if (interval.Timestamp < nextTimestamp) { totalTrade += interval.NumberOfTrades; if (interval.Low < currentBar.Low) { currentBar.Low = interval.Low; } if (interval.High > currentBar.High) { currentBar.High = interval.High; } currentBar.Close = interval.Close; currentBar.PeriodVolume += interval.PeriodVolume; currentBar.PeriodTrade += interval.NumberOfTrades; currentBar.TotalVolume = interval.TotalVolume; currentBar.TotalTrade = totalTrade; currentBar.Wap += (interval.High + interval.Low + interval.Close) / 3 * interval.PeriodVolume; // VWAP estimation continue; } if (currentBar != null) { // reset the counts if dates differ if (interval.Timestamp.Date != currentBar.Timestamp.Date) { totalTrade = 0; } currentBar.Wap = currentBar.Wap / currentBar.PeriodVolume; yield return(currentBar); } totalTrade += interval.NumberOfTrades; var currentTimestamp = interval.Timestamp.Trim(intervalTicks); nextTimestamp = currentTimestamp.AddTicks(intervalTicks); currentBar = new HistoricalBar <double>() { Timestamp = currentTimestamp, Open = interval.Open, High = interval.High, Low = interval.Low, Close = interval.Close, PeriodVolume = interval.PeriodVolume, PeriodTrade = interval.NumberOfTrades, TotalVolume = interval.TotalVolume, TotalTrade = totalTrade, Wap = (interval.High + interval.Low + interval.Close) / 3 * interval.PeriodVolume // VWAP estimation }; } // return the last created bar when last interval reached if (currentBar != null) { currentBar.Wap = currentBar.Wap / currentBar.PeriodVolume; yield return(currentBar); } }
private static IEnumerable <HistoricalBar> ToHistoricalBarsAscending(this IEnumerable <ITickMessage> tickMessages, TimeSpan interval) { var intervalTicks = interval.Ticks; DateTime? nextTimestamp = null; HistoricalBar currentBar = null; var totalVolume = 0; var totalTrade = 0; foreach (var tick in tickMessages) { // skip if trade size is zero if (tick.LastSize == 0) { continue; } totalVolume += tick.LastSize; totalTrade += 1; // to effect the price the trade must be C or E if (tick.BasisForLast == 'O') { continue; } if (tick.Timestamp < nextTimestamp) { if (tick.Last < currentBar.Low) { currentBar.Low = tick.Last; } if (tick.Last > currentBar.High) { currentBar.High = tick.Last; } currentBar.Close = tick.Last; currentBar.PeriodVolume += tick.LastSize; currentBar.PeriodTrade += 1; currentBar.TotalVolume = totalVolume; currentBar.TotalTrade = totalTrade; currentBar.VWAP += tick.Last * tick.LastSize; continue; } if (currentBar != null) { // reset the counts if dates differ if (tick.Timestamp.Date != currentBar.Timestamp.Date) { totalVolume = tick.LastSize; totalTrade = 1; } currentBar.VWAP = currentBar.VWAP / currentBar.PeriodVolume; yield return(currentBar); } var currentTimestamp = tick.Timestamp.Trim(intervalTicks); nextTimestamp = currentTimestamp.AddTicks(intervalTicks); currentBar = new HistoricalBar( currentTimestamp, tick.Last, tick.Last, tick.Last, tick.Last, totalVolume, tick.LastSize, totalTrade, 1, tick.Last * tick.LastSize); } // return the last created bar when last tick reached if (currentBar != null) { currentBar.VWAP = currentBar.VWAP / currentBar.PeriodVolume; yield return(currentBar); } }
private static IEnumerable <HistoricalBar> ToHistoricalBarsAscending(this IEnumerable <ITickMessage> tickMessages, TimeSpan interval) { var intervalTicks = interval.Ticks; DateTime? nextTimestamp = null; DateTime? currentDate = null; HistoricalBar currentBar = null; var totalVolume = 0; var totalTrade = 0; foreach (var tick in tickMessages) { // skip if trade size is zero if (tick.LastSize == 0) { continue; } // Check if we need to close off the current bar before we do anything else if (currentBar != null && tick.Timestamp >= nextTimestamp) { // We've reached the end of this bar. Send it out! Setting the currentBar to null // will cause a new bar to be generated on the first valid tick, below. currentBar.VWAP = currentBar.VWAP / currentBar.PeriodVolume; yield return(currentBar); currentBar = null; } // Check for date change up here otherwise 'O' ticks will be ignored // if they are the first ticks of the day, which will make total volume incorrect if (currentDate != null && tick.Timestamp.Date != currentDate) { // Date has changed. Reset the numbers for the next one // Don't start a new bar here, because if the next tick is an 'O' we want to count the volume // but not the tick, and if it's the only tick in a bar, then there shouldn't be a bar! (Apparently) totalVolume = 0; totalTrade = 0; currentDate = tick.Timestamp.Date; } totalVolume += tick.LastSize; totalTrade += 1; // to effect the price the trade must be C or E if (tick.BasisForLast == 'O') { continue; } if (currentBar == null) { // if we get here, we have a valid trade tick, and we need a new bar var currentTimestamp = tick.Timestamp.Trim(intervalTicks); currentBar = new HistoricalBar( currentTimestamp, tick.Last, tick.Last, tick.Last, tick.Last, 0, 0, 0, 0, 0); nextTimestamp = currentTimestamp.AddTicks(intervalTicks); currentDate = currentTimestamp.Date; } if (tick.Last < currentBar.Low) { currentBar.Low = tick.Last; } if (tick.Last > currentBar.High) { currentBar.High = tick.Last; } currentBar.Close = tick.Last; currentBar.PeriodVolume += tick.LastSize; currentBar.PeriodTrade += 1; currentBar.TotalVolume = totalVolume; currentBar.TotalTrade = totalTrade; currentBar.VWAP += tick.Last * tick.LastSize; } // return the last created bar when last tick reached if (currentBar != null) { currentBar.VWAP = currentBar.VWAP / currentBar.PeriodVolume; yield return(currentBar); } }
public void SetUp() { _historicalBar = new HistoricalBar(new DateTime(2020, 01, 01, 9, 30, 00), 1.21, 1.22, 1.23, 1.24, 1000, 1, 100, 1, 12345.12345); }