Monday, June 26, 2023

Money Hustle

Following up on prior entries related to the stock market and market timing strategies, I’d like to present the following article for review:

https://prosperitythinkers.com/personal-finance/three-monkeys-and-cat-pick-stocks/

This article will be the topic for today’s post.

Returning again to the wisdom of Burton Malkiel, who was the subject of our last article, we find this sage of finance being quoted as stating,

“A blindfolded monkey throwing darts at a newspaper’s financial pages could select a portfolio that would do just as well as one carefully selected by experts.”

It would seem that some researchers took this quote a bit too literally as the article suggests, and decided to perform variations of the above described experiment.

The article discusses these contests of stock picking in detail. As apparently, in different instances, a cat, school children, and dart throwers, were employed to discern differing investment portfolios. In each instance described, the seemingly random selection of equities, regardless of the employed methodologies, outperformed both actively managed funds, and broad indexes.

I decided to perform my own trial research as it relates to this sort investment approach.

#### WARNING – INVESTMENT OF ANY SORT BEARS RISK! THIS ARTICLE IS NOT FINANCIAL ADVICE! DO NOT REPLICATE THIS EXPERIMENT AND EXPECT TO MAKE MONEY! ####

First, I chose a few financial benchmarks.

AI Powered Equity ETF (AIEQ) – An ETF which is described as, “AIEQ uses artificial intelligence to analyze and identify US stocks believed to have the highest probability of capital appreciation over the next 12 months, while exhibiting volatility similar to the overall US market. The fund selects 30 to 125 constituents and has no restrictions on the market cap of its included securities. The model suggests weights based on capital appreciation potential and correlation to other included companies, subject to a 10% cap per holding. It is worth noting that while AIEQ relies heavily on its quantitative model, the fund is actively-managed, and follows no index.”

Source: https://www.etf.com/AIEQ

Fidelity Magellan Fund (FMAGX) – A famous actively managed mutual fund which possess the following strategy, “The Fund seeks capital appreciation. Fidelity Management & Research may buy "growth" stocks or "value" stocks or a combination of both. They rely on fundamental analysis of each issuer and its potential for success in light of its current financial condition, its industry position, and economic and market conditions.”

Source: https://www.marketwatch.com/investing/fund/fmagx

Vanguard Total Stock Market Index Fund (VTSAX) – Description provided, “Created in 1992, Vanguard Total Stock Market Index Fund is designed to provide investors with exposure to the entire U.S. equity market, including small-, mid-, and large-cap growth and value stocks. The fund’s key attributes are its low costs, broad diversification, and the potential for tax efficiency. Investors looking for a low-cost way to gain broad exposure to the U.S. stock market who are willing to accept the volatility that comes with stock market investing may wish to consider this fund as either a core equity holding or your only domestic stock fund.”

Source: https://investor.vanguard.com/investment-products/mutual-funds/profile/vtsax

With these benchmarks defined, I set off too to create my own randomly established equity fund. To fairly decide which equities my fund would hold, I utilized the two websites:

https://www.rayberger.org/random-stock-picker/ 

~AND~

https://www.randstock.ca/selector

The only equity selections which I outright rejected from inclusion were fixed income ETFs, and ETFs which sought to replicate the performance of a commodity.

All funds would receive an equal allocations of capital ($ 1000), and the initial issue price of my Random Fund would be set at $ 10.00 a share.

Oshkosh Corporation (OSK) - Oshkosh Corporation designs, manufacture, and markets specialty trucks and access equipment vehicles worldwide. Sector(s): Industrials

Franklin FTSE Brazil ETF (FLBR) - The FTSE Brazil Capped Index is based on the FTSE Brazil Index and is designed to measure the performance of Brazilian large- and mid-capitalization stocks.  Sector(s): ETF

Public Storage (PSA) - Public Storage, a member of the S&P 500 and FT Global 500, is a REIT that primarily acquires, develops, owns, and operates self-storage facilities. Sector(s) - Real Estate

Dorian LPG Ltd. (LPG) - Dorian LPG Ltd., together with its subsidiaries, engages in the transportation of liquefied petroleum gas (LPG) through its LPG tankers worldwide. The company owns and operates very large gas carriers (VLGCs). Sector(s) - Energy

Delta Air Lines, Inc. (DAL) - Delta Air Lines, Inc. provides scheduled air transportation for passengers and cargo in the United States and internationally. Sector(s) – Industrials

Grupo Industrial Saltillo, S.A.B. de C.V. (SALT) (MX) - Grupo Industrial Saltillo, S.A.B. de C.V. engages in the design, manufacture, wholesale, and marketing of products for automotive, construction, and houseware industries in Mexico, Europe, and Asia. Sector(s) - Consumer Cyclical

Equity LifeStyle Properties, Inc. (ELS) - We are a self-administered, self-managed real estate investment trust (REIT) with headquarters in Chicago. Sector(s) – Real Estate

SPDR Portfolio S&P 500 ETF (SPLG) - Under normal market conditions, the fund generally invests substantially all, but at least 80%, of its total assets in the securities comprising the index. Sector(s) – ETF

DHT Holdings, Inc. (DHT)
- DHT Holdings, Inc., through its subsidiaries, owns and operates crude oil tankers primarily in Monaco, Singapore, and Norway. As of March 16, 2023, it had a fleet of 23 very large crude carriers. Sector(s) - Energy

Norfolk Southern Corporation (NSC) - Norfolk Southern Corporation, together with its subsidiaries, engages in the rail transportation of raw materials, intermediate products, and finished goods in the United States. Sector(s) – Industrials

With a purchase date of each equity being set at 5/1/2019 (closing price), our fictitious Random Fund performed as shown below:

               
Now let’s compare the fund’s performance against our previously decided upon benchmarks:



Graphing the performance of each fund across multiple years:



Or looking at returns over the span of a five year period:



Strangely enough, our Random Fund outperforms the advisor managed fund (Magellan Fund), the broad based index fund (VTSAX), and the AI managed fund (AIEQ). While actively managed funds typically underperform index benchmarks for a multitude of reasons, I found it incredibly odd that my e-monkey Random Fund outperformed even the index itself. This is also what happened to be the case in the similarly conducted experiments mentioned within the article.

Let’s think of a few informed reasons as to why this might be:

1. Actively managed funds often turn over equities with far greater frequency when compared to their index counterparts. Index funds typically owe the majority of their equity turnover to modifications made to the underlying index. This causes both tax implications, and a lack of dividend opportunities.

2. Our Random Fund contains less components, and is less balanced than its competitors. Therefore, we would expect the fund to be more generally impacted by variance. In bull markets, I would expect such a selection of equities to outperform an underlying index. However, in bear markets, the inverse should hold true. In that, our Random Fund would likely lose more value than its contemporaries.

3. The time frame which is being utilized to assess performance is both short in duration and directionally positive for equities.

4. Actively managed funds attempt to protect investors from downside, which also limits the upside potential for returns.

5. As it relates to #5, actively managed funds must also keep greater amounts of cash and cash equivalents on hand. This equates to time out of the market.

6. Actively managed funds have higher management fees, which are utilized to compensate fund managers.

7. Index components are themselves, popular equities. This means that incoming investment money either chases the price of individual equites upward through individual stock purchase, or through periodic fund purchases.

8. Randomly selecting equities is far less biased than making an “informed selection”. Such bias often manifests in vastly over-estimating ones abilities, and under-assessing the abilities of others. Such an over estimation may cause an individual manager to go overweight in a particular sector or individual equity, and in doing such, miss opportunities elsewhere. As indexes are broad, there is always the exposure to opportunity within a bull market. This combined with the other previously numbered aspects, likely partially explains the underperformance of actively managed funds.

9. As it relates to point #9. In a bull market, over a short time span, randomly selecting a small number of equities may be the best method to employing a strategy which beats alpha. As bias will be eliminated, and beta will be increased.

10. Active fund managers may not possess the fiduciary ability to allow their investment strategies to materialize. As the annual alpha is always the metric which high net worth clients measure all performance against, an informed, but otherwise risk incurring position must deliver results in the intermediate term, or risk liquidation at a loss in both capital and opportunity. 

That's all for today.

Until next time, stay curious data heads!

-RD

Saturday, June 17, 2023

(R) Is Wall Street Random?


Anyone who has spent any serious time within the investment world, has probably at some point, encountered the book, A Random Walk Down Wall Street. While the book does contain some interesting historical anecdotes, and disproves numerous methods of stock picking quackery, the title itself refers to the following theory:

Burton G. Malkiel, an economics professor at Princeton University and writer of A Random Walk Down Wall Street, performed a test where his students were given a hypothetical stock that was initially worth fifty dollars. The closing stock price for each day was determined by a coin flip. If the result was heads, the price would close a half point higher, but if the result was tails, it would close a half point lower. Thus, each time, the price had a fifty-fifty chance of closing higher or lower than the previous day. Cycles or trends were determined from the tests. Malkiel then took the results in chart and graph form to a chartist, a person who "seeks to predict future movements by seeking to interpret past patterns on the assumption that 'history tends to repeat itself'." The chartist told Malkiel that they needed to immediately buy the stock. Since the coin flips were random, the fictitious stock had no overall trend. Malkiel argued that this indicates that the market and stocks could be just as random as flipping a coin.

Source: https://en.wikipedia.org/wiki/Random_walk_hypothesis

It would seem that within the field of contemporary finance, that some critics believe that Malkiel's book is prefaced upon a flawed theory. In this article, we will perform our own analysis in order to determine which side is correct in their assumption. This isn’t to in any way to provide further evidence to either side as it pertains to the ages old: Managed Fund vs. Index Fund argument, but instead, to utilize the evidence which we have as it pertains to this purposed theory, and see if it withstands a thorough statistical assessment.

Random Walking

To begin our foray into proving / disproving, “The Random Walk Hypothesis”, let’s take a random walk through R-Studio.

First, we’ll set a number of sample observations (n = 101). Then, we’ll perform the same experiment that Malkiel performed with his students. We’ll do this by randomly generating two numbers (-1, 1), with 1 equating a step upward, and -1 equating a step downwards.

However, we’ll make a few slight modifications to our experiment. As prices for an equity index cannot (theoretically) go negative, or in most cases, reach zero only to rebound, I’ve added a few caveats to our simulation.

We will be creating a random walk. However, in every instance in which our random walk would take us below a zero threshold, an absolute value of the outcome will instead be returned. For example, in the case of a typical random walk, the values: (1,-1,1,-1,-1,-1), provide the corresponding cumulative elements of: (1,0,1,0,-1,-2), as each element is being summed against the previous sum of the prior elements.


Example:

Random Walk Generated Values = {1,-1,1,-1,-1,-1}

0 + 1 = 1

1 – 1 = 0

0 + 1 = 1

1 – 1 = 0

0 – 1 = -1

-1 – 1 = -2

Thus, our cumulative elements are:

0 + 1 = 1

1 – 1 = 0

0 + 1 = 1

1 – 1 = 0

0 – 1 = -1

-1 – 1 = -2

In our variation of the simulation, instead of returning negative values, we will only return the absolute values of the cumulative elements. 

Example:

|1| = 1

|0| = 0

|1| = 1

|0| = 0

|-1| = 1

|-2| = 2


Another modification that we will be making, is that every element of 0 will be changed to the value of 1. 


Example:

1 = 1

0 = 1

1 = 1

0 = 1

1 = 1

2 = 2

# Set the random seed to 7 so that this example’s outcome can be reproduced #

set.seed(7)

# 101 random elements are needed for our example #

n <- 101

# Create a random walk with caveats (absolute values returned for negative numbers) #

Random_Walk <- abs(cumsum(sample(c(-1, 1), n, TRUE)))

# Further modify the random walk values (values of 0 will be modified to 1) #

Random_Walk <- ifelse(Random_Walk == 0, 1, Random_Walk)

# We’ll be attempting to simulate Dow Index returns from 1923 – 2023 #

year <- 1923:2023

# Graph the Random_Walk simulation #

Random_Walk_Plot <- data.frame(year, Random_Walk)

plot(Random_Walk_Plot, type = "l", xlim = c(1923, 2023), ylim = c(0, 30),

    col = "blue", xlab = "Year", ylab = "Random Walk")


This produces the following graphic:



Which in some ways resembles:


Let’s overlay a resized version of the random walk graphic against the Dow Jones Industrial Average’s annualized returns:


Obviously, this proves nothing. It only demonstrates that by selectively choosing a randomly generated pattern, that one can draw aesthetic comparisons to an existing pattern. 

Instead of taking the Random Walk Hypothesis at face value, or postulating ill-informed criticisms, let’s attack this hypothesis like good data scientists. First, we’ll forget about amateurish comparative assessment, and run a few tests in order to make a well researched conclusion. 

To test as to whether or not the market is random, we’ll need real world (US) market data. Of the available indexes, I decided to choose the Dow Jones Industrial Average. The reasons supporting this decision are as follows: 


1. The S&P 500 Stock Composite Index was not created until March of 1957. Therefore, not as many data points are available as compared to the Dow Jones Industrial Average.

2. The NASDAQ Composite Index was not created until February of 1971. It also lacks the broad market exposure which is found within the Dow Jones Industrial Average.

The data gathered to perform the following analysis, which also provided the Dow Jones Annual Average graphic above, originated from the source below.

Source: https://www.macrotrends.net/1319/dow-jones-100-year-historical-chart


# Dow Jones Industrial Average Years Vector #

Dow_Year <- c(2023, 2022, 2021, 2020, 2019, 2018, 2017, 2016, 2015, 2014, 2013, 2012, 2011, 2010, 2009, 2008, 2007, 2006, 2005, 2004, 2003, 2002, 2001, 2000, 1999, 1998, 1997, 1996, 1995, 1994, 1993, 1992, 1991, 1990, 1989, 1988, 1987, 1986, 1985, 1984, 1983, 1982, 1981, 1980, 1979, 1978, 1977, 1976, 1975, 1974, 1973, 1972, 1971, 1970, 1969, 1968, 1967, 1966, 1965, 1964, 1963, 1962, 1961, 1960, 1959, 1958, 1957, 1956, 1955, 1954, 1953, 1952, 1951, 1950, 1949, 1948, 1947, 1946, 1945, 1944, 1943, 1942, 1941, 1940, 1939, 1938, 1937, 1936, 1935, 1934, 1933, 1932, 1931, 1930, 1929, 1928, 1927, 1926, 1925, 1924, 1923)

# Dow Jones Industrial Average Annual Closing Price Vector #

Dow_Close <- c(33301.87, 33147.25, 36338.3, 30606.48, 28538.44, 23327.46, 24719.22, 19762.6, 17425.03, 17823.07, 16576.66, 13104.14, 12217.56, 11577.51, 10428.05, 8776.39, 13264.82, 12463.15, 10717.5, 10783.01, 10453.92, 8341.63, 10021.57, 10787.99, 11497.12, 9181.43, 7908.3, 6448.27, 5117.12, 3834.44, 3754.09, 3301.11, 3168.83, 2633.66, 2753.2, 2168.57, 1938.83, 1895.95, 1546.67,
1211.57, 1258.64, 1046.54, 875, 963.99, 838.74, 805.01, 831.17, 1004.65, 852.41, 616.24, 850.86, 1020.02, 890.2, 838.92, 800.36, 943.75, 905.11, 785.69, 969.26, 874.13, 762.95, 652.1, 731.14, 615.89,
679.36, 583.65, 435.69, 499.47, 488.4, 404.39, 280.9, 291.9, 269.23, 235.41, 200.13, 177.3, 181.16, 177.2, 192.91, 152.32, 135.89, 119.4, 110.96, 131.13, 150.24, 154.76, 120.85, 179.9, 144.13, 104.04, 99.9, 59.93, 77.9, 164.58, 248.48, 300, 200.7, 157.2, 151.08, 120.51, 95.52)


# Combine both vectors into a singular data frame #

Dow_Data_Frame <- data.frame(Dow_Year, Dow_Close)

# Preview the data frame #

Dow_Data_Frame


This produces the output:

> Dow_Data_Frame
Dow_Year Dow_Close
1 2023 33301.87
2 2022 33147.25
3 2021 36338.30
4 2020 30606.48
5 2019 28538.44
6 2018 23327.46
7 2017 24719.22
8 2016 19762.60

Though we aren’t testing for this hypothesis directly through the application of a singular methodology, our hypothesis for this general experiment would resemble something like:

H0 (null): The Dow Jones Industrial Average Index’s annual returns are NOT random.

Ha (alternative): The Dow Jones Industrial Average Index’s annual returns are random.

The primary test that we will perform is the Phillips-Perron Unit Test. This particular method assess time series data for order of integration. In simplified terms, order of integration is the minimum number of differences required to obtain a covariance-stationary series. In the case of the Phillips-Perron Unit Test, we will be utilizing the underlying order of methodology to assess for random walk potential.

# The package: ‘tseries’ must be downloaded and enabled in order to utilize the PP.test() function #

library(tseries)

# Phillips-Perron Unit Root Test - A methodology utilized to test data for random walk potential #

# Null - The time series IS integrated of order (not-random) #

# Alternative - The time series is NOT integrated of order (random) #

PP.test(Dow_Data_Frame$Dow_Close)


This produces the output:

    Phillips-Perron Unit Root Test

data: Dow_Data_Frame$Dow_Close
Dickey-Fuller = -3.6678, Truncation lag parameter = 4, p-value = 0.03055


The secondary analysis which we will perform on our time series data, is the Dicky-Fuller Unit Root Test. This test assesses data for stationary potential.

# Dicky-Fuller Unit Root Test - A methodology utilized to test data for stationarity #

# Null - Data is NOT stationary #

# Alternative - Data IS stationary #

adf.test(Dow_Data_Frame$Dow_Close)


This produces the output:

    Augmented Dickey-Fuller Test

data: Dow_Data_Frame$Dow_Close
Dickey-Fuller = -5.0152, Lag order = 4, p-value = 0.01
alternative hypothesis: stationary

Warning message:
In adf.test(Dow_Data_Frame$Dow_Close) :
p-value smaller than printed p-value


Assuming an alpha value of .05, we would reject the null hypothesis in both instances. Thus, we would conclude with 95% confidence, that the annual Dow Jones Industrial Average closing prices are not integrated of order, and are also stationary. The combination of these results would therefore indicate that The Dow Jones Industrial Average returns are random.

I believe that the Dicky-Fuller test provides much more interesting insight. As unless a type I error was committed, we would eventually expect to witness either a Seneca Cliff event or parabolic downturn within the market given a long enough time frame. WOULD, EXPECT, EVENTUALLY, and UNLESS being the key terms here. (Don’t time the market or trade on the basis of a singular statistical methodology).

Some of you might be wondering why The Wald-Wolfowitz Test was not utilized. As a reminder, this particular method is only applicable to factor series data. However, if we were to inappropriately apply it in this instance, it would resemble the following:

# THIS IS NOT APPROPRIATE FOR OUR EXAMPLE #

# THIS CODE IS FOR DEMONSTRATION PURPOSES ONLY #

# The package: ‘trend’ must be downloaded and enabled in order to utilize the ww.test() function #

library(trend)

# Wald Wolfowitz Test #

# Null - Each element in the sequence is (independently) drawn from the same distribution (not-random) #

# Alternative - Each element in the sequence is not (independently) drawn from the same distribution (random) #

Dow_Close_Factor < as.factor(Dow_Data_Frame$Dow_Close)

ww.test(Dow_Close_Factor)


So that is it for today’s article, Data Heads. It would seem that Malkiel is vindicated, at least as it pertains to the methodologies which we applied within this particular entry. I’ll be back again soon with more data content.

-RD