Anyone know how to build these in P123

Thank you both for your feedback.

It looks like you both are good at reading Phyton, is the code below, the Bold Aggressive version or one of Kelly’s other systems? And how to change this so that it becomes the aggressive version?

From what I understand, the only difference to the aggressive version is what comes from point 4 here:

> 4. If selecting from the offensive universe, select the 6 assets (balanced version) or 1 asset (aggressive version) with the highest relative momentum.
>
> Warning: The aggressive version of the strategy is going all in on a single risk asset. That’s a dangerous approach. We suggest minimizing that risk by combining multiple unrelated strategies together in a combined portfolio (something our platform was built to tackle).

Otherwise, https://www.quantconnect.com/ actually gives you the opportunity to run the system for free, so it is the possibility to examine there what is the last position.

#region imports
from AlgorithmImports import *
#endregion

#See: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4166845
import pandas as pd
import numpy as np

class BoldAssetAllocation(QCAlgorithm):

def Initialize(self):
    self.SetStartDate(2015,1,1)  # Set Start Date
    self.start_cash = 100000
    self.SetCash(self.start_cash)  # Set Strategy Cash
    self.SetBenchmark('SPY')
    
    # Algo Parameters
    self.prds = [1,3,6,12]
    self.prdwts = np.array([12,6,2,1])
    self.LO, self.LD, self.LP, self.B, self.TO, self.TD = [12,12,0,1,1,3]
    self.hprd = max(self.prds+[self.LO,self.LD])*21+50
    
    # Assets
    self.canary = ['SPY','EFA','EEM','BND']
    self.offensive = ['QQQ','EFA','EEM','BND']
    self.defensive = ['BIL','BND','DBC','IEF','LQD','TIP','TLT']
    self.safe = 'BIL'
    # repeat safe asset so it can be selected multiple times
    self.alldefensive = self.defensive + [self.safe] * max(0,self.TD - sum([1*(e==self.safe) for e in self.defensive]))
    self.eqs = list(dict.fromkeys(self.canary+self.offensive+self.alldefensive))
    for eq in self.eqs:
        self.AddEquity(eq,Resolution.Minute)
    
    # monthly rebalance
    self.Schedule.On(self.DateRules.MonthStart(self.canary[0]),self.TimeRules.AfterMarketOpen(self.canary[0],30),self.rebal)
    self.Trade = True
    
def rebal(self):
    self.Trade = True

def OnData(self, data):           
    if self.Trade:
        # Get price data and trading weights
        h = self.History(self.eqs,self.hprd,Resolution.Daily)['close'].unstack(level=0)
        wts = self.trade_wts(h)

        # trade
        port_tgt = [PortfolioTarget(x,y) for x,y in zip(wts.index,wts.values)]
        self.SetHoldings(port_tgt)
        
        self.Trade = False

def trade_wts(self,hist):
    # initialize wts Series
    wts = pd.Series(0,index=hist.columns)
    # end of month values
    h_eom = (hist.loc[hist.groupby(hist.index.to_period('M')).apply(lambda x: x.index.max())]
            .iloc[:-1,:])

    # =====================================
    # check if canary universe is triggered
    # =====================================
    # build dataframe of momentum values
    mom = h_eom.iloc[-1,:].div(h_eom.iloc[[-p-1 for p in self.prds],:],axis=0)-1
    mom = mom.loc[:,self.canary].T
    # Determine number of canary securities with negative weighted momentum
    n_canary = np.sum(np.sum(mom.values*self.prdwts,axis=1)<0)
    # % equity offensive 
    pct_in = 1-min(1,n_canary/self.B)

    # =====================================
    # get weights for offensive and defensive universes
    # =====================================
    # determine weights of offensive universe
    if pct_in > 0:
        # price / SMA
        mom_in = h_eom.iloc[-1,:].div(h_eom.iloc[[-t for t in range(1,self.LO+1)]].mean(axis=0),axis=0)
        mom_in = mom_in.loc[self.offensive].sort_values(ascending=False)
        # equal weightings to top relative momentum securities
        in_wts = pd.Series(pct_in/self.TO,index=mom_in.index[:self.TO])
        wts = pd.concat([wts,in_wts])
    # determine weights of defensive universe
    if pct_in < 1:
        # price / SMA
        mom_out = h_eom.iloc[-1,:].div(h_eom.iloc[[-t for t in range(1,self.LD+1)]].mean(axis=0),axis=0)
        mom_out = mom_out.loc[self.alldefensive].sort_values(ascending=False)
        # equal weightings to top relative momentum securities
        out_wts = pd.Series((1-pct_in)/self.TD,index=mom_out.index[:self.TD])
        wts = pd.concat([wts,out_wts])     
    
    wts = wts.groupby(wts.index).sum()

    return wts