From 3ffabfa14256da4e8b88ac8129251131d72449ae Mon Sep 17 00:00:00 2001 From: LouisSzeto Date: Tue, 3 Sep 2024 17:06:21 +0800 Subject: [PATCH 1/2] add us equity short example --- .../01 US Equity/07 Shorting/99 Examples.html | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 03 Writing Algorithms/03 Securities/99 Asset Classes/01 US Equity/07 Shorting/99 Examples.html diff --git a/03 Writing Algorithms/03 Securities/99 Asset Classes/01 US Equity/07 Shorting/99 Examples.html b/03 Writing Algorithms/03 Securities/99 Asset Classes/01 US Equity/07 Shorting/99 Examples.html new file mode 100644 index 0000000000..c74bb42ca4 --- /dev/null +++ b/03 Writing Algorithms/03 Securities/99 Asset Classes/01 US Equity/07 Shorting/99 Examples.html @@ -0,0 +1,139 @@ +

Example 1: Tim Sykes Alpha Model - Short Penny Stock Gainers

+

As a renowned millionaire penny stock trader, Tim Sykes gained his reputation through intra-day trading of short-selling peeny stocks that made him a billionaire. In this example, we aimed to create a simple strategy with a similar logic: short selling the low-cap penny stocks with the greatest gain on the previous day with Bollinger Band signals. The rule are as below:

+ +

We need to set up the daily filtering function first:

+
+
// Dictionary to cache last price for gain calculation
+private Dictionary<Symbol, decimal> _symbolLastPrices = new();
+
+public override void Initialize()
+{
+    // Add universe filtering function to obtain the low-cap penny stocks top gainers
+    AddUniverse(Selection)
+}
+
+private IEnumerable<Symbol> Selection(IEnumerable<Fundamental> fundamental)
+{
+    // Small-cap penny stocks
+    var filtered = fundamental.Where(x => x.MarketCap <= 5e6 && x.Price <= 1).ToList();
+    
+    var pctGain = new Dictionary<Symbol, decimal>();
+    // Iterate filtered stocks to calculate best gainers
+    foreach (var f in filtered)
+    {
+        // If not in dictionary, save last price and exit
+        if (!_symbolLastPrices.TryGetValue(f.Symbol, out var lastPrice))
+        {
+            lastPrice = _symbolLastPrices[f.Symbol] = f.Price;
+            continue;
+        }
+
+        // Cache the 1-day percentage change
+        var pctChg = (f.Price - lastPrice) / lastPrice;
+        pctGain.Add(f.Symbol, pctChg);
+
+        // Update last price
+        _symbolLastPrices[f.Symbol] = f.Price;
+    }
+
+    // Return the top 20 gainers
+    return pctGain.OrderByDescending(x => x.Value)
+        .Take(20)
+        .Select(x => x.Key);
+}
+
def initialize(self) -> None:
+    self.symbol_last_prices = None
+    # Add universe filtering function to obtain the low-cap penny stocks top gainers
+    self.add_universe(self.selection)
+
+def selection(self, fundamental: List[Fundamental]) -> List[Symbol]:
+    symbols = []
+    market_caps = []
+    prices = []
+    # Iterate stocks to get market cap and price
+    for f in fundamental:
+        symbols.append(f.symbol)
+        market_caps.append(f.market_cap)
+        prices.append(f.price)
+    df = pd.DataFrame({"Symbol": symbols, "MarketCap": market_caps, "Price": prices}).set_index("Symbol")
+    
+    # Filter the stocks
+    df = df[(df["MarketCap"] <= 5e6) & (df["Price"] <= 1)]
+
+    # Calculate the percentage change
+    top_gainers = []
+    if self.symbol_last_prices:
+        pct_chg = (df["Price"] - self.symbol_last_prices["Price"]) / self.symbol_last_prices["Price"]
+        # Get the top 20 gainers
+        top_gainers = list(pct_chg.nlargest(20).index)
+
+    # Update last price
+    self.symbol_last_prices = df
+    
+    return top_gainers
+
+ +

Then, we need to create a BollingerBand indicator for the universe members.

+
+
public override void OnSecuritiesChanged(SecurityChanges changes)
+{
+    // Iterate new members
+    foreach (var added in changes.AddedSecurities)
+    {
+        var security = added as dynamic;
+        // Create a BollingerBand indicator
+        security.BBands = BB(added.Symbol, 20, Resolution.Minute);
+        // Add a handler for trading
+        security.BBands.Updated += OnBBUpdate;
+    }
+}
+
def on_securities_changed(self, changes: SecurityChanges) -> None:
+    # Iterate new members
+    for added in changes.added_securities:
+        # Create a BollingerBand indicator
+        added._bbands = self.bb(added.symbol, 20, Resolution.MINUTE)
+        # Add a handler for trading
+        added._bbands.updated += self.on_bb_updated
+
+ +

Finally, trade the stocks through the indicator update handler.

+
+
private void OnBBUpdate(object sender, IndicatorDataPoint point)
+{
+    var price = Securities[point.Symbol].Price;
+    // Check if the stock is invested
+    if (!Portfolio[point.Symbol].Invested)
+    {
+        // Trade if short sell criteria met
+        if (price > sender.UpperBand.Current.Value)
+        {
+            SetHoldings(point.Symbol, -0.05m);
+        }
+    }
+    else
+    {
+        // Exit if invested and price drop below middle band
+        if (price < sender.MiddleBand.Current.Value)
+        {
+            Liquidate(point.Symbol)
+        }
+    }
+}
+
def on_securities_changed(self, sender: object, point: IndicatorDataPoint) -> None:
+    price = self.securities[point.symbol].price
+    # Check if the stock is invested
+    if not self.portfolio[point.symbol].invested:
+        # Trade if short sell criteria met
+        if price < sender.upper_band.current.value:
+            self.set_holdings(point.symbol, -0.05)
+    else:
+        # Exit if invested and price drop below middle band
+        price < sender.middle_band.current.value:
+            self.liquidate(point.symbol)
+
\ No newline at end of file From 879e5687ab5bfcc38c64f14981423665cde35ea4 Mon Sep 17 00:00:00 2001 From: Jared Date: Wed, 11 Sep 2024 08:53:49 -0400 Subject: [PATCH 2/2] Update 99 Examples.html --- .../01 US Equity/07 Shorting/99 Examples.html | 104 ++++++++---------- 1 file changed, 46 insertions(+), 58 deletions(-) diff --git a/03 Writing Algorithms/03 Securities/99 Asset Classes/01 US Equity/07 Shorting/99 Examples.html b/03 Writing Algorithms/03 Securities/99 Asset Classes/01 US Equity/07 Shorting/99 Examples.html index c74bb42ca4..0da10875e5 100644 --- a/03 Writing Algorithms/03 Securities/99 Asset Classes/01 US Equity/07 Shorting/99 Examples.html +++ b/03 Writing Algorithms/03 Securities/99 Asset Classes/01 US Equity/07 Shorting/99 Examples.html @@ -1,13 +1,5 @@ -

Example 1: Tim Sykes Alpha Model - Short Penny Stock Gainers

-

As a renowned millionaire penny stock trader, Tim Sykes gained his reputation through intra-day trading of short-selling peeny stocks that made him a billionaire. In this example, we aimed to create a simple strategy with a similar logic: short selling the low-cap penny stocks with the greatest gain on the previous day with Bollinger Band signals. The rule are as below:

- -

We need to set up the daily filtering function first:

+

Example 1: Short Penny Stock Gainers

+

This example builds a universe of low-cap penny stocks (below $1) that showed the greatest gain on the previous day. It uses an intraday Bollinger Band indicator to time entry and exit.

// Dictionary to cache last price for gain calculation
 private Dictionary<Symbol, decimal> _symbolLastPrices = new();
@@ -20,7 +12,7 @@ 

Example 1: Tim Sykes Alpha Model - Short Penny Stock Gainers

private IEnumerable<Symbol> Selection(IEnumerable<Fundamental> fundamental) { - // Small-cap penny stocks + // Select the small-cap penny stocks with a price less than $1. var filtered = fundamental.Where(x => x.MarketCap <= 5e6 && x.Price <= 1).ToList(); var pctGain = new Dictionary<Symbol, decimal>(); @@ -42,10 +34,45 @@

Example 1: Tim Sykes Alpha Model - Short Penny Stock Gainers

_symbolLastPrices[f.Symbol] = f.Price; } - // Return the top 20 gainers + // Return Symbols of the top 20 gainers return pctGain.OrderByDescending(x => x.Value) .Take(20) .Select(x => x.Key); +} + +public override void OnSecuritiesChanged(SecurityChanges changes) +{ + // Iterate new universe members to setup the indicators + foreach (var added in changes.AddedSecurities) + { + var security = added as dynamic; + // Create an automatically updated BollingerBand indicator + security.BBands = BB(added.Symbol, 20, Resolution.Minute); + // Add a handler for trading + security.BBands.Updated += OnBBUpdate; + } +} + +private void OnBBUpdate(object sender, IndicatorDataPoint point) +{ + var price = Securities[point.Symbol].Price; + // Check if the stock is invested + if (!Portfolio[point.Symbol].Invested) + { + // Trade if short sell criteria met + if (price > sender.UpperBand.Current.Value) + { + SetHoldings(point.Symbol, -0.05m); + } + } + else + { + // Exit if invested and price drop below middle band + if (price < sender.MiddleBand.Current.Value) + { + Liquidate(point.Symbol) + } + } }
def initialize(self) -> None:
     self.symbol_last_prices = None
@@ -76,56 +103,17 @@ 

Example 1: Tim Sykes Alpha Model - Short Penny Stock Gainers

# Update last price self.symbol_last_prices = df - return top_gainers
-
- -

Then, we need to create a BollingerBand indicator for the universe members.

-
-
public override void OnSecuritiesChanged(SecurityChanges changes)
-{
-    // Iterate new members
-    foreach (var added in changes.AddedSecurities)
-    {
-        var security = added as dynamic;
-        // Create a BollingerBand indicator
-        security.BBands = BB(added.Symbol, 20, Resolution.Minute);
-        // Add a handler for trading
-        security.BBands.Updated += OnBBUpdate;
-    }
-}
-
def on_securities_changed(self, changes: SecurityChanges) -> None:
-    # Iterate new members
+    return top_gainers
+	
+def on_securities_changed(self, changes: SecurityChanges) -> None:
+    # Iterate new members to create an automatically updated BollingerBand indicator
     for added in changes.added_securities:
         # Create a BollingerBand indicator
         added._bbands = self.bb(added.symbol, 20, Resolution.MINUTE)
         # Add a handler for trading
-        added._bbands.updated += self.on_bb_updated
-
+ added._bbands.updated += self.on_bb_updated -

Finally, trade the stocks through the indicator update handler.

-
-
private void OnBBUpdate(object sender, IndicatorDataPoint point)
-{
-    var price = Securities[point.Symbol].Price;
-    // Check if the stock is invested
-    if (!Portfolio[point.Symbol].Invested)
-    {
-        // Trade if short sell criteria met
-        if (price > sender.UpperBand.Current.Value)
-        {
-            SetHoldings(point.Symbol, -0.05m);
-        }
-    }
-    else
-    {
-        // Exit if invested and price drop below middle band
-        if (price < sender.MiddleBand.Current.Value)
-        {
-            Liquidate(point.Symbol)
-        }
-    }
-}
-
def on_securities_changed(self, sender: object, point: IndicatorDataPoint) -> None:
+def on_bb_updated(self, sender: object, point: IndicatorDataPoint) -> None:
     price = self.securities[point.symbol].price
     # Check if the stock is invested
     if not self.portfolio[point.symbol].invested:
@@ -136,4 +124,4 @@ 

Example 1: Tim Sykes Alpha Model - Short Penny Stock Gainers

# Exit if invested and price drop below middle band price < sender.middle_band.current.value: self.liquidate(point.symbol)
-
\ No newline at end of file +