Skip to content

Commit

Permalink
Updates Examples
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexCatarino committed Oct 19, 2023
1 parent c69b140 commit a99128f
Showing 1 changed file with 37 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,52 @@
<p>The following examples are typical filter functions you may want.<br></p>
<h4>Example 1: Take 500 stocks that are worth more than $10 and have more than $10M daily trading volume</h4>
<p>
The most common use case is to select a lot of liquid stocks. With a coarse universe filter, this is simple and fast. The following example selects the top most liquid 500 stocks over $10 per share.
The most common use case is to select a lot of liquid stocks. With a fundamental universe filter, this is simple and fast. The following example selects the top most liquid 500 stocks over $10 per share.
</p>
<div class="section-example-container">
<pre class="csharp">IEnumerable&lt;Symbol&gt; CoarseFilterFunction(IEnumerable&lt;CoarseFundamental&gt; coarse)
<pre class="csharp">private IEnumerable&lt;Symbol&gt; FundamentalFilterFunction(IEnumerable&lt;Fundamental&gt; fundamental)
{
// Linq makes this a piece of cake;
return (from c in coarse
where c.DollarVolume &gt; 10000000 &amp;&amp;
c.Price &gt; 10
orderby c.DollarVolume descending
select c.Symbol).Take(500);
return (from f in fundamental
where f.Price &gt; 10 &amp;&amp; f.DollarVolume &gt; 10000000
orderby f.DollarVolume descending
select f.Symbol).Take(500);
}</pre>
<pre class="python">def CoarseFilterFunction(self, coarse: List[CoarseFundamental]) -&gt; List[Symbol]:
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
filtered = [ x.Symbol for x in sortedByDollarVolume
if x.Price &gt; 10 and x.DollarVolume &gt; 10000000 ]
return filtered[:500]</pre>
<pre class="python">def FundamentalFilterFunction(self, fundamental: List[Fundamental]) -&gt; List[Symbol]:
filtered = [f for f in fundamental if f.Price &gt; 10 and f.DollarVolume &gt; 10000000]
sortedByDollarVolume = sorted(filtered, key=lambda f: f.DollarVolume, reverse=True)
return sortedByDollarVolume[:500]</pre>
</div>


<h4>Example 2: Take 10 stocks above their 200-Day EMA and have more than $1B daily trading volume</h4>
<p>
Another common request is to filter the universe by a technical indicator, such as only picking stocks above their 200-day EMA. The <code>CoarseFundamental</code> object has adjusted price and volume information, so you can do any price-related analysis.
Another common request is to filter the universe by a technical indicator, such as only picking stocks above their 200-day EMA. The <code>Fundamental</code> object has adjusted price and volume information, so you can do any price-related analysis.
</p>
<div class="section-example-container">
<pre class="csharp">ConcurrentDictionary&lt;Symbol, SelectionData&gt;
_stateData = new ConcurrentDictionary&lt;Symbol, SelectionData&gt;();

// Coarse filter function
IEnumerable&lt;Symbol&gt; CoarseFilterFunction(IEnumerable&lt;CoarseFundamental&gt; coarse) {
private IEnumerable&lt;Symbol&gt; FundamentalFilterFunction(IEnumerable&lt;Fundamental&gt; fundamental)
{
// Linq makes this a piece of cake;
return (from c in coarse
let avg = _stateData.GetOrAdd(c.Symbol, sym =&gt; new SelectionData(200))
where avg.Update(c.EndTime, c.AdjustedPrice)
where c.DollarVolume &gt; 1000000000 &amp;&amp;
c.Price &gt; avg.Ema
orderby c.DollarVolume descending
select c.Symbol).Take(10);
return (from f in fundamental
let avg = _stateData.GetOrAdd(f.Symbol, sym =&gt; new SelectionData(200))
where avg.Update(f.EndTime, f.AdjustedPrice)
where f.Price &gt; avg.Ema &amp;&amp; f.DollarVolume &gt; 1000000000
orderby f.DollarVolume descending
select f.Symbol).Take(10);
}</pre>
<pre class="python"># setup state storage in initialize method
self.stateData = { }

def CoarseFilterFunction(self, coarse: List[CoarseFundamental]) -&gt; List[Symbol]:
# We are going to use a dictionary to refer the object that will keep the moving averages
for c in coarse:
if c.Symbol not in self.stateData:
self.stateData[c.Symbol] = SelectionData(c.Symbol, 200)
def FundamentalFilterFunction(self, fundamental: List[Fundamental]) -&gt; List[Symbol]:<br> # We are going to use a dictionary to refer the object that will keep the moving averages
for f in fundamental:<br> if f.Symbol not in self.stateData:
self.stateData[f.Symbol] = SelectionData(f.Symbol, 200)

# Updates the SymbolData object with current EOD price
avg = self.stateData[c.Symbol]
avg.update(c.EndTime, c.AdjustedPrice, c.DollarVolume)
avg = self.stateData[f.Symbol]
avg.update(c.EndTime, f.AdjustedPrice, f.DollarVolume)

# Filter the values of the dict to those above EMA and more than $1B vol.
values = [x for x in self.stateData.values() if x.is_above_ema and x.volume &gt; 1000000000]
Expand Down Expand Up @@ -100,7 +95,7 @@ <h4>Example 2: Take 10 stocks above their 200-Day EMA and have more than $1B dai
}</pre>
</div>

<p>Note that the preceding <code>SelectionData</code> class uses a <a href="/docs/v2/writing-algorithms/indicators/manual-indicators">manual</a> EMA indicator instead of the <a href="/docs/v2/writing-algorithms/indicators/automatic-indicators">automatic version</a>. For more information about universes that select assets based on indicators, see <a href="/docs/v2/writing-algorithms/indicators/indicator-universes">Indicator Universes</a>. You need to use a <code>SelectionData</code> class instead of assigning the EMA to the <code>CoarseFundamental</code> object because you can't create custom <span class='csharp'>properties</span><span class='python'>attributes</span> on <code>CoarseFundamental</code> objects like you can with <code>Security</code> objects.</p>
<p>Note that the preceding <code>SelectionData</code> class uses a <a href="/docs/v2/writing-algorithms/indicators/manual-indicators">manual</a> EMA indicator instead of the <a href="/docs/v2/writing-algorithms/indicators/automatic-indicators">automatic version</a>. For more information about universes that select assets based on indicators, see <a href="/docs/v2/writing-algorithms/indicators/indicator-universes">Indicator Universes</a>. You need to use a <code>SelectionData</code> class instead of assigning the EMA to the <code>Fundamental</code> object because you can't create custom <span class="csharp">properties</span><span class="python">attributes</span> on <code>Fundamental</code> objects like you can with <code>Security</code> objects.</p>

<h4>Example 3: Take 10 stocks that are the furthest above their 10-day SMA of volume</h4>
<p>
Expand Down Expand Up @@ -142,12 +137,11 @@ <h4>Example 3: Take 10 stocks that are the furthest above their 10-day SMA of vo
</p>

<div class="section-example-container">
<pre class="python">def CoarseFilterFunction(self, coarse: List[CoarseFundamental]) -&gt; List[Symbol]:
for c in coarse:
if c.Symbol not in self.stateData:
self.stateData[c.Symbol] = SelectionData(c.Symbol, 10)
avg = self.stateData[c.Symbol]
avg.update(c.EndTime, c.AdjustedPrice, c.DollarVolume)
<pre class="python">def FundamentalFilterFunction(self, fundamental: List[Fundamental]) -&gt; List[Symbol]:
for f in fundamental:<br> if f.Symbol not in self.stateData:
self.stateData[f.Symbol] = SelectionData(f.Symbol, 10)
avg = self.stateData[f.Symbol]
avg.update(f.EndTime, f.AdjustedPrice, f.DollarVolume)

# filter the values of selectionData(sd) above SMA
values = [sd for sd in self.stateData.values() if sd.volume &gt; sd.sma.Current.Value and sd.volume_ratio &gt; 0]
Expand All @@ -159,13 +153,13 @@ <h4>Example 3: Take 10 stocks that are the furthest above their 10-day SMA of vo
return [ sd.symbol for sd in values[:10] ]
</pre>
<pre class="csharp">
IEnumerable&lt;Symbol&gt; CoarseFilterFunction(IEnumerable&lt;CoarseFundamental&gt; coarse) <br>{
return (from c in coarse
let avg = _stateData.GetOrAdd(c.Symbol, sym =&gt; new SelectionData(10))
where avg.Update(c.EndTime, c.Volume)
where c.Volume &gt; avg.VolumeSma
private IEnumerable&lt;Symbol&gt; FundamentalFilterFunction(IEnumerable&lt;Fundamental&gt; fundamental) <br>{
return (from f in fundamental
let avg = _stateData.GetOrAdd(f.Symbol, sym =&gt; new SelectionData(10))
where avg.Update(f.EndTime, f.Volume)
where f.Volume &gt; avg.VolumeSma
orderby avg.VolumeRatio descending
select c.Symbol).Take(10);
select f.Symbol).Take(10);
}</pre>
</div>

Expand All @@ -186,4 +180,4 @@ <h4>Example 4: Take the top 10 "fastest moving" stocks with a 50-Day EMA &gt; 20
DropboxUniverseSelectionAlgorithm.cs <span class="badge badge-sm badge-csharp pull-right">C#</span></a><a class="csharp example-algorithm-link" href="https://github.com/QuantConnect/Lean/blob/master/Algorithm.CSharp/WeeklyUniverseSelectionRegressionAlgorithm.cs" target="_BLANK">
WeeklyUniverseSelectionRegressionAlgorithm.cs <span class="badge badge-sm badge-csharp pull-right">C#</span></a><a class="csharp example-algorithm-link" href="https://github.com/QuantConnect/Lean/blob/master/Algorithm.CSharp/CoarseFineFundamentalComboAlgorithm.cs" target="_BLANK">
CoarseFineFundamentalComboAlgorithm.cs <span class="badge badge-sm badge-csharp pull-right">C#</span></a>
</div>
</div>

0 comments on commit a99128f

Please sign in to comment.