Overall Statistics
Total Orders
2967
Average Win
0.32%
Average Loss
-0.18%
Compounding Annual Return
68.095%
Drawdown
50.500%
Expectancy
0.777
Start Equity
100000
End Equity
797264.98
Net Profit
697.265%
Sharpe Ratio
1.196
Sortino Ratio
1.965
Probabilistic Sharpe Ratio
47.263%
Loss Rate
37%
Win Rate
63%
Profit-Loss Ratio
1.80
Alpha
0.487
Beta
0.945
Annual Standard Deviation
0.471
Annual Variance
0.222
Information Ratio
1.105
Tracking Error
0.437
Treynor Ratio
0.596
Total Fees
$5376.27
Estimated Strategy Capacity
$690000.00
Lowest Capacity Asset
CVI TX15LMGOX205
Portfolio Turnover
2.81%
#region imports
from AlgorithmImports import *
#endregion
from AlgorithmImports import *
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
class LiquidValueStocks(QCAlgorithm):

    def Initialize(self):
        self.set_start_date(2020, 1, 1)
        self.set_end_date(2024, 1, 1)
        self.set_cash(100000)
        self.universe_settings.resolution = Resolution.HOUR
        self.add_universe_selection(OperationIncomeGrowthtoPE())
        
        self.add_alpha(PeterLynchAlphaModel())
        
        self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
        self.set_execution(ImmediateExecutionModel())
        #self.add_risk_management(MaximumDrawdownPercentPerSecurity(0.2))

class OperationIncomeGrowthtoPE(FundamentalUniverseSelectionModel):
    
    def __init__(self):
        super().__init__(True, None)
        self.last_month = -1 
        
    def select_coarse(self, algorithm, coarse):
        if self.last_month == algorithm.time.month:
            return Universe.UNCHANGED
        self.last_month = algorithm.time.month

        sorted_by_dollar_volume = sorted([x for x in coarse if x.has_fundamental_data],
            key=lambda x: x.dollar_volume, reverse=True)

        return [x.symbol for x in sorted_by_dollar_volume[:1000]]

    def select_fine(self, algorithm, fine):
        filter = [f for f in fine if (f.operation_ratios.operation_income_growth.one_year/f.valuation_ratios.pe_ratio) > 1]
        universe = filter[:20]
        return [f.symbol for f in universe]

class PeterLynchAlphaModel(AlphaModel):

    def __init__(self):
        self.last_month = -1

    def update(self, algorithm, data):
        insights = []
        
        if self.last_month == algorithm.time.month:
            return insights
        self.last_month = algorithm.time.month
        
        for security in algorithm.active_securities.values:
            insights.append(Insight.price(security.symbol, timedelta(28), InsightDirection.UP)) 
        return insights