Skip to content

Commit 629de49

Browse files
committed
Implement Benzinga custom data as ToolBox application and BaseData class
1 parent dfbbf0a commit 629de49

14 files changed

Lines changed: 869 additions & 7 deletions
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3+
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Collections.Generic;
17+
using System.Linq;
18+
using QuantConnect.Algorithm.Framework.Selection;
19+
using QuantConnect.Data;
20+
using QuantConnect.Data.Custom.Benzinga;
21+
using QuantConnect.Data.UniverseSelection;
22+
23+
namespace QuantConnect.Algorithm.CSharp
24+
{
25+
public class BenzingaNewsAlgorithm : QCAlgorithm
26+
{
27+
// Predefine a dictionary of words with scores to scan for in the description
28+
// of the news article
29+
private readonly Dictionary<string, double> _words = new Dictionary<string, double>()
30+
{
31+
{"bad", -0.5}, {"good", 0.5},
32+
{"negative", -0.5}, {"great", 0.5},
33+
{"growth", 0.5}, {"fail", -0.5},
34+
{"failed", -0.5}, {"success", 0.5},
35+
{"nailed", 0.5}, {"beat", 0.5},
36+
{"missed", -0.5}, {"slipped", -0.5},
37+
{"outperforming", 0.5}, {"underperforming", -0.5},
38+
{"outperform", 0.5}, {"underperform", -0.5}
39+
};
40+
41+
/// <summary>
42+
/// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
43+
/// </summary>
44+
public override void Initialize()
45+
{
46+
SetStartDate(2018, 10, 12);
47+
SetEndDate(2018, 11, 25);
48+
SetCash(100000);
49+
50+
UniverseSettings.Resolution = Resolution.Daily;
51+
AddUniverseSelection(new CoarseFundamentalUniverseSelectionModel(CoarseSelector));
52+
}
53+
54+
public IEnumerable<Symbol> CoarseSelector(IEnumerable<CoarseFundamental> coarse)
55+
{
56+
// Add Benzinga news data from the filtered coarse selection
57+
var symbols = coarse.Where(x => x.HasFundamentalData && x.DollarVolume > 50000000)
58+
.Select(x => x.Symbol)
59+
.Take(10);
60+
61+
foreach (var symbol in symbols)
62+
{
63+
AddData<BenzingaNews>(symbol);
64+
}
65+
66+
return symbols;
67+
}
68+
69+
public override void OnData(Slice data)
70+
{
71+
// Get all Benzinga data and loop over it
72+
foreach (var article in data.Get<BenzingaNews>().Values)
73+
{
74+
// Get the list of matching words we have sentiment definitions for
75+
var intersection = article.Contents.ToLowerInvariant()
76+
.Split(' ')
77+
.Intersect(_words.Keys);
78+
79+
// Get the sentiment score
80+
var sentimentScore = intersection.Select(x => _words[x]).Sum();
81+
82+
// Set holdings equal to 1/10th of the sentiment score we get
83+
SetHoldings(article.Symbol.Underlying, sentimentScore / 10);
84+
}
85+
}
86+
87+
public override void OnSecuritiesChanged(SecurityChanges changes)
88+
{
89+
foreach (var r in changes.RemovedSecurities.Where(x => x.Symbol.SecurityType == SecurityType.Equity))
90+
{
91+
// If removed from the universe, liquidate and remove the custom data from the algorithm
92+
Liquidate(r.Symbol);
93+
RemoveSecurity(QuantConnect.Symbol.CreateBase(typeof(BenzingaNews), r.Symbol, Market.USA));
94+
}
95+
}
96+
}
97+
}

Algorithm.CSharp/QuantConnect.Algorithm.CSharp.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@
152152
<Compile Include="Alphas\TripleLeveragedETFPairVolatilityDecayAlpha.cs" />
153153
<Compile Include="Alphas\VixDualThrustAlpha.cs" />
154154
<Compile Include="AltData\CachedAlternativeDataAlgorithm.cs" />
155+
<Compile Include="AltData\BenzingaNewsAlgorithm.cs" />
155156
<Compile Include="AltData\SECReport8KAlgorithm.cs" />
156157
<Compile Include="AltData\SmartInsiderTransactionAlgorithm.cs" />
157158
<Compile Include="AltData\USTreasuryYieldCurveRateAlgorithm.cs" />
@@ -410,4 +411,4 @@
410411
<Target Name="AfterBuild">
411412
</Target>
412413
-->
413-
</Project>
414+
</Project>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
2+
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
from clr import AddReference
15+
AddReference("System")
16+
AddReference("QuantConnect.Algorithm")
17+
AddReference("QuantConnect.Algorithm.Framework")
18+
AddReference("QuantConnect.Common")
19+
20+
from System import *
21+
from QuantConnect import *
22+
from QuantConnect.Algorithm import *
23+
from QuantConnect.Algorithm.Framework.Selection import *
24+
from QuantConnect.Data.Custom.Benzinga import *
25+
from QuantConnect.Data.UniverseSelection import *
26+
27+
class BenzingaNewsAlgorithm(QCAlgorithm):
28+
29+
def Initialize(self):
30+
self.words = {
31+
"bad": -0.5, "good": 0.5,
32+
"negative": -0.5, "great": 0.5,
33+
"growth": 0.5, "fail": -0.5,
34+
"failed": -0.5, "success": 0.5,
35+
"nailed": 0.5, "beat": 0.5,
36+
"missed": -0.5, "slipped": -0.5,
37+
"outperforming": 0.5, "underperforming": -0.5,
38+
"outperform": 0.5, "underperform": -0.5
39+
}
40+
41+
self.SetStartDate(2018, 10, 12)
42+
self.SetEndDate(2018, 11, 25)
43+
self.SetCash(100000)
44+
45+
self.UniverseSettings.Resolution = Resolution.Daily
46+
self.AddUniverseSelection(CoarseFundamentalUniverseSelectionModel(self.CoarseSelector))
47+
48+
def CoarseSelector(self, coarse):
49+
# Add Benzinga news data from the filtered coarse selection
50+
symbols = [i.Symbol for i in coarse if i.HasFundamentalData and i.DollarVolume > 50000000][:10]
51+
52+
for symbol in symbols:
53+
self.AddData(BenzingaNews, symbol)
54+
55+
return symbols
56+
57+
def OnData(self, data):
58+
for article in data.Get(BenzingaNews).Values:
59+
# Split the article into words in all lowercase
60+
articleWords = article.Contents.lower().split(" ")
61+
62+
# Get the list of matching words we have sentiment definitions for
63+
intersection = set(self.words.keys()).intersection(articleWords)
64+
65+
# Get the sentiment score
66+
sentimentScore = sum([self.words[i] for i in intersection])
67+
68+
# Set holdings equal to 1/10th of the sentiment score we get
69+
self.SetHoldings(article.Symbol.Underlying, sentimentScore / 10.0)
70+
71+
def OnSecuritiesChanged(self, changes):
72+
for r in [i for i in changes.RemovedSecurities if i.Symbol.SecurityType == SecurityType.Equity]:
73+
# If removed from the universe, liquidate and remove the custom data from the algorithm
74+
self.Liquidate(r.Symbol)
75+
self.RemoveSecurity(Symbol.CreateBase(BenzingaNews, r.Symbol, Market.USA))

Algorithm.Python/QuantConnect.Algorithm.Python.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
<Content Include="Alphas\TripleLeverageETFPairVolatilityDecayAlpha.py" />
6262
<Content Include="Alphas\VIXDualThrustAlpha.py" />
6363
<Content Include="AltData\CachedAlternativeDataAlgorithm.py" />
64+
<Content Include="AltData\BenzingaNewsAlgorithm.py" />
6465
<Content Include="AltData\SECReport8KAlgorithm.py" />
6566
<Content Include="AltData\SmartInsiderTransactionAlgorithm.py" />
6667
<Content Include="AltData\USTreasuryYieldCurveRateAlgorithm.py" />
@@ -322,4 +323,4 @@
322323
<Target Name="AfterBuild">
323324
</Target>
324325
-->
325-
</Project>
326+
</Project>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3+
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using Newtonsoft.Json;
17+
18+
namespace QuantConnect.Data.Custom.Benzinga
19+
{
20+
/// <summary>
21+
/// News data powered by Benzinga
22+
/// </summary>
23+
public class BenzingaCategory
24+
{
25+
/// <summary>
26+
/// Source/Link associated with the article
27+
/// </summary>
28+
[JsonProperty("@domain")]
29+
public string Resource { get; set; }
30+
31+
/// <summary>
32+
/// Description of the <see cref="Resource"/> property
33+
/// </summary>
34+
[JsonProperty("#text")]
35+
public string Description { get; set; }
36+
}
37+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3+
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using Newtonsoft.Json;
17+
18+
namespace QuantConnect.Data.Custom.Benzinga
19+
{
20+
/// <summary>
21+
/// Article metadata
22+
/// </summary>
23+
public class BenzingaMetadata
24+
{
25+
/// <summary>
26+
/// Is the article for pro subscribers only
27+
/// </summary>
28+
[JsonProperty("@pro")]
29+
public bool IsPro { get; set; }
30+
31+
/// <summary>
32+
/// Is the article a first run
33+
/// </summary>
34+
[JsonProperty("@firstrun")]
35+
public bool FirstRun { get; set; }
36+
37+
/// <summary>
38+
/// Type of article
39+
/// </summary>
40+
[JsonProperty("#text")]
41+
public string Kind { get; set; }
42+
}
43+
}

0 commit comments

Comments
 (0)