Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Common/Indicators/RollingWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,12 @@ public T this[int i]
{
throw new ArgumentOutOfRangeException(nameof(i), i, Messages.RollingWindow.IndexOutOfSizeRange);
}
i = _size + i;
i = _list.Count + i;

if (i < 0)
{
return default;
}
}

if (i > _list.Count - 1)
Expand Down
17 changes: 12 additions & 5 deletions Engine/RealTime/LiveTradingRealTimeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,7 @@ private void Run()
while (!_cancellationTokenSource.IsCancellationRequested)
{
var time = TimeProvider.GetUtcNow();

// pause until the next second
var nextSecond = time.RoundUp(TimeSpan.FromSeconds(1));
var delay = Convert.ToInt32((nextSecond - time).TotalMilliseconds);
Thread.Sleep(delay < 0 ? 1 : delay);
WaitTillNextSecond(time);

// poke each event to see if it should fire, we order by unique id to be deterministic
foreach (var kvp in ScheduledEvents.OrderBySafe(pair => pair.Value))
Expand Down Expand Up @@ -166,6 +162,17 @@ public override void Exit()
base.Exit();
}

/// <summary>
/// Helper method to wait until the second passes, useful to testing
/// </summary>
protected virtual void WaitTillNextSecond(DateTime time)
{
// pause until the next second
var nextSecond = time.RoundUp(TimeSpan.FromSeconds(1));
var delay = Convert.ToInt32((nextSecond - time).TotalMilliseconds);
Thread.Sleep(delay < 0 ? 1 : delay);
}

/// <summary>
/// Resets the market hours database, forcing a reload when reused.
/// Called in tests where multiple algorithms are run sequentially,
Expand Down
13 changes: 9 additions & 4 deletions Tests/Engine/RealTime/LiveTradingRealTimeHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,18 +200,18 @@ public void RefreshesSymbolProperties(string refreshPeriodStr)
// wait for the internal thread to start
WaitUntilActive(realTimeHandler);

for (var i = 0; i < 10; i++)
for (var i = 0; i < 5; i++)
{
timeProvider.Advance(step);

// We only advanced half the time, so we should not have refreshed yet
if (i % 2 == 0)
{
Assert.IsFalse(realTimeHandler.SpdbRefreshed.Wait(5000));
Assert.IsFalse(realTimeHandler.SpdbRefreshed.Wait(100));
}
else
{
Assert.IsTrue(realTimeHandler.SpdbRefreshed.Wait(5000));
Assert.IsTrue(realTimeHandler.SpdbRefreshed.Wait(2000));
realTimeHandler.SpdbRefreshed.Reset();
}
}
Expand Down Expand Up @@ -295,7 +295,7 @@ private static void WaitUntilActive(LiveTradingRealTimeHandler realTimeHandler)
{
while (!realTimeHandler.IsActive)
{
Thread.Sleep(5);
Thread.Sleep(2);
}
}

Expand Down Expand Up @@ -410,6 +410,11 @@ protected override void ResetSymbolPropertiesDatabase()
SpdbRefreshed.Set();
}

protected override void WaitTillNextSecond(DateTime time)
{
Thread.Sleep(2);
}

public void Dispose()
{
if (_disposed) return;
Expand Down
46 changes: 41 additions & 5 deletions Tests/Indicators/RollingWindowTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,52 @@
*/

using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Python.Runtime;
using QuantConnect.Data.Market;
using NUnit.Framework;
using QuantConnect.Indicators;
using QuantConnect.Python;
using System.Collections.Generic;

namespace QuantConnect.Tests.Indicators
{
[TestFixture]
public class RollingWindowTests
{
[Test]
public void NotFullRollingWindowNegativeIndex()
{
var window = new RollingWindow<int>(3);
window.Add(10);
window.Add(20);

Assert.AreEqual(20, window.First());
Assert.AreEqual(20, window[0]);
Assert.AreEqual(20, window[-2]);

Assert.AreEqual(10, window[1]);
Assert.AreEqual(10, window[-1]);
Assert.AreEqual(10, window.Last());

Assert.AreEqual(0, window[2]);
Assert.AreEqual(0, window[-3]);

window.Add(30);
window.Add(40);

Assert.AreEqual(40, window.First());
Assert.AreEqual(40, window[0]);
Assert.AreEqual(40, window[-3]);

Assert.AreEqual(20, window[2]);
Assert.AreEqual(20, window[-1]);
Assert.AreEqual(20, window.Last());

Assert.IsTrue(window.IsReady);
Assert.AreEqual(3, window.Size);
Assert.AreEqual(3, window.Count);
Assert.AreEqual(4, window.Samples);
}

[Test]
public void NewWindowIsEmpty()
{
Expand Down Expand Up @@ -373,7 +406,10 @@ public void RollingWindowSupportsNegativeIndices()
// Add two elements and test negative indexing before window is full
window.Add(7);
window.Add(-2);
Assert.AreEqual(0, window[-1]);
Assert.AreEqual(7, window[-1]);
Assert.AreEqual(7, window.Last());
Assert.AreEqual(-2, window[0]);
Assert.AreEqual(-2, window.First());
Assert.AreEqual(2, window.Count);
Assert.IsFalse(window.IsReady);

Expand Down
Loading