progs/drumb_sol.scala
changeset 30 bb8c3dd8c75c
parent 26 a7afc2540a88
child 39 c6fe374a5fca
equal deleted inserted replaced
29:fde9223a5301 30:bb8c3dd8c75c
     1 // Advanvced Part 3 about Mr T. Drumb investing into stocks
     1 // Advanvced Part 3 about really dump investing strategy
     2 //==========================================================
     2 //=======================================================
     3 
     3 
     4 //two test portfolios
     4 //two test portfolios
     5 
     5 
     6 val blchip_portfolio = List("GOOG", "AAPL", "MSFT", "IBM", "FB", "YHOO", "AMZN", "BIDU")
     6 val blchip_portfolio = List("GOOG", "AAPL", "MSFT", "IBM", "FB", "YHOO", "AMZN", "BIDU")
     7 val rstate_portfolio = List("PLD", "PSA", "AMT", "AIV", "AVB", "BXP", "CBG", "CCI", 
     7 val rstate_portfolio = List("PLD", "PSA", "AMT", "AIV", "AVB", "BXP", "CBG", "CCI", 
     8                             "DLR", "EQIX", "EQR", "ESS", "EXR", "FRT", "GGP", "HCP") 
     8                             "DLR", "EQIX", "EQR", "ESS", "EXR", "FRT", "GGP", "HCP") 
     9 
     9 
       
    10 // (1) The function below should obtain the first trading price
       
    11 // for a stock symbol by using the query
       
    12 //
       
    13 //    http://ichart.yahoo.com/table.csv?s=<<symbol>>&a=0&b=1&c=<<year>>&d=1&e=1&f=<<year>> 
       
    14 // 
       
    15 // and extracting the first January Adjusted Close price in a year.
    10 
    16 
    11 import io.Source
    17 import io.Source
    12 import scala.util._
    18 import scala.util._
    13 
    19 
    14 def get_yahoo_page(url: String): Option[List[String]] = {
    20 def get_yahoo_page(url: String): Option[List[String]] = {
    23   val url = """http://ichart.yahoo.com/table.csv?s=""" + symbol + date_string
    29   val url = """http://ichart.yahoo.com/table.csv?s=""" + symbol + date_string
    24   val data = get_yahoo_page(url)
    30   val data = get_yahoo_page(url)
    25   data.map(_.last.split(",").toList(6).toDouble)
    31   data.map(_.last.split(",").toList(6).toDouble)
    26 }
    32 }
    27 
    33 
       
    34 
       
    35 // Complete the function below that obtains all first prices
       
    36 // for the stock symbols from a portfolio for the given
       
    37 // range of years
       
    38 
    28 def get_prices(portfolio: List[String], years: Range): List[List[Option[Double]]] = 
    39 def get_prices(portfolio: List[String], years: Range): List[List[Option[Double]]] = 
    29   for (year <- years.toList) yield
    40   for (year <- years.toList) yield
    30     for (symbol <- portfolio) yield get_first_price(symbol, year)
    41     for (symbol <- portfolio) yield get_first_price(symbol, year)
    31 
    42 
    32 get_prices(List("GOOG", "AAPL"), 2010 to 2012)
       
    33 
    43 
       
    44 // test case
       
    45 //val p = get_prices(List("GOOG", "AAPL"), 2010 to 2012)
       
    46 
       
    47 
       
    48 // (2) The first function below calculates the change factor (delta) between
       
    49 // a price in year n and a price in year n+1. The second function calculates
       
    50 // all change factors for all prices (from a portfolio).
    34 
    51 
    35 def get_delta(price_old: Option[Double], price_new: Option[Double]): Option[Double] = {
    52 def get_delta(price_old: Option[Double], price_new: Option[Double]): Option[Double] = {
    36   (price_old, price_new) match {
    53   (price_old, price_new) match {
    37     case (Some(x), Some(y)) => Some((y - x) / x)
    54     case (Some(x), Some(y)) => Some((y - x) / x)
    38     case _ => None
    55     case _ => None
    41 
    58 
    42 def get_deltas(data: List[List[Option[Double]]]):  List[List[Option[Double]]] =
    59 def get_deltas(data: List[List[Option[Double]]]):  List[List[Option[Double]]] =
    43   for (i <- (0 until (data.length - 1)).toList) yield 
    60   for (i <- (0 until (data.length - 1)).toList) yield 
    44     for (j <- (0 until (data(0).length)).toList) yield get_delta(data(i)(j), data(i + 1)(j))
    61     for (j <- (0 until (data(0).length)).toList) yield get_delta(data(i)(j), data(i + 1)(j))
    45 
    62 
       
    63 
       
    64 // test case using the prices calculated above
       
    65 //val d = get_deltas(p)
       
    66 
       
    67 
       
    68 // (3) Write a function that given change factors, a starting balance and a year
       
    69 // calculates the yearly yield, i.e. new balanace, according to our dump investment 
       
    70 // strategy. Another function calculates given the same data calculates the
       
    71 // compound yield up to a given year. Finally a function combines all 
       
    72 // calculations by taking a portfolio, a range of years and a start balance
       
    73 // as arguments.
       
    74 
       
    75 
    46 def yearly_yield(data: List[List[Option[Double]]], balance: Long, year: Int): Long = {
    76 def yearly_yield(data: List[List[Option[Double]]], balance: Long, year: Int): Long = {
    47   val somes = data(year).flatten
    77   val somes = data(year).flatten
    48   val somes_length = somes.length
    78   val somes_length = somes.length
    49   if (somes_length == 0) balance
    79   if (somes_length == 0) balance
    50   else {
    80   else {
    51     val portion: Double = balance / somes_length
    81     val portion: Double = balance / somes_length
    52     balance + (for (x <- somes) yield (x * portion)).sum.toLong
    82     balance + (for (x <- somes) yield (x * portion)).sum.toLong
    53   }
    83   }
    54 }
    84 }
    55 
    85 
       
    86 //test case
       
    87 //yearly_yield(d, 100, 0)
       
    88 
    56 def compound_yield(data: List[List[Option[Double]]], balance: Long, year: Int): Long = {
    89 def compound_yield(data: List[List[Option[Double]]], balance: Long, year: Int): Long = {
    57   if (year >= data.length) balance else {
    90   if (year >= data.length) balance else {
    58     val new_balance = yearly_yield(data, balance, year)
    91     val new_balance = yearly_yield(data, balance, year)
    59     compound_yield(data, new_balance, year + 1)
    92     compound_yield(data, new_balance, year + 1)
    60   }
    93   }
    61 }
    94 }
    62 
    95 
    63 val p = get_prices(List("GOOG", "AAPL"), 2010 to 2012)
       
    64 val d = get_deltas(p)
       
    65 yearly_yield(d, 100, 0)
       
    66 
       
    67 def investment(portfolio: List[String], years: Range, start_balance: Long): Long = {
    96 def investment(portfolio: List[String], years: Range, start_balance: Long): Long = {
    68   compound_yield(get_deltas(get_prices(portfolio, years)), start_balance, 0)
    97   compound_yield(get_deltas(get_prices(portfolio, years)), start_balance, 0)
    69 }
    98 }
    70 
    99 
    71 
   100 
       
   101 //test cases for the two portfolios given above
       
   102 
    72 println("Real data: " + investment(rstate_portfolio, 1978 to 2016, 100))
   103 println("Real data: " + investment(rstate_portfolio, 1978 to 2016, 100))
    73 println("Blue data: " + investment(blchip_portfolio, 1978 to 2016, 100))
   104 println("Blue data: " + investment(blchip_portfolio, 1978 to 2016, 100))
    74 
   105