| Overall Statistics |
|
Total Orders 15433 Average Win 0.11% Average Loss -0.12% Compounding Annual Return 12.835% Drawdown 34.800% Expectancy 0.299 Start Equity 100000 End Equity 1214755.52 Net Profit 1114.756% Sharpe Ratio 0.429 Sortino Ratio 0.411 Probabilistic Sharpe Ratio 0.388% Loss Rate 33% Win Rate 67% Profit-Loss Ratio 0.95 Alpha 0.056 Beta 0.552 Annual Standard Deviation 0.208 Annual Variance 0.043 Information Ratio 0.141 Tracking Error 0.202 Treynor Ratio 0.161 Total Fees $19612.50 Estimated Strategy Capacity $75000000.00 Lowest Capacity Asset AGG SSC0EI5J2F6T Portfolio Turnover 6.98% |
# region imports
from AlgorithmImports import *
import statistics
# endregion
class MeasuredYellowGreenLemur(QCAlgorithm):
def initialize(self):
# Set start date
self.set_start_date(2000, 1, 1)
# Set cash
self.set_cash(100000)
# List of stocks/ETFs
list_of_tickers = ["SPY","IWM","QQQ","EWA","ASEA","GLD"]
# SMA fast dictionary
self.fast_dictionary = {}
# SMA slow dictionary
self.slow_dictionary = {}
# create lists to store the raw forecast values
self.raw_forecast_list_64 = []
self.raw_forecast_list_16 = []
self.scaled_forecast_list_16 = []
# Loop through list
for ticker in list_of_tickers:
# Register
equity = self.add_future(ticker = ticker, resolution = Resolution.Daily)
# Get symbol
symbol = equity.symbol
# Create slow SMA
EMA_object_slow = ExponentialMovingAverage(period = 256)
# Create fast SMA
EMA_object_fast = ExponentialMovingAverage(period = 64)
# Store SMA slow
self.slow_dictionary[symbol] = EMA_object_slow
# Store SMA fast
self.fast_dictionary[symbol] = EMA_object_fast
# Register SMA for automatic update
self.register_indicator(symbol, self.fast_dictionary[symbol])
# Register SMA for automatic update
self.register_indicator(symbol, self.slow_dictionary[symbol])
# ----------------------------------------------------------------------------------------------
# Add another period length for smas to calculate forecasts
# SMA fast dictionary
self.fast_16_dictionary = {}
# SMA slow dictionary
self.slow_64_dictionary = {}
# Loop through list
for ticker in list_of_tickers:
# Register
equity = self.add_equity(ticker = ticker, resolution = Resolution.Daily)
# Get symbol
symbol = equity.symbol
# Create slow SMA
EMA_object_slow = ExponentialMovingAverage(period = 64)
# Create fast SMA
EMA_object_fast = ExponentialMovingAverage(period = 16)
# Store SMA slow
self.slow_64_dictionary[symbol] = EMA_object_slow
# Store SMA fast
self.fast_16_dictionary[symbol] = EMA_object_fast
# Register SMA for automatic update
self.register_indicator(symbol, self.fast_16_dictionary[symbol])
# Register SMA for automatic update
self.register_indicator(symbol, self.slow_64_dictionary[symbol])
# ----------------------------------------------------------------------------------------------
# Add the standard deviation indicator to calculate the std of prices for each symbol
# STD dictionary
self.std_dictionary = {}
# Loop through list
for ticker in list_of_tickers:
# Register
equity = self.add_equity(ticker = ticker, resolution = Resolution.Daily)
# Get symbol
symbol = equity.symbol
# Create standard dev object
STD_object = StandardDeviation(35)
# Store STD
self.std_dictionary[symbol] = STD_object
# Register SMA for automatic update
self.register_indicator(symbol, self.std_dictionary[symbol])
def on_data(self, data: Slice):
# List to store invested symbols
invested_list = []
# Loop EMA dictionary
for symbol in self.fast_dictionary:
# If invested
if self.portfolio[symbol].invested == True:
# Add to invested list
invested_list.append(symbol)
# Get number of invested assets
assets_invested = len(invested_list)
# Get number of assets in algorithm
assets_in_algorithm = len(self.fast_dictionary)
# Get number of assets not invested
not_invested = assets_in_algorithm - assets_invested
# If not invested in all of the algorithm's assets
if not_invested != 0:
# Divide cash available by number of assets not invested
capital = self.portfolio.cash / not_invested
# If EMA fast and slow is ready
if self.fast_dictionary[symbol].is_ready == True and self.slow_dictionary[symbol].is_ready == True:
# Loop EMA dictionary
for symbol in self.fast_dictionary:
# Get the standard deviation of price points
risk_daily_price_points = self.std_dictionary[symbol].current.value
if risk_daily_price_points != 0:
# Calculate the normalised raw forecast for EWMA64
raw_forecast_64 = (self.fast_dictionary[symbol].current.value - self.slow_dictionary[symbol].current.value) / risk_daily_price_points
# Calculate the absolute raw forecast to add it to the list
absolute_raw_forecast = abs(raw_forecast_64)
# Append the value to the list
self.raw_forecast_list_64.append(absolute_raw_forecast)
# Calculate the forecast scalar
forecast_scalar = 10 / statistics.mean(self.raw_forecast_list_64)
# Calculate the scaled forecast by multiplying the scalar by the raw forecast
scaled_forecast_64 = raw_forecast_64 * 3.15
# Repeat the process for the EWMA16
raw_forecast_16 = (self.fast_16_dictionary[symbol].current.value - self.slow_64_dictionary[symbol].current.value) / risk_daily_price_points
absolute_raw_forecast_16 = abs(raw_forecast_16)
self.raw_forecast_list_16.append(absolute_raw_forecast_16)
forecast_scalar_16 = 10 / statistics.mean(self.raw_forecast_list_16)
scaled_forecast_16 = raw_forecast_16 * 8.91
absolute_scaled_forecast_16 = abs(scaled_forecast_16)
self.scaled_forecast_list_16.append(absolute_scaled_forecast_16)
mean_absolute_forecast = statistics.mean(self.scaled_forecast_list_16)
# Combine the two forecasts by calculating the average
combined_forecast = (scaled_forecast_64 + scaled_forecast_16) / 2
# If EMA fast and slow is ready
if self.fast_dictionary[symbol].is_ready == True and self.slow_dictionary[symbol].is_ready == True:
# If not invested enter into the position based on the forecast
if self.portfolio[symbol].invested == False:
# Calculate quantity
quantity = int((capital * combined_forecast / (self.securities[symbol].close * 10)))
# Submit market order
self.market_order(symbol = symbol, quantity = quantity)
# If invested then adjust the position based on the forecast
if self.portfolio[symbol].invested == True:
# Calculate quantity
quantity = int((self.portfolio.total_portfolio_value * combined_forecast / (self.securities[symbol].close * 10)))
# calculate the qunatity based on the difference between the old quantity and the new quantity
updated_quantity = quantity - self.portfolio[symbol].quantity
# Submit market order
self.market_order(symbol = symbol, quantity = updated_quantity)
# Plot the combined forecast
self.plot("combined_forecast", "forecast", combined_forecast)
# Plot the quantity of position
self.plot("forecast_scalar_16", "forecast_scalar_16", forecast_scalar_16)
# Plot the quantity of position
self.plot("position", "position", self.portfolio[symbol].quantity) # region imports
from AlgorithmImports import *
import statistics
# endregion
class MeasuredYellowGreenLemur(QCAlgorithm):
def initialize(self):
# Set start date
self.set_start_date(2004, 1, 1)
# Set cash
self.set_cash(100000)
# List of stocks/ETFs
list_of_tickers = ["SPY","GLD","XLE","AGG"]
# SMA fast dictionary
self.fast_dictionary = {}
# SMA slow dictionary
self.slow_dictionary = {}
# create lists to store the raw forecast values
self.raw_forecast_list_64 = []
self.raw_forecast_list_16 = []
self.scaled_forecast_list_16 = []
# Loop through list
for ticker in list_of_tickers:
# Register
equity = self.add_equity(ticker = ticker, resolution = Resolution.Daily, leverage = 6)
# Get symbol
symbol = equity.symbol
# Create slow SMA
EMA_object_slow = ExponentialMovingAverage(period = 256)
# Create fast SMA
EMA_object_fast = ExponentialMovingAverage(period = 64)
# Store SMA slow
self.slow_dictionary[symbol] = EMA_object_slow
# Store SMA fast
self.fast_dictionary[symbol] = EMA_object_fast
# Register SMA for automatic update
self.register_indicator(symbol, self.fast_dictionary[symbol])
# Register SMA for automatic update
self.register_indicator(symbol, self.slow_dictionary[symbol])
# ----------------------------------------------------------------------------------------------
# Add another period length for smas to calculate forecasts
# SMA fast dictionary
self.fast_16_dictionary = {}
# SMA slow dictionary
self.slow_64_dictionary = {}
# Loop through list
for ticker in list_of_tickers:
# Register
equity = self.add_equity(ticker = ticker, resolution = Resolution.Daily, leverage = 6)
# Get symbol
symbol = equity.symbol
# Create slow SMA
EMA_object_slow = ExponentialMovingAverage(period = 64)
# Create fast SMA
EMA_object_fast = ExponentialMovingAverage(period = 16)
# Store SMA slow
self.slow_64_dictionary[symbol] = EMA_object_slow
# Store SMA fast
self.fast_16_dictionary[symbol] = EMA_object_fast
# Register SMA for automatic update
self.register_indicator(symbol, self.fast_16_dictionary[symbol])
# Register SMA for automatic update
self.register_indicator(symbol, self.slow_64_dictionary[symbol])
# ----------------------------------------------------------------------------------------------
# Add the standard deviation indicator to calculate the std of prices for each symbol
# STD dictionary
self.std_dictionary = {}
# Loop through list
for ticker in list_of_tickers:
# Register
equity = self.add_equity(ticker = ticker, resolution = Resolution.Daily, leverage = 6)
# Get symbol
symbol = equity.symbol
# Create standard dev object
STD_object = StandardDeviation(35)
# Store STD
self.std_dictionary[symbol] = STD_object
# Register SMA for automatic update
self.register_indicator(symbol, self.std_dictionary[symbol])
def on_data(self, data: Slice):
# List to store invested symbols
invested_list = []
# Loop EMA dictionary
for symbol in self.fast_dictionary:
# If invested
if self.portfolio[symbol].invested == True:
# Add to invested list
invested_list.append(symbol)
# Get number of invested assets
assets_invested = len(invested_list)
# Get number of assets in algorithm
assets_in_algorithm = len(self.fast_dictionary)
# Get number of assets not invested
not_invested = assets_in_algorithm - assets_invested
# If not invested in all of the algorithm's assets
if not_invested != 0:
# Divide cash available by number of assets not invested
capital = self.portfolio.cash / not_invested
# If EMA fast and slow is ready
if self.fast_dictionary[symbol].is_ready == True and self.slow_dictionary[symbol].is_ready == True:
# Loop EMA dictionary
for symbol in self.fast_dictionary:
# Get the standard deviation of price points
risk_daily_price_points = self.std_dictionary[symbol].current.value
if risk_daily_price_points != 0:
# Calculate the normalised raw forecast for EWMA64
raw_forecast_64 = (self.fast_dictionary[symbol].current.value - self.slow_dictionary[symbol].current.value) / risk_daily_price_points
# Calculate the absolute raw forecast to add it to the list
absolute_raw_forecast = abs(raw_forecast_64)
# Append the value to the list
self.raw_forecast_list_64.append(absolute_raw_forecast)
# Calculate the forecast scalar
forecast_scalar = 10 / statistics.mean(self.raw_forecast_list_64)
# Calculate the scaled forecast by multiplying the scalar by the raw forecast
scaled_forecast_64 = raw_forecast_64 * 3.15
# Repeat the process for the EWMA16
raw_forecast_16 = (self.fast_16_dictionary[symbol].current.value - self.slow_64_dictionary[symbol].current.value) / risk_daily_price_points
absolute_raw_forecast_16 = abs(raw_forecast_16)
self.raw_forecast_list_16.append(absolute_raw_forecast_16)
forecast_scalar_16 = 10 / statistics.mean(self.raw_forecast_list_16)
scaled_forecast_16 = raw_forecast_16 * 8.6
absolute_scaled_forecast_16 = abs(scaled_forecast_16)
self.scaled_forecast_list_16.append(absolute_scaled_forecast_16)
mean_absolute_forecast = statistics.mean(self.scaled_forecast_list_16)
# Combine the two forecasts by calculating the average
combined_forecast = (scaled_forecast_64 + scaled_forecast_16) / 2
# If not invested and the forecast is positive enter into the position based on the forecast
if self.portfolio[symbol].invested == False and combined_forecast > 0 and self.securities[symbol].close != 0:
# Calculate quantity
quantity = int((combined_forecast * self.portfolio.total_portfolio_value * 0.25 * 3.57 / (self.securities[symbol].close * 10)))
# Submit market order
self.market_order(symbol = symbol, quantity = quantity)
# If invested then adjust the position based on the forecast
if self.portfolio[symbol].invested == True and combined_forecast > 0 and self.securities[symbol].close != 0:
# Calculate quantity
quantity = int((combined_forecast * self.portfolio.total_portfolio_value * 0.25 * 3.57 / (self.securities[symbol].close * 10)))
# calculate the qunatity based on the difference between the old quantity and the new quantity
updated_quantity = quantity - self.portfolio[symbol].quantity
# Submit market order
self.market_order(symbol = symbol, quantity = updated_quantity)
# Plot the combined forecast
self.plot("combined_forecast", "forecast", combined_forecast)
# Plot the quantity of position
self.plot("position", "position", self.portfolio[symbol].quantity)# region imports
from AlgorithmImports import *
# endregion
class MeasuredYellowGreenLemur(QCAlgorithm):
def initialize(self):
# Set start date
self.set_start_date(2001, 1, 1)
# Set cash
self.set_cash(100000)
# List of stocks/ETFs
list_of_tickers = ["SPY","IWM","QQQ","EWA","ASEA","GLD","SLV","USO","WEAT","CORN","PLTM","GBTC","FXE","FXY","EWO","CPER","SOYB","BNO","UGA"]
# SMA fast dictionary
self.fast_dictionary = {}
# SMA slow dictionary
self.slow_dictionary = {}
# Loop through list
for ticker in list_of_tickers:
# Register
equity = self.add_equity(ticker = ticker, resolution = Resolution.Daily, leverage = 8)
# Get symbol
symbol = equity.symbol
# Create slow SMA
EMA_object_slow = ExponentialMovingAverage(period = 128)
# Create fast SMA
EMA_object_fast = ExponentialMovingAverage(period = 32)
# Store SMA slow
self.slow_dictionary[symbol] = EMA_object_slow
# Store SMA fast
self.fast_dictionary[symbol] = EMA_object_fast
# Register SMA for automatic update
self.register_indicator(symbol, self.fast_dictionary[symbol])
# Register SMA for automatic update
self.register_indicator(symbol, self.slow_dictionary[symbol])
def on_data(self, data: Slice):
# List to store invested symbols
invested_list = []
# Loop MACD dictionary
for symbol in self.fast_dictionary:
# If invested
if self.portfolio[symbol].invested == True:
# Add to invested list
invested_list.append(symbol)
# Get number of invested assets
assets_invested = len(invested_list)
# Get number of assets in algorithm
assets_in_algorithm = len(self.fast_dictionary)
# Get number of assets not invested
not_invested = assets_in_algorithm - assets_invested
# If not invested in all of the algorithm's assets
if not_invested != 0:
# Divide cash available by number of assets not invested
cash_to_invest_in_each_additional_asset = self.portfolio.cash / not_invested
# Loop EMA dictionary
for symbol in self.fast_dictionary:
# If EMA fast and slow is ready
if self.fast_dictionary[symbol].is_ready == True and self.slow_dictionary[symbol].is_ready == True:
# If EMA fast is greater than EMA slow go long
if self.fast_dictionary[symbol].current.value > self.slow_dictionary[symbol].current.value:
# If not invested
if self.portfolio[symbol].invested == False:
# Calculate quantity
quantity = (int(cash_to_invest_in_each_additional_asset / self.securities[symbol].close)) * 8
# Submit market order
self.market_order(symbol = symbol, quantity = quantity)
# If EMA fast is less than EMA slow then exit
elif self.fast_dictionary[symbol].current.value < self.slow_dictionary[symbol].current.value:
# If invested
if self.portfolio[symbol].invested == True:
# Submit market order
self.market_order(symbol = symbol, quantity = -self.portfolio[symbol].quantity)