Overall Statistics
Total Orders
327
Average Win
1.90%
Average Loss
-0.09%
Compounding Annual Return
27.557%
Drawdown
10.600%
Expectancy
0.816
Start Equity
100000
End Equity
143691.77
Net Profit
43.692%
Sharpe Ratio
1.011
Sortino Ratio
0.991
Probabilistic Sharpe Ratio
65.585%
Loss Rate
92%
Win Rate
8%
Profit-Loss Ratio
21.76
Alpha
0.169
Beta
-0.314
Annual Standard Deviation
0.138
Annual Variance
0.019
Information Ratio
0.193
Tracking Error
0.234
Treynor Ratio
-0.445
Total Fees
$681.47
Estimated Strategy Capacity
$10000000.00
Lowest Capacity Asset
SPY R735QTJ8XC9X
Portfolio Turnover
119.28%
from AlgorithmImports import *

class AlgorithmStatisticsAlgorithm(QCAlgorithm):
    _statistics = ["Time,Sharpe,Beta,95VaR"]

    def initialize(self) -> None:
        self.set_start_date(2024, 1, 1)
        #self.set_end_date(2024, 12, 30)
        self.set_cash(100000)

        # Request SPY data to trade.
        self.spy = self.add_equity("SPY").symbol
        # Create an EMA indicator to generate trade signals.
        self._ema = self.ema(self.spy, 20, Resolution.DAILY)
        # Warm-up indicator for immediate readiness.
        self.warm_up_indicator(self.spy, self._ema, Resolution.DAILY)

    def on_data(self, slice: Slice) -> None:
        bar = slice.bars.get(self.spy)
        if bar:
            # Trend-following strategy using price above or below EMA.
            # If the price is above EMA, SPY is in an uptrend, and we buy it.
            if bar.close > self._ema.current.value and not self.portfolio[self.spy].is_long:
                self.set_holdings(self.spy, 1)
            elif bar.close < self._ema.current.value and not self.portfolio[self.spy].is_short:
                self.set_holdings(self.spy, -1)

    def on_end_of_day(self, symbol: Symbol) -> None:
        # Obtain the algorithm statistics interested.
        sharpe = self.statistics.total_performance.portfolio_statistics.sharpe_ratio
        b = self.statistics.total_performance.portfolio_statistics.beta
        var = self.statistics.total_performance.portfolio_statistics.value_at_risk_95

        # Plot the statistics.
        self.plot("Statistics", "Sharpe", sharpe)
        self.plot("Statistics", "Beta", b)
        self.plot("Statistics", "Value-at-Risk", var)

        # Write to save the statistics.
        self._statistics.append(f'{self.time.strftime("%Y%m%d")},{sharpe},{b},{var}')

    def on_end_of_algorithm(self) -> None:
        # Save the logged statistics for later access in the object store.
        self.object_store.save(f'{self.project_id}/algorithm-statistics', '\n'.join(self._statistics))