| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Sortino Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.443 Tracking Error 0.149 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
import pandas as pd
import numpy as np
import math
from datetime import datetime, timedelta
### INITIALIZE
# Variables
stocks = ["SPK","WPP","CCV","DVN","CYG","SDI","DTL","MAH","REH","TAH","GRR","AIA","NCM","ORI","AVJ","MCR","CLV","IGO","GME","ALL","HAV","SEN","WEB","MGX","WOR","SBM","OZL","IMD","AUZ","ANG","RMS","PAN","OMH","CVN","NHC","MTS","X64","JBH","SLR","QTM","OGC","CCX","FLT","GAP","MAY","VMG","AMA","DDT","MLX","GEM","RRL","ILU","VYS","CGM","PHX","JIN","SYD","AGI","CAJ","IFM","NEA","IMS","VMT","GOR","RHT","ELD","VPR","EGH","ADA","BAR","NWH","NAE","BSE","WHC","BCN","LYC","OLI","BAL","BYE","EHL","DCC","ACF","RED","ALK","M7T","HTG","TPW","HT8","ZNO","MGV","ICI","RNT","MAI","FSG","AIS","BRK","ATP","TER","SMR","NEU","CTT","SMP","MIL","MP1","CBA","DLC","ASB","SGP","SWM","TNE","IRI","RDF","AAR","IPL","CIM","AJL","APA","ACR","NST","FDM","PDZ","CDA","FNP","CSS","RHP","QAN","PXS","CMP","SSM","LPD","AMI","PYC","WTC","CGR","ADH","LNY","PME","ZIP","CXZ","AEF","ESK","OEC","TNT","JPR","AQS","LCY","NGY","EGL","IDT","JLG","CRN","BRL","YAL","DUR","LAU","DUG","360","SVW","CIA","BLD","A2B","JHX",]
portfolio_value = 10000
weight = 0.10
start_date = "2002-01-31"
end_date = "2023-12-31"
# Universe selection
universe = pd.read_csv("C:/Users/jerem/LeanCLI/data/asx_fundamentals\ASX Piotroski Universe Selection.csv", header=None, index_col=0)
universe.fillna('', inplace=True)
# Gather price data
stock_data = pd.DataFrame(columns=stocks)
stock_data['date'] = []
stock_data.set_index('date', inplace=True)
for stock in stocks:
data = pd.read_csv("C:/Users/jerem/LeanCLI/data/asx_prices/{} Price Data.csv".format(stock), index_col='date')
stock_data[stock] = data['adjusted_close']
# Set initial shares on first day
shares_df = pd.DataFrame(index=[universe.loc[start_date].index])
for s in universe.loc[start_date]:
if s != '':
shares_df[s + '_shares'] = np.floor((portfolio_value * weight) / stock_data[s][0])
### REBALANCING ENGINE
# Variables
balance_date = datetime.strptime(start_date, "%Y-%m-%d")
balance_month = balance_date.month
count = 0
prev_values = {}
"""for day in stock_data.index:
count += 1
if day.month != balance_month:
signal = True
new_shares = universe.loc[balance_date]"""
print(shares_df)# region imports
from datetime import date, datetime, timedelta
from AlgorithmImports import *
from QuantConnect.Data import BaseData, SubscriptionDataConfig
from QuantConnect.Python import PythonData
from QuantConnect import Globals, SubscriptionTransportMedium
import os
# endregion
class ASXPiotroski(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2002, 1, 1)
self.SetEndDate(2023, 12, 31)
self.SetAccountCurrency("AUD")
self.SetCash(10000)
self.SetBrokerageModel(BrokerageName.QuantConnectBrokerage, AccountType.Margin)
self.SetSecurityInitializer(self.CustomSecurityInitializer)
# Add Custom Universe
self.AddUniverse(StockDataSource, "ASX_Piotroski_Universe", self.selector_function)
self.UniverseSettings.Resolution = Resolution.Daily
# Variables
self.stoploss = -0.1
self.num_fine = 10
self.data_uploaded = []
# Rebalancing
self.month = 0
def CustomSecurityInitializer(self, security):
security.SetLeverage(2)
def selector_function(self, data):
list = []
for item in data:
for symbol in item["Symbols"]:
list.append(symbol)
if symbol not in self.data_uploaded:
self.AddData(CustomOHLC, symbol, Resolution.Daily)
self.data_uploaded.append(symbol)
return list
def OnData(self, slice: Slice):
if self.IsWarmingUp: return
for security in self.ActiveSecurities.Values:
if slice.ContainsKey(security.Symbol):
custom_data = slice[security.Symbol]
close = custom_data.Value
else:
return
for symbol in self.Portfolio.Keys:
pnl = self.Securities[symbol].Holdings.UnrealizedProfitPercent
if pnl < self.stoploss:
self.Liquidate(symbol, "Stop Loss initiated.")
def OnSecuritiesChanged(self, changes):
# Liquidate removed securities
for security in changes.RemovedSecurities:
self.Liquidate(security.Symbol, "Removed from universe")
self.Log(str(security.Symbol) + " has been removed from the universe.")
# Purchase added securities
for security in changes.AddedSecurities:
self.SetHoldings(security.Symbol, 1/self.num_fine * security.Leverage, False, "Added to universe")
self.Log(str(security.Symbol) + " has been added to the universe.")
class StockDataSource(PythonData):
def GetSource(self,
config: SubscriptionDataConfig,
date: datetime,
isLiveMode: bool) -> SubscriptionDataSource:
source = os.path.join(Globals.DataFolder,"asx_fundamentals/ASX Piotroski Universe Selection.csv")
return SubscriptionDataSource(source, SubscriptionTransportMedium.LocalFile)
def Reader(self,
config: SubscriptionDataConfig,
line: str,
date: datetime,
isLive: bool) -> BaseData:
if not (line.strip() and line[0].isdigit()): return None
stocks = StockDataSource()
stocks.Symbol = config.Symbol
try:
csv = line.split(',')
csv = list(filter(None,csv))
stocks.Time = datetime.strptime(csv[0], "%Y-%m-%d")
stocks.EndTime = stocks.Time + timedelta(days=1)
stocks["Symbols"] = csv[1:]
except ValueError:
return None
return stocks
class CustomOHLC(PythonData):
def GetSource(self,
config: SubscriptionDataConfig,
date: datetime,
isLiveMode: bool) -> SubscriptionDataSource:
symbol = config.Symbol.Value.split(" ")[0]
source = os.path.join(Globals.DataFolder,"asx_prices/{} Price Data.csv".format(symbol))
return SubscriptionDataSource(source, SubscriptionTransportMedium.LocalFile)
def Reader(self,
config: SubscriptionDataConfig,
line: str,
date: datetime,
isLive: bool) -> BaseData:
if not (line.strip() and line[0].isdigit()): return None
ohlc = CustomOHLC()
ohlc.Symbol = config.Symbol
try:
data = line.split(',')
ohlc.Time = datetime.strptime(data[0], "%Y-%m-%d")
ohlc.EndTime = ohlc.Time + timedelta(days=1)
ohlc.Value = data[5]
ohlc["open"] = float(data[1])
ohlc["high"] = float(data[2])
ohlc["low"] = float(data[3])
ohlc["close"] = float(data[4])
except ValueError:
return None
return ohlc