Skip to content

Commit c024a41

Browse files
committed
Cleanup regression algorithms
1 parent 9d99517 commit c024a41

3 files changed

Lines changed: 58 additions & 146 deletions

Algorithm.CSharp/SecurityInitializationOnReAdditionForEquityRegressionAlgorithm.cs

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,36 @@
1919
using QuantConnect.Data.UniverseSelection;
2020
using QuantConnect.Interfaces;
2121
using QuantConnect.Securities;
22-
using QuantConnect.Securities.Equity;
2322

2423
namespace QuantConnect.Algorithm.CSharp
2524
{
2625
/// <summary>
26+
/// Regression algorithm testing the behavior of the algorithm when a security is removed and re-added.
27+
/// It asserts that the securities are marked as non-tradable when removed and that they are tradable when re-added.
28+
/// It also asserts that the algorithm receives the correct security changed events for the added and removed securities.
29+
///
30+
/// This specific algorithm tests this behavior for equities.
2731
/// </summary>
2832
public class SecurityInitializationOnReAdditionForEquityRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
2933
{
30-
private Security _equity;
34+
private Security _security;
3135
private Queue<DateTime> _tradableDates;
3236
private bool _securityWasRemoved;
3337

38+
protected virtual DateTime StartTimeToUse => new DateTime(2013, 10, 05);
39+
40+
protected virtual DateTime EndTimeToUse => new DateTime(2013, 10, 30);
41+
3442
public override void Initialize()
3543
{
36-
SetStartDate(2013, 10, 04);
37-
SetEndDate(2013, 10, 30);
44+
SetStartDate(StartTimeToUse);
45+
SetEndDate(EndTimeToUse);
3846

39-
_equity = AddEquity();
47+
_security = AddSecurity();
4048

41-
_tradableDates = new(QuantConnect.Time.EachTradeableDay(_equity.Exchange.Hours, StartDate, EndDate));
49+
_tradableDates = new(QuantConnect.Time.EachTradeableDay(_security.Exchange.Hours, StartDate, EndDate));
4250

43-
Schedule.On(DateRules.EveryDay(_equity.Symbol), TimeRules.Midnight, () =>
51+
Schedule.On(DateRules.EveryDay(_security.Symbol), TimeRules.Midnight, () =>
4452
{
4553
var currentTradableDate = _tradableDates.Dequeue();
4654
if (currentTradableDate != Time.Date)
@@ -54,21 +62,24 @@ public override void Initialize()
5462
}
5563

5664
// Remove the security every day
57-
Debug($"[{Time}] Removing the equity");
58-
_securityWasRemoved = RemoveSecurity(_equity.Symbol);
65+
Debug($"[{Time}] Removing the security");
66+
_securityWasRemoved = RemoveSecurity(_security.Symbol);
5967

6068
if (!_securityWasRemoved)
6169
{
62-
throw new RegressionTestException($"Expected the equity to be removed");
70+
throw new RegressionTestException($"Expected the security to be removed");
71+
}
72+
73+
if (_security.IsTradable)
74+
{
75+
throw new RegressionTestException($"Expected the security to be not tradable after removing it");
6376
}
6477
});
6578
}
6679

67-
private Equity AddEquity()
80+
protected virtual Security AddSecurity()
6881
{
69-
var equity = AddEquity("SPY");
70-
71-
return equity;
82+
return AddEquity("SPY");
7283
}
7384

7485
public override void OnSecuritiesChanged(SecurityChanges changes)
@@ -80,30 +91,30 @@ public override void OnSecuritiesChanged(SecurityChanges changes)
8091
throw new RegressionTestException($"Expected no securities to be added. Got {changes.AddedSecurities.Count}");
8192
}
8293

83-
if (!changes.RemovedSecurities.Contains(_equity))
94+
if (!changes.RemovedSecurities.Contains(_security))
8495
{
85-
throw new RegressionTestException($"Expected the equity to be removed. Got {changes.RemovedSecurities.Count}");
96+
throw new RegressionTestException($"Expected the security to be removed. Got {changes.RemovedSecurities.Count}");
8697
}
8798

8899
_securityWasRemoved = false;
89100

90101
// Add the security back
91-
Debug($"[{Time}] Re-adding the equity");
92-
var reAddedEquity = AddEquity();
102+
Debug($"[{Time}] Re-adding the security");
103+
var reAddedSecurity = AddSecurity();
93104

94-
if (!ReferenceEquals(reAddedEquity, _equity))
105+
if (!ReferenceEquals(reAddedSecurity, _security))
95106
{
96-
throw new RegressionTestException($"Expected the re-added equity to be the same as the original equity");
107+
throw new RegressionTestException($"Expected the re-added security to be the same as the original security");
97108
}
98109

99-
if (!reAddedEquity.IsTradable)
110+
if (!reAddedSecurity.IsTradable)
100111
{
101-
throw new RegressionTestException($"Expected the re-added equity to be tradable");
112+
throw new RegressionTestException($"Expected the re-added security to be tradable");
102113
}
103114
}
104-
else if (!changes.AddedSecurities.Contains(_equity))
115+
else if (!changes.AddedSecurities.Contains(_security))
105116
{
106-
throw new RegressionTestException($"Expected the equity to be added back");
117+
throw new RegressionTestException($"Expected the security to be added back");
107118
}
108119
}
109120

@@ -128,12 +139,12 @@ public override void OnEndOfAlgorithm()
128139
/// <summary>
129140
/// Data Points count of all timeslices of algorithm
130141
/// </summary>
131-
public long DataPoints => 4823;
142+
public virtual long DataPoints => 4036;
132143

133144
/// <summary>
134145
/// Data Points count of the algorithm history
135146
/// </summary>
136-
public int AlgorithmHistoryDataPoints => 0;
147+
public virtual int AlgorithmHistoryDataPoints => 0;
137148

138149
/// <summary>
139150
/// Final status of the algorithm
@@ -143,7 +154,7 @@ public override void OnEndOfAlgorithm()
143154
/// <summary>
144155
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
145156
/// </summary>
146-
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
157+
public virtual Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
147158
{
148159
{"Total Orders", "0"},
149160
{"Average Win", "0%"},
@@ -164,8 +175,8 @@ public override void OnEndOfAlgorithm()
164175
{"Beta", "0"},
165176
{"Annual Standard Deviation", "0"},
166177
{"Annual Variance", "0"},
167-
{"Information Ratio", "-4.884"},
168-
{"Tracking Error", "0.108"},
178+
{"Information Ratio", "-5.028"},
179+
{"Tracking Error", "0.11"},
169180
{"Treynor Ratio", "0"},
170181
{"Total Fees", "$0.00"},
171182
{"Estimated Strategy Capacity", "$0"},

Algorithm.CSharp/SecurityInitializationOnReAdditionForManuallyAddedOptionRegressionAlgorithm.cs

Lines changed: 13 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,18 @@
1515

1616
using System;
1717
using System.Collections.Generic;
18-
using System.Linq;
19-
using QuantConnect.Data.UniverseSelection;
20-
using QuantConnect.Interfaces;
2118
using QuantConnect.Securities;
22-
using QuantConnect.Securities.Option;
2319

2420
namespace QuantConnect.Algorithm.CSharp
2521
{
2622
/// <summary>
23+
/// Regression algorithm testing the behavior of the algorithm when a security is removed and re-added.
24+
/// It asserts that the securities are marked as non-tradable when removed and that they are tradable when re-added.
25+
/// It also asserts that the algorithm receives the correct security changed events for the added and removed securities.
26+
///
27+
/// This specific algorithm tests this behavior for manually added option contracts.
2728
/// </summary>
28-
public class SecurityInitializationOnReAdditionForManuallyAddedOptionRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
29+
public class SecurityInitializationOnReAdditionForManuallyAddedOptionRegressionAlgorithm : SecurityInitializationOnReAdditionForEquityRegressionAlgorithm
2930
{
3031
private static readonly Symbol _optionContractSymbol = QuantConnect.Symbol.CreateOption(
3132
QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA),
@@ -35,130 +36,29 @@ public class SecurityInitializationOnReAdditionForManuallyAddedOptionRegressionA
3536
342.9m,
3637
new DateTime(2014, 07, 19));
3738

38-
private Option _manuallyAddedContract;
39+
protected override DateTime StartTimeToUse => new DateTime(2014, 06, 04);
3940

40-
private bool _securityWasRemoved;
41+
protected override DateTime EndTimeToUse => new DateTime(2014, 06, 20);
4142

42-
private Queue<DateTime> _tradableDates;
43-
44-
public override void Initialize()
45-
{
46-
SetStartDate(2014, 06, 04);
47-
SetEndDate(2014, 06, 20);
48-
SetCash(100000);
49-
50-
_manuallyAddedContract = AddOptionContract();
51-
52-
_tradableDates = new(QuantConnect.Time.EachTradeableDay(_manuallyAddedContract.Exchange.Hours, StartDate, EndDate));
53-
54-
Schedule.On(DateRules.EveryDay(_manuallyAddedContract.Symbol), TimeRules.Midnight, () =>
55-
{
56-
var currentTradableDate = _tradableDates.Dequeue();
57-
if (currentTradableDate != Time.Date)
58-
{
59-
throw new RegressionTestException($"Expected the current tradable date to be {Time.Date}. Got {currentTradableDate}");
60-
}
61-
62-
if (Time == StartDate)
63-
{
64-
return;
65-
}
66-
67-
// Remove the security every day
68-
Debug($"[{Time}] Removing the equity");
69-
_securityWasRemoved = RemoveSecurity(_manuallyAddedContract.Symbol);
70-
71-
if (!_securityWasRemoved)
72-
{
73-
throw new RegressionTestException($"Expected the equity to be removed");
74-
}
75-
});
76-
}
77-
78-
public Option AddOptionContract()
43+
protected override Security AddSecurity()
7944
{
80-
var option = AddOptionContract(_optionContractSymbol, Resolution.Daily);
81-
return option;
82-
}
83-
84-
public override void OnSecuritiesChanged(SecurityChanges changes)
85-
{
86-
if (_securityWasRemoved)
87-
{
88-
if (changes.AddedSecurities.Count > 0)
89-
{
90-
throw new RegressionTestException($"Expected no securities to be added. Got {changes.AddedSecurities.Count}");
91-
}
92-
93-
if (!changes.RemovedSecurities.Contains(_manuallyAddedContract))
94-
{
95-
throw new RegressionTestException($"Expected the option contract to be removed. Got {changes.RemovedSecurities.Count}");
96-
}
97-
98-
_securityWasRemoved = false;
99-
100-
if (Time.Date >= EndDate.Date)
101-
{
102-
return;
103-
}
104-
105-
// Add the security back
106-
Debug($"[{Time}] Re-adding the option contract");
107-
var reAddedContract = AddOptionContract();
108-
109-
if (!ReferenceEquals(reAddedContract, _manuallyAddedContract))
110-
{
111-
throw new RegressionTestException($"Expected the re-added option contract to be the same as the original option contract");
112-
}
113-
114-
if (!reAddedContract.IsTradable)
115-
{
116-
throw new RegressionTestException($"Expected the re-added option contract to be tradable");
117-
}
118-
}
119-
else if (!changes.AddedSecurities.Contains(_manuallyAddedContract))
120-
{
121-
throw new RegressionTestException($"Expected the option contract to be added back");
122-
}
123-
}
124-
125-
public override void OnEndOfAlgorithm()
126-
{
127-
if (_tradableDates.Count > 0)
128-
{
129-
throw new RegressionTestException($"Expected no more tradable dates. Still have {_tradableDates.Count}");
130-
}
45+
return AddOptionContract(_optionContractSymbol, Resolution.Daily);
13146
}
13247

133-
/// <summary>
134-
/// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm.
135-
/// </summary>
136-
public bool CanRunLocally { get; } = true;
137-
138-
/// <summary>
139-
/// This is used by the regression test system to indicate which languages this algorithm is written in.
140-
/// </summary>
141-
public List<Language> Languages { get; } = new() { Language.CSharp };
142-
14348
/// <summary>
14449
/// Data Points count of all timeslices of algorithm
14550
/// </summary>
146-
public long DataPoints => 115;
51+
public override long DataPoints => 115;
14752

14853
/// <summary>
14954
/// Data Points count of the algorithm history
15055
/// </summary>
151-
public int AlgorithmHistoryDataPoints => 0;
152-
153-
/// <summary>
154-
/// Final status of the algorithm
155-
/// </summary>
156-
public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed;
56+
public override int AlgorithmHistoryDataPoints => 0;
15757

15858
/// <summary>
15959
/// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
16060
/// </summary>
161-
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
61+
public override Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
16262
{
16363
{"Total Orders", "0"},
16464
{"Average Win", "0%"},

Algorithm.CSharp/SecurityInitializationOnReAdditionForSelectedOptionRegressionAlgorithm.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@
2424
namespace QuantConnect.Algorithm.CSharp
2525
{
2626
/// <summary>
27+
/// Regression algorithm testing the behavior of the algorithm when a security is removed and re-added.
28+
/// It asserts that the securities are marked as non-tradable when removed and that they are tradable when re-added.
29+
/// It also asserts that the algorithm receives the correct security changed events for the added and removed securities.
30+
///
31+
/// This specific algorithm tests this behavior for option contracts that are selected, deselected and re-selected.
2732
/// </summary>
2833
public class SecurityInitializationOnReAdditionForSelectedOptionRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
2934
{
3035
private List<Symbol> _contractsToSelect;
3136
private HashSet<Option> _selectedContracts = new();
32-
private Dictionary<Security, int> _initializedContracts = new();
33-
3437
private bool _selectSingle;
3538
private int _selectionsCount;
3639

@@ -52,10 +55,8 @@ public override void Initialize()
5255
option.SetFilter(u => u.Contracts(contracts =>
5356
{
5457
_selectionsCount++;
55-
_initializedContracts.Clear();
5658

5759
List<Symbol> selected;
58-
5960
if (_selectSingle)
6061
{
6162
_selectSingle = false;

0 commit comments

Comments
 (0)