| 166 |      1 | // Advanvced Part 3 about a really dumb investment strategy
 | 
| 130 |      2 | //==========================================================
 | 
|  |      3 | 
 | 
|  |      4 | object CW6c {
 | 
|  |      5 | 
 | 
|  |      6 | 
 | 
|  |      7 | //two test portfolios
 | 
|  |      8 | 
 | 
| 160 |      9 | val blchip_portfolio = List("GOOG", "AAPL", "MSFT", "IBM", "FB", "AMZN", "BIDU")
 | 
| 166 |     10 | val rstate_portfolio = List("PLD", "PSA", "AMT", "AIV", "AVB", "BXP", "CCI", 
 | 
|  |     11 |                             "DLR", "EQIX", "EQR", "ESS", "EXR", "FRT", "GGP", "HCP") 
 | 
| 130 |     12 | 
 | 
| 166 |     13 | // (1) The function below should obtain the first trading price
 | 
|  |     14 | // for a stock symbol by using the query
 | 
|  |     15 | //
 | 
|  |     16 | //    http://ichart.yahoo.com/table.csv?s=<<symbol>>&a=0&b=1&c=<<year>>&d=1&e=1&f=<<year>> 
 | 
|  |     17 | // 
 | 
|  |     18 | // and extracting the first January Adjusted Close price in a year.
 | 
|  |     19 | 
 | 
| 130 |     20 | 
 | 
|  |     21 | import io.Source
 | 
|  |     22 | import scala.util._
 | 
|  |     23 | 
 | 
| 166 |     24 | def get_january_data(symbol: String, year: Int) : List[String] = 
 | 
|  |     25 |   Source.fromFile(symbol ++ ".csv")("ISO-8859-1").getLines.toList.filter(_.startsWith(year.toString))
 | 
| 130 |     26 | 
 | 
|  |     27 | 
 | 
|  |     28 | def get_first_price(symbol: String, year: Int) : Option[Double] = {
 | 
| 166 |     29 |   val data = Try(Some(get_january_data(symbol, year).head)) getOrElse None 
 | 
|  |     30 |   data.map(_.split(",").toList(1).toDouble)
 | 
| 130 |     31 | }
 | 
|  |     32 | 
 | 
| 166 |     33 | get_first_price("GOOG", 1980)
 | 
|  |     34 | get_first_price("GOOG", 2010)
 | 
|  |     35 | get_first_price("FB", 2014)
 | 
| 130 |     36 | 
 | 
| 166 |     37 | 
 | 
|  |     38 | // Complete the function below that obtains all first prices
 | 
|  |     39 | // for the stock symbols from a portfolio for the given
 | 
|  |     40 | // range of years
 | 
|  |     41 | 
 | 
|  |     42 | def get_prices(portfolio: List[String], years: Range): List[List[Option[Double]]] = 
 | 
|  |     43 |   for (year <- years.toList) yield
 | 
|  |     44 |     for (symbol <- portfolio) yield get_first_price(symbol, year)
 | 
| 130 |     45 | 
 | 
|  |     46 | 
 | 
| 166 |     47 | // test case
 | 
| 167 |     48 | val p_fb = get_prices(List("FB"), 2012 to 2014)
 | 
|  |     49 | val p = get_prices(List("GOOG", "AAPL"), 2010 to 2012)
 | 
|  |     50 | 
 | 
|  |     51 | val tt = get_prices(List("BIDU"), 2004 to 2008)
 | 
| 166 |     52 | 
 | 
|  |     53 | // (2) The first function below calculates the change factor (delta) between
 | 
|  |     54 | // a price in year n and a price in year n+1. The second function calculates
 | 
|  |     55 | // all change factors for all prices (from a portfolio).
 | 
|  |     56 | 
 | 
|  |     57 | def get_delta(price_old: Option[Double], price_new: Option[Double]) : Option[Double] = {
 | 
|  |     58 |   (price_old, price_new) match {
 | 
|  |     59 |     case (Some(x), Some(y)) => Some((y - x) / x)
 | 
|  |     60 |     case _ => None
 | 
|  |     61 |   }
 | 
| 161 |     62 | }
 | 
|  |     63 | 
 | 
| 166 |     64 | def get_deltas(data: List[List[Option[Double]]]):  List[List[Option[Double]]] =
 | 
|  |     65 |   for (i <- (0 until (data.length - 1)).toList) yield 
 | 
|  |     66 |     for (j <- (0 until (data(0).length)).toList) yield get_delta(data(i)(j), data(i + 1)(j))
 | 
| 130 |     67 | 
 | 
|  |     68 | 
 | 
| 166 |     69 | // test case using the prices calculated above
 | 
| 167 |     70 | val d = get_deltas(p)
 | 
|  |     71 | val ttd = get_deltas(tt)
 | 
| 130 |     72 | 
 | 
|  |     73 | // (3) Write a function that given change factors, a starting balance and a year
 | 
| 166 |     74 | // calculates the yearly yield, i.e. new balanace, according to our dump investment 
 | 
|  |     75 | // strategy. Another function calculates given the same data calculates the
 | 
|  |     76 | // compound yield up to a given year. Finally a function combines all 
 | 
|  |     77 | // calculations by taking a portfolio, a range of years and a start balance
 | 
|  |     78 | // as arguments.
 | 
| 130 |     79 | 
 | 
|  |     80 | 
 | 
| 166 |     81 | def yearly_yield(data: List[List[Option[Double]]], balance: Long, year: Int): Long = {
 | 
|  |     82 |   val somes = data(year).flatten
 | 
|  |     83 |   val somes_length = somes.length
 | 
|  |     84 |   if (somes_length == 0) balance
 | 
|  |     85 |   else {
 | 
|  |     86 |     val portion: Double = balance.toDouble / somes_length.toDouble
 | 
| 167 |     87 |     balance + (for (x <- somes) yield (x * portion)).sum.toLong
 | 
| 166 |     88 |   }
 | 
|  |     89 | }
 | 
|  |     90 | 
 | 
|  |     91 | def compound_yield(data: List[List[Option[Double]]], balance: Long, year: Int): Long = {
 | 
|  |     92 |   if (year >= data.length) balance else {
 | 
|  |     93 |     val new_balance = yearly_yield(data, balance, year)
 | 
|  |     94 |     compound_yield(data, new_balance, year + 1)
 | 
|  |     95 |   }
 | 
|  |     96 | }
 | 
|  |     97 | 
 | 
|  |     98 | //yearly_yield(d, 100, 0)
 | 
|  |     99 | //compound_yield(d.take(6), 100, 0)
 | 
|  |    100 | 
 | 
|  |    101 | //test case
 | 
|  |    102 | //yearly_yield(d, 100, 0)
 | 
|  |    103 | //yearly_yield(d, 225, 1)
 | 
|  |    104 | //yearly_yield(d, 246, 2)
 | 
|  |    105 | //yearly_yield(d, 466, 3)
 | 
|  |    106 | //yearly_yield(d, 218, 4)
 | 
|  |    107 | 
 | 
|  |    108 | //yearly_yield(d, 100, 0)
 | 
|  |    109 | //yearly_yield(d, 125, 1)
 | 
|  |    110 | 
 | 
|  |    111 | def investment(portfolio: List[String], years: Range, start_balance: Long): Long = {
 | 
|  |    112 |   compound_yield(get_deltas(get_prices(portfolio, years)), start_balance, 0)
 | 
| 130 |    113 | }
 | 
|  |    114 | 
 | 
| 166 |    115 | /*
 | 
|  |    116 | val q1 = get_deltas(get_prices(List("GOOG", "AAPL", "BIDU"), 2000 to 2017))
 | 
|  |    117 | yearly_yield(q1, 100, 0)
 | 
|  |    118 | yearly_yield(q1, 100, 1)
 | 
|  |    119 | yearly_yield(q1, 100, 2)
 | 
|  |    120 | yearly_yield(q1, 100, 3)
 | 
|  |    121 | yearly_yield(q1, 100, 4)
 | 
|  |    122 | yearly_yield(q1, 100, 5)
 | 
|  |    123 | yearly_yield(q1, 100, 6)
 | 
|  |    124 | 
 | 
|  |    125 | investment(List("GOOG", "AAPL", "BIDU"), 2004 to 2017, 100)
 | 
|  |    126 | val one = get_deltas(get_prices(rstate_portfolio, 1978 to 1984))
 | 
|  |    127 | val two = get_deltas(get_prices(blchip_portfolio, 1978 to 1984))
 | 
|  |    128 | 
 | 
|  |    129 | val one_full = get_deltas(get_prices(rstate_portfolio, 1978 to 2017))
 | 
|  |    130 | val two_full = get_deltas(get_prices(blchip_portfolio, 1978 to 2017))
 | 
|  |    131 | 
 | 
|  |    132 | one_full.map(_.flatten).map(_.sum).sum
 | 
|  |    133 | two_full.map(_.flatten).map(_.sum).sum
 | 
|  |    134 | 
 | 
|  |    135 | //test cases for the two portfolios given above
 | 
|  |    136 | 
 | 
|  |    137 | //println("Real data: " + investment(rstate_portfolio, 1978 to 2017, 100))
 | 
|  |    138 | //println("Blue data: " + investment(blchip_portfolio, 1978 to 2017, 100))
 | 
|  |    139 | 
 | 
|  |    140 | for (i <- 2000 to 2017) {
 | 
|  |    141 |   println("Year " + i)
 | 
|  |    142 |   //println("Real data: " + investment(rstate_portfolio, 1978 to i, 100))
 | 
|  |    143 |   //println("Blue data: " + investment(blchip_portfolio, 1978 to i, 100))
 | 
|  |    144 |   println("test: " + investment(List("GOOG", "AAPL", "BIDU"), 2000 to i, 100))
 | 
| 144 |    145 | }
 | 
| 166 |    146 | 
 | 
|  |    147 | 
 | 
|  |    148 | */ 
 | 
|  |    149 | //1984
 | 
|  |    150 | //1992
 | 
|  |    151 | }
 |