Skip to content

Commit

Permalink
Avoid termination on empty live cash balance (#7581)
Browse files Browse the repository at this point in the history
- Avoid algorithm termination on empty live cash balance if there was no
  error
  • Loading branch information
Martin-Molinero authored Nov 17, 2023
1 parent 5e9901c commit 830df29
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
5 changes: 3 additions & 2 deletions Brokerages/Brokerage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ public virtual bool PerformCashSync(IAlgorithm algorithm, DateTime currentTimeUt

Log.Trace("Brokerage.PerformCashSync(): Sync cash balance");

var balances = new List<CashAmount>();
List<CashAmount> balances = null;
try
{
balances = GetCashBalance();
Expand All @@ -470,7 +470,8 @@ public virtual bool PerformCashSync(IAlgorithm algorithm, DateTime currentTimeUt
Log.Error(err, "Error in GetCashBalance:");
}

if (balances.Count == 0)
// empty cash balance is valid, if there was No error/exception
if (balances == null)
{
Log.Trace("Brokerage.PerformCashSync(): No cash balances available, cash sync not performed");
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,42 @@ public void ProcessSynchronousEventsShouldPerformCashSyncOnlyAtExpectedTime()
Assert.AreEqual(0, brokerage.GetCashBalanceCallCount);
}

[Test]
public void EmptyCashBalanceIsValid()
{
var mock = new Mock<TestBrokerage>
{
CallBase = true
};
var cashBalance = mock.Setup(m => m.GetCashBalance()).Returns(new List<CashAmount>());
mock.Setup(m => m.IsConnected).Returns(true);
mock.Setup(m => m.ShouldPerformCashSync(It.IsAny<DateTime>())).Returns(true);

var brokerage = mock.Object;
Assert.IsTrue(brokerage.IsConnected);

var algorithm = new QCAlgorithm();
var marketHoursDatabase = MarketHoursDatabase.FromDataFolder();
var symbolPropertiesDataBase = SymbolPropertiesDatabase.FromDataFolder();
var securityService = new SecurityService(algorithm.Portfolio.CashBook, marketHoursDatabase, symbolPropertiesDataBase, algorithm, RegisteredSecurityDataTypesProvider.Null, new SecurityCacheProvider(algorithm.Portfolio));
algorithm.Securities.SetSecurityService(securityService);
algorithm.SetLiveMode(true);
algorithm.SetFinishedWarmingUp();

var transactionHandler = new TestBrokerageTransactionHandler();
var resultHandler = new TestResultHandler();
transactionHandler.Initialize(algorithm, brokerage, resultHandler);

// Advance current time UTC so cash sync is performed
transactionHandler.TestCurrentTimeUtc = transactionHandler.TestCurrentTimeUtc.AddDays(2);

transactionHandler.ProcessSynchronousEvents();

resultHandler.Exit();

mock.VerifyAll();
}

[Test]
public void DoesNotLoopEndlesslyIfGetCashBalanceAlwaysThrows()
{
Expand Down
5 changes: 4 additions & 1 deletion Tests/Engine/Setup/BrokerageSetupHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,10 @@ public TestBrokerageFactory() : base(typeof(TestBrokerage))
public override void Dispose() { }
}

internal class TestBrokerage : Brokerage
/// <summary>
/// Public so that mock can access it
/// </summary>
public class TestBrokerage : Brokerage
{
public override bool IsConnected { get; } = true;
public int GetCashBalanceCallCount;
Expand Down

0 comments on commit 830df29

Please sign in to comment.