Skip to content

Commit f2b4371

Browse files
committed
Improve regression algo
1 parent c52dbc0 commit f2b4371

File tree

2 files changed

+68
-70
lines changed

2 files changed

+68
-70
lines changed

Algorithm.CSharp/OptionChainedUniverseSelectionModelRegressionAlgorithm.cs

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
* limitations under the License.
1414
*/
1515

16+
using QuantConnect.Algorithm.Framework.Selection;
1617
using QuantConnect.Algorithm.Selection;
18+
using QuantConnect.Data;
19+
using QuantConnect.Data.Market;
1720
using QuantConnect.Data.UniverseSelection;
1821
using QuantConnect.Interfaces;
19-
using QuantConnect.Securities;
2022
using System;
2123
using System.Collections.Generic;
2224
using System.Linq;
@@ -28,52 +30,44 @@ namespace QuantConnect.Algorithm.CSharp
2830
/// </summary>
2931
public class OptionChainedUniverseSelectionModelRegressionAlgorithm: QCAlgorithm, IRegressionAlgorithmDefinition
3032
{
33+
Symbol _aapl;
3134
public override void Initialize()
3235
{
33-
UniverseSettings.Resolution = Resolution.Daily;
34-
SetStartDate(2014, 03, 22);
35-
SetEndDate(2014, 04, 07);
36+
UniverseSettings.Resolution = Resolution.Minute;
37+
SetStartDate(2014, 6, 6);
38+
SetEndDate(2014, 6, 6);
3639
SetCash(100000);
40+
_aapl = QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA);
41+
var config = new SubscriptionDataConfig(typeof(TradeBar), _aapl, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, false, false, true);
42+
var universe = AddUniverse(new ManualUniverse(config, UniverseSettings, new[] { _aapl }));
3743

38-
AddSecurity(SecurityType.Equity, "GOOG", Resolution.Daily);
39-
40-
var universe = AddUniverse(coarse =>
41-
{
42-
// select the various google symbols over the period
43-
return from c in coarse
44-
let sym = c.Symbol.Value
45-
where sym == "GOOG" || sym == "GOOCV" || sym == "GOOAV"
46-
select c.Symbol;
47-
48-
// Before March 28th 2014:
49-
// - Only GOOG T1AZ164W5VTX existed
50-
// On March 28th 2014
51-
// - GOOAV VP83T1ZUHROL and GOOCV VP83T1ZUHROL are listed
52-
// On April 02nd 2014
53-
// - GOOAV VP83T1ZUHROL is delisted
54-
// - GOOG T1AZ164W5VTX becomes GOOGL
55-
// - GOOCV VP83T1ZUHROL becomes GOOG
56-
});
57-
58-
AddUniverseSelection(new OptionChainedUniverseSelectionModel(universe,
59-
option_filter_universe => option_filter_universe));
44+
AddUniverseSelection(new OptionChainedUniverseSelectionModel(universe, u => u.Strikes(-2, +2)
45+
// Expiration method accepts TimeSpan objects or integer for days.
46+
// The following statements yield the same filtering criteria
47+
.Expiration(0, 180)));
6048
}
6149

62-
public override void OnEndOfAlgorithm()
50+
public override void OnData(Slice slice)
6351
{
64-
if (!UniverseManager.ContainsKey("?GOOCV"))
52+
if (!Portfolio.Invested && IsMarketOpen(_aapl))
6553
{
66-
throw new Exception("Option chain {?GOOCV} should have been in the universe but it was not");
67-
}
54+
OptionChain chain;
55+
if (slice.OptionChains.TryGetValue("?AAPL", out chain))
56+
{
57+
// we find at the money (ATM) put contract with farthest expiration
58+
var atmContract = chain
59+
.OrderByDescending(x => x.Expiry)
60+
.ThenBy(x => Math.Abs(chain.Underlying.Price - x.Strike))
61+
.ThenByDescending(x => x.Right)
62+
.FirstOrDefault();
6863

69-
if (!UniverseManager.ContainsKey("?GOOG"))
70-
{
71-
throw new Exception("Option chain {?GOOG} should have been in the universe but it was not");
72-
}
73-
74-
if (!UniverseManager.ContainsKey("?GOOAV"))
75-
{
76-
throw new Exception("Option chain {?GOOAV} should have been in the universe but it was not");
64+
if (atmContract != null)
65+
{
66+
// if found, trade it
67+
MarketOrder(atmContract.Symbol, 1);
68+
MarketOnCloseOrder(atmContract.Symbol, -1);
69+
}
70+
}
7771
}
7872
}
7973

@@ -90,7 +84,7 @@ public override void OnEndOfAlgorithm()
9084
/// <summary>
9185
/// Data Points count of all timeslices of algorithm
9286
/// </summary>
93-
public long DataPoints => 78080;
87+
public long DataPoints => 936646;
9488

9589
/// <summary>
9690
/// Data Points count of the algorithm history
@@ -102,7 +96,7 @@ public override void OnEndOfAlgorithm()
10296
/// </summary>
10397
public Dictionary<string, string> ExpectedStatistics => new Dictionary<string, string>
10498
{
105-
{"Total Trades", "0"},
99+
{"Total Trades", "2"},
106100
{"Average Win", "0%"},
107101
{"Average Loss", "0%"},
108102
{"Compounding Annual Return", "0%"},
@@ -119,14 +113,14 @@ public override void OnEndOfAlgorithm()
119113
{"Beta", "0"},
120114
{"Annual Standard Deviation", "0"},
121115
{"Annual Variance", "0"},
122-
{"Information Ratio", "1.552"},
123-
{"Tracking Error", "0.092"},
116+
{"Information Ratio", "0"},
117+
{"Tracking Error", "0"},
124118
{"Treynor Ratio", "0"},
125-
{"Total Fees", "$0.00"},
126-
{"Estimated Strategy Capacity", "$0"},
127-
{"Lowest Capacity Asset", ""},
128-
{"Portfolio Turnover", "0%"},
129-
{"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
119+
{"Total Fees", "$2.00"},
120+
{"Estimated Strategy Capacity", "$100000.00"},
121+
{"Lowest Capacity Asset", "AAPL 2ZTXYLO9EQPZA|AAPL R735QTJ8XC9X"},
122+
{"Portfolio Turnover", "8.01%"},
123+
{"OrderListHash", "3c4bef29d95bf4c3a566bca7531b1df0"}
130124
};
131125
}
132126
}

Algorithm.Python/OptionChainedUniverseSelectionModelRegressionAlgorithm.py

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,40 @@
1818
### </summary>
1919
class OptionChainedUniverseSelectionModelRegressionAlgorithm(QCAlgorithm):
2020
def Initialize(self):
21-
self.UniverseSettings.Resolution = Resolution.Daily
22-
self.SetStartDate(2014, 3, 22)
23-
self.SetEndDate(2014, 4, 7)
21+
self.UniverseSettings.Resolution = Resolution.Minute
22+
self.SetStartDate(2014, 6, 6)
23+
self.SetEndDate(2014, 6, 6)
2424
self.SetCash(100000)
2525

26-
self.AddSecurity(SecurityType.Equity, "GOOG", Resolution.Daily)
27-
universe = self.AddUniverse(lambda coarse: self.Selector(coarse))
26+
self.aapl = Symbol.Create("AAPL", SecurityType.Equity, Market.USA)
27+
tradebar = TradeBar()
28+
config = SubscriptionDataConfig(type(tradebar), self.aapl, Resolution.Minute, TimeZones.NewYork, TimeZones.NewYork, False, False, True)
29+
universe = self.AddUniverse(ManualUniverse(config, self.UniverseSettings, [ self.aapl ]))
2830
self.AddUniverseSelection(
2931
OptionChainedUniverseSelectionModel(
3032
universe,
31-
lambda option_filter_universe: option_filter_universe,
32-
self.UniverseSettings
33+
lambda u: (u.Strikes(-2, +2)
34+
# Expiration method accepts TimeSpan objects or integer for days.
35+
# The following statements yield the same filtering criteria
36+
.Expiration(0, 180))
3337
)
3438
)
35-
36-
def OnEndOfAlgorithm(self):
37-
if not self.UniverseManager.ContainsKey("?GOOCV"):
38-
raise Exception("Option chain {?GOOCV} should have been in the universe but it was not")
3939

40-
if not self.UniverseManager.ContainsKey("?GOOG"):
41-
raise Exception("Option chain {?GOOG} should have been in the universe but it was not")
40+
def OnData(self, slice):
41+
if self.Portfolio.Invested or not self.IsMarketOpen(self.aapl): return
42+
chain = slice.OptionChains.GetValue("?AAPL")
43+
if chain is None:
44+
return
4245

43-
if not self.UniverseManager.ContainsKey("?GOOAV"):
44-
raise Exception("Option chain {?GOOAV} should have been in the universe but it was not")
45-
46-
def Selector(self, coarse):
47-
result = []
48-
for c in coarse:
49-
sym = c.Symbol.Value
50-
if sym == "GOOG" or sym == "GOOCV" or sym == "GOOAV":
51-
result.append(c.Symbol)
52-
return result
46+
# we sort the contracts to find at the money (ATM) contract with farthest expiration
47+
contracts = sorted(sorted(sorted(chain, \
48+
key = lambda x: abs(chain.Underlying.Price - x.Strike)), \
49+
key = lambda x: x.Expiry, reverse=True), \
50+
key = lambda x: x.Right, reverse=True)
51+
52+
# if found, trade it
53+
if len(contracts) == 0: return
54+
symbol = contracts[0].Symbol
55+
self.MarketOrder(symbol, 1)
56+
self.MarketOnCloseOrder(symbol, -1)
5357

0 commit comments

Comments
 (0)