+ All Categories
Home > Documents > STAT682 Final Project Group 2

STAT682 Final Project Group 2

Date post: 09-Feb-2016
Category:
Upload: nessa
View: 24 times
Download: 0 times
Share this document with a friend
Description:
STAT682 Final Project Group 2. Iliya Atanasov Matthew Ginley Aaron Mielke Lisa Stryjewski John Varghese. The Basics. Hold 50 stocks for 1 year Rebalance every year according to fundamentals. Reproducing O’Shaughnessy. Assisted by ClariFI ( backtesting software) Sales / Price - PowerPoint PPT Presentation
53
STAT682 Final Project Group 2 Iliya Atanasov Matthew Ginley Aaron Mielke Lisa Stryjewski John Varghese
Transcript
Page 1: STAT682 Final Project Group 2

STAT682 Final ProjectGroup 2

Iliya AtanasovMatthew Ginley

Aaron MielkeLisa StryjewskiJohn Varghese

Page 2: STAT682 Final Project Group 2

The Basics

• Hold 50 stocks for 1 year• Rebalance every year according to

fundamentals

Page 3: STAT682 Final Project Group 2

Reproducing O’Shaughnessy

• Assisted by ClariFI (backtesting software)• Sales / Price• Earnings Per Share / Price• Book / Price• Dividends Per Share / Price

Page 4: STAT682 Final Project Group 2

Our Approach

• Created our own backtesting code• Started with Sales / Price• Exhaustive coverage of all Compustat

Variables• Reviewed high coverage and high correlation

ratios• Selected an additional ratio to complement

Sales / Price

Page 5: STAT682 Final Project Group 2

Using ClariFI

Page 6: STAT682 Final Project Group 2

ClariFI

Page 7: STAT682 Final Project Group 2

ClariFI

Page 8: STAT682 Final Project Group 2

Results from ClariFI

Page 9: STAT682 Final Project Group 2

Sales to Price

Page 10: STAT682 Final Project Group 2

Sales to Price

Page 11: STAT682 Final Project Group 2

Sales to Price

Page 12: STAT682 Final Project Group 2

EPS to Price

Page 13: STAT682 Final Project Group 2

EPS to Price

Page 14: STAT682 Final Project Group 2

EPS to Price

Page 15: STAT682 Final Project Group 2

Book to Price

Page 16: STAT682 Final Project Group 2

Book to Price

Page 17: STAT682 Final Project Group 2

Book to Price

Page 18: STAT682 Final Project Group 2

Dividend Yield

Page 19: STAT682 Final Project Group 2

Dividend Yield

Page 20: STAT682 Final Project Group 2

Dividend Yield

Page 21: STAT682 Final Project Group 2

Writing our Own Simulator

C# Source Code

Page 22: STAT682 Final Project Group 2

1. Variables

var priceIndex = Enumerable.Range(0, headers.Length).First(i => headers[i] =="prcc_c");

var dividendIndex = Enumerable.Range(0, headers.Length).First(i => headers[i] =="dvpsx_c");

var yearIndex = Enumerable.Range(0, headers.Length).First(i => headers[i] == "fyear");

var sharesIndex = Enumerable.Range(0, headers.Length).First(i => headers[i] =="CSHO");

var epsIndex = Enumerable.Range(0, headers.Length).First(i => headers[i] == "EPSPX");

var idIndex = Enumerable.Range(0, headers.Length).First(i => headers[i] == "gvkey");

var ajexIndex = Enumerable.Range(0, headers.Length).First(i => headers[i] =="adjex_c");

Page 23: STAT682 Final Project Group 2

2. Market Capitalizationvar marketCapMinimums = new int[Years];yearToStocks = Enumerable.Range(0, Years).Select(i => new Dictionary<int, Stock>()).ToArray();

for (var i = 0; i < marketCapMinimums.Length; i++){

var year = i + MinYear;

if (year < 1955) marketCapMinimums[i] = 27;else if (year < 1959) marketCapMinimums[i] = 27;else if (year < 1964) marketCapMinimums[i] = 28;else if (year < 1969) marketCapMinimums[i] = 31;else if (year < 1974) marketCapMinimums[i] = 34;else if (year < 1979) marketCapMinimums[i] = 44;else if (year < 1984) marketCapMinimums[i] = 64;else if (year < 1989) marketCapMinimums[i] = 97;else if (year < 1994) marketCapMinimums[i] = 117;else if (year < 1996) marketCapMinimums[i] = 150;else marketCapMinimums[i] = 185;

}

Page 24: STAT682 Final Project Group 2

3.A Reading Datawhile ((line = reader.ReadLine()) != null){

if (++count%10000 == 0) Console.WriteLine(count + ": " + (double) reader.BaseStream.Position/(double) reader.BaseStream.Length);

var parts = line.Split(',');double price, shares, dividend, eps, ajex;int year;

if (double.TryParse(parts[priceIndex], out price) == false || price == 0.0) continue;if (double.TryParse(parts[sharesIndex], out shares) == false) continue;if (double.TryParse(parts[epsIndex], out eps) == false) continue;if (int.TryParse(parts[yearIndex], out year) == false) continue;

var marketCap = price*shares;yearToMarketCaps[year - MinYear].Add(marketCap);var marketCapMinimum = marketCapMinimums[year - MinYear];if (marketCap < marketCapMinimum) continue;

Page 25: STAT682 Final Project Group 2

3.B Reading Datadouble.TryParse(parts[ajexIndex], out ajex);double.TryParse(parts[dividendIndex], out dividend);var id = int.Parse(parts[idIndex]);if (ajex <= 0.0) ajex = 1.0;

var values = Enumerable.Range(0, parts.Length).Select( i => { double value; if (double.TryParse(parts[i], out value) == false) value =double.NaN; return value; }).ToArray();

yearToStocks[year - MinYear].Add(id, new Stock(id, price, shares, dividend, ajex, values));

yearToMeanMarketCap = yearToMarketCaps.Select(marketCaps => marketCaps.Count == 0 ? 0.0 : marketCaps.Average()).ToArray();

}

Page 26: STAT682 Final Project Group 2

4. Calculating Returnspublic void CalculateReturns(Stock nextYears){ if (nextYears == null) return; Return = Ajex * (nextYears.Price + nextYears.Dividend)

/ Price / nextYears.Ajex - 1.0;}

Page 27: STAT682 Final Project Group 2

5.A Ranking StocksFunc<Func<Stock, double>, List<RanksAndStock>> rankStocks =

getTestValue =>

{

var rankAndStock = new List<RanksAndStock>(count);

for (var year = 0; year < Years - 1; year++)

{

var testSortedStockList = yearToStocks[year].Values.ToArray();

var returnSortedIndexes = Enumerable.Range(0, testSortedStockList.Length).ToArray();

Array.Sort(testSortedStockList, (x, y) => getTestValue(x).CompareTo(getTestValue(y)));

Array.Sort(testSortedStockList.Select(s => s.Return.Value).ToArray(),

returnSortedIndexes);

Page 28: STAT682 Final Project Group 2

5.B Ranking Stocks var returnRanks = GenerateRanks(testSortedStockList.Length,

i => testSortedStockList[returnSortedIndexes[i]],stock => stock.Return.Value);

var testRanks = GenerateRanks(testSortedStockList.Length, i => testSortedStockList[i], getTestValue); for (var returnSortedIndex = 0; returnSortedIndex < returnSortedIndexes.Length; returnSortedIndex++) { var testSortedIndex = returnSortedIndexes[returnSortedIndex]; var stock = testSortedStockList[testSortedIndex]; if (double.IsNaN(getTestValue(stock))) continue;

rankAndStock.Add(new RanksAndStock(testRanks[testSortedIndex],returnRanks[returnSortedIndex], stock));

} } return rankAndStock; };

Page 29: STAT682 Final Project Group 2

6. Pearsonprivate static double CalculatePearson(IEnumerable<RanksAndStock> ranksAndStocks){ var n = ranksAndStocks.Count(); var sumReturn = ranksAndStocks.Sum(ranksAndStock => ranksAndStock.ReturnRank); var sumReturnSquared = ranksAndStocks.Sum(

ranksAndStock => ranksAndStock.ReturnRank*ranksAndStock.ReturnRank); var returnDifferences = ((n*sumReturnSquared) - (sumReturn*sumReturn)); var sumTest = ranksAndStocks.Sum(ranksAndStock => ranksAndStock.TestRank); var sumTestSquared = ranksAndStocks.Sum(

ranksAndStock => ranksAndStock.TestRank*ranksAndStock.TestRank); var sumTestReturn = ranksAndStocks.Sum(

ranksAndStock => ranksAndStock.TestRank*ranksAndStock.ReturnRank); var denom = Math.Sqrt(returnDifferences*((n*sumTestSquared) - (sumTest*sumTest)));

var pearson = (n*sumTestReturn - (sumReturn*sumTest))/denom; return pearson;}

Page 30: STAT682 Final Project Group 2

7. Single Valuesusing (var writer = new StreamWriter("singles.csv")) { writer.WriteLine("column,r,%"); Parallel.For( 0, headers.Length, //new ParallelOptions{ MaxDegreeOfParallelism = 1}, header => { Func<Stock, double> getTestValue = stock => stock.Values[header]; var rankAndStock = rankStocks(getTestValue); var pearson = CalculatePearson(rankAndStock); var temp = header + ":" + headers[header] + "," + pearson + "," + ((double)

rankAndStock.Count/count); Console.WriteLine(temp); lock (writer) writer.WriteLine(temp); if (double.IsNaN(pearson) == false) lock (validColumns) validColumns.Add(header); }); }

Page 31: STAT682 Final Project Group 2

8.A Ratiosusing (var writer = new StreamWriter("ratios.csv")) { writer.WriteLine("numerator,denominator,r,%"); Parallel.For(

0, validColumns.Count, //new ParallelOptions{ MaxDegreeOfParallelism = 1}, numeratorIndex => Parallel.For(

0, validColumns.Count, //new ParallelOptions{ MaxDegreeOfParallelism = 1}, denominatorIndex => { try { var numerator = validColumns[numeratorIndex]; var denominator = validColumns[denominatorIndex]; if (numerator == denominator) return;

Page 32: STAT682 Final Project Group 2

8.B Ratios

if (System.Threading.Interlocked.Increment(ref progress)%1000 == 0) Console.WriteLine("******* " + progress + "/" + total + "=" + ((double) progress/total) + " *******");

Func<Stock, double> getTestValue = stock => stock.Values[numerator]/stock.Values[denominator];var rankAndStock = rankStocks(getTestValue);var pearson = CalculatePearson(rankAndStock);var temp = numerator + ":" + headers[numerator] + "," + denominator + ":" +

headers[denominator] + "," + pearson + "," + ((double) rankAndStock.Count/count);

Console.WriteLine(temp);lock (writer) writer.WriteLine(temp);

} catch (Exception e) {

try { using (var errors = new StreamWriter("errors.txt", true)) errors.WriteLine(e.ToString()); } catch {} }}));}

Page 33: STAT682 Final Project Group 2

9.A Multipliersusing (var writer = new StreamWriter("multipliers.csv")) { writer.WriteLine("first,second,r,%"); Parallel.For( 0, validColumns.Count, //new ParallelOptions{ MaxDegreeOfParallelism = 1}, firstIndex => Parallel.For( 0, validColumns.Count, //new ParallelOptions{ MaxDegreeOfParallelism = 1}, secondIndex => { try { var first = validColumns[firstIndex]; var second = validColumns[secondIndex]; if (System.Threading.Interlocked.Increment(ref progress)%1000 == 0)

Console.WriteLine("******* " + progress + "/" + total + "=” + ((double) progress/total) + " *******");

Page 34: STAT682 Final Project Group 2

9.B Multipliers

Func<Stock, double> getTestValue = stock => stock.Values[first]*stock.Values[second];var rankAndStock = rankStocks(getTestValue);var pearson = CalculatePearson(rankAndStock);var temp = first + ":" + headers[first] + "," + second + ":" + headers[second] + "," +

pearson + "," + ((double) rankAndStock.Count/count);

Console.WriteLine(temp);lock (writer) writer.WriteLine(temp);

}catch (Exception e) {

try { using (var errors = new StreamWriter("errors.txt", true)) errors.WriteLine(e.ToString()); } catch {}}

]}));}

Page 35: STAT682 Final Project Group 2

10. Strategiesvar nameToTest = new Dictionary<string, Func<Stock, double>>{ { "EPS_OVER_Price", stock => -stock.Values[258] / stock.Values[944]},

{ "-EPS_OVER_Price", stock => stock.Values[258] / stock.Values[944]},

{ "EBITDA_over_EV",stock => -stock.Values[250] /

(stock.Values[944] * stock.Values[149] + stock.Values[194] + stock.Values[153] - stock.Values[109])},

{ "Sales_OVER_Price", stock => -stock.Values[705] / stock.Values[944]},

{ "Sales_OVER_Price_PLUS_IBCOM_OVER_NI",stock => -stock.Values[705] / stock.Values[944] + -stock.Values[352] / stock.Values[513]},

{ "Dividends_OVER_Price", stock => -stock.Values[943] / stock.Values[944]},

{ "IBCOM_OVER_NI", stock => -stock.Values[352] / stock.Values[513]}};

Page 36: STAT682 Final Project Group 2

11.A Strategy Simulationfor (var large = 0; large < 2; large++) { var strategies = nameToTest.ToArray(); for (var i = 0; i < nameToTest.Count; i++) { Func<Stock, double> strategy; string name; if(i < nameToTest.Count) { strategy = strategies[i].Value; name = strategies[i].Key; } else { name = "Combo”; strategy = stock => { return strategies.Select(s => s.Value(stock)).Where(d => double.IsNaN(d) == false).Average(); }; }

Page 37: STAT682 Final Project Group 2

11.B Strategy Simulation var largeName = large == 0 ? "_large" : string.Empty;

using (var writer = new StreamWriter("returns_" + name + largeName + ".csv")) {

writer.WriteLine("Year,Average Return");

Parallel.For( 1, Years - 1, new ParallelOptions {MaxDegreeOfParallelism = 1}, year => { var testSortedStockList = yearToStocks[year - 1].Values.ToArray();

if (large == 0)testSortedStockList = testSortedStockList.Where(s => s.Price * s.Shares >= yearToMeanMarketCap[year]).ToArray();

Array.Sort(testSortedStockList, (x, y) => strategy(x).CompareTo(strategy(y)));

Page 38: STAT682 Final Project Group 2

11.C Strategy Simulationvar returns = new List<double>();for (var index = 0; index < testSortedStockList.Length && returns.Count < 50; index++){ var lastYearsStock = testSortedStockList[index]; if (double.IsNaN(strategy(lastYearsStock))) continue;

Stock thisYearsStock; if (yearToStocks[year].TryGetValue(lastYearsStock.ID, out thisYearsStock) == false)

continue; returns.Add(thisYearsStock.Return.Value);}var line = (year + MinYear) + "," + (returns.Count() == 0 ? 0.0 : returns.Average()) + "," +

string.Join(",", returns.Select(r => r.ToString()));Console.WriteLine(line);lock (writer) writer.WriteLine(line);

});}

}}}

Page 39: STAT682 Final Project Group 2

12.A Unused CRSP Datausing (var reader = new StreamReader(@"d:\data\stat\just price2.csv")){

string line;

var priceHeaders = reader.ReadLine().Split(',');

var idIndex = Enumerable.Range(0, priceHeaders.Length).First(i => priceHeaders[i] == "gvkey");

var dateIndex = Enumerable.Range(0, priceHeaders.Length).First(i => priceHeaders[i] == "datadate");

var priceIndex = Enumerable.Range(0, priceHeaders.Length).First(i => priceHeaders[i] == "PRCCM");

count = 0;

Page 40: STAT682 Final Project Group 2

12.B Unused CRSP Datawhile ((line = reader.ReadLine()) != null){

if (++count%10000 == 0) Console.WriteLine(count + ": " + (double) reader.BaseStream.Position/(double) reader.BaseStream.Length);

var parts = line.Split(','); double price; var date = DateTime.ParseExact(parts[dateIndex], "yyyyMMdd”,

CultureInfo.InvariantCulture, DateTimeStyles.None);

if (date.Month != 12) continue;

var id = int.Parse(parts[idIndex]); if (double.TryParse(parts[priceIndex], out price) == false || price == 0.0) continue;

yearToStockToPrice[date.Year - MinYear][id] = price;}

}

Page 41: STAT682 Final Project Group 2

Our Results

Page 42: STAT682 Final Project Group 2

Sales to Price (All Stocks)

Page 43: STAT682 Final Project Group 2

Sales to Price (All Stocks)

Page 44: STAT682 Final Project Group 2

Sales to Price (Large Stocks)

Page 45: STAT682 Final Project Group 2

Sales to Price (Large Stocks)

Page 46: STAT682 Final Project Group 2

IBCOM to NI (All Stocks)

Page 47: STAT682 Final Project Group 2

IBCOM to NI (All Stocks)

Page 48: STAT682 Final Project Group 2

IBCOM to NI (Large Stocks)

Page 49: STAT682 Final Project Group 2

IBCOM to NI (Large Stocks)

Page 50: STAT682 Final Project Group 2

S/P + IBCOM/NI (All Stocks)

Page 51: STAT682 Final Project Group 2

S/P + IBCOM/NI (All Stocks)

Page 52: STAT682 Final Project Group 2

S/P + IBCOM/NI (Large Stocks)

Page 53: STAT682 Final Project Group 2

S/P + IBCOM/NI (Large Stocks)


Recommended