TRINUG F# Analytics SIG Prep

I am putting together the finishing touches of the lab that the F#/data analytics group will do on Wednesday. We are working through Johan Astborg’s awesome book F# For Quantitative Finance.  Since the group is pretty much all C# with some bi-curious F#ers, I created a solution that mixes both C# and F#.  I put F# in the places where the language really shines: the data layer and the analytical layer.  I put C# in the places where C# has popular support: UI and unit tests.

image

In this lab, I am introducing script files and the REPL for the first time as a way to ‘prove out’ concepts.  Once the idea is sufficiently hashed out in the REPL, the code is moved into a source file and corresponding unit tests are created.  For example, in the data layer, we use the csv type provider to hit up the yahoo data and save and retrieve it from disk:

  1. #r "C:\Users\Jamie\Desktop\NewCo.OptionsTradingProgram.Solution\packages\FSharp.Data.2.0.8\lib\portable-net40+sl5+wp8+win8\FSharp.Data.dll"
  2. #r "C:\Users\Jamie\Desktop\NewCo.OptionsTradingProgram.Solution\packages\Newtonsoft.Json.6.0.3\lib\\net45\Newtonsoft.Json.dll"
  3.  
  4. open System
  5. open FSharp.Data
  6. open Newtonsoft.Json
  7. open System.IO
  8.  
  9. type csvProvider = CsvProvider<"http://ichart.finance.yahoo.com/table.csv?s=MSFT&quot;>
  10.  
  11. type YahooStockProvider() =
  12.     member this.GetData(stockSymbol: string) =
  13.             csvProvider.Load("http://ichart.finance.yahoo.com/table.csv?s=&quot; + stockSymbol).Rows
  14.     
  15. type FileSystemStockProvider() =
  16.     member this.PutData(filePath:string, stockData) =
  17.         let serializedData = stockData
  18.                                 |> Seq.map(fun row -> JsonConvert.SerializeObject(row))
  19.         File.WriteAllLines(filePath,serializedData)
  20.  
  21.     member this.GetData(filePath:string) =
  22.         let serializedData = File.ReadAllLines(filePath)
  23.         serializedData
  24.             |> Seq.map(fun row -> JsonConvert.DeserializeObject<(DateTime*float*float*float*float*int*float)>(row))

In the analytics module, we spend a good amount of time implementing mathematical calculations and getting comfortable with some of the differences between how imperative C# might implement a solution and how F# would

  1. open System.Collections.Generic
  2.  
  3. let testData = [1.0 .. 6.0]
  4. let sum = testData |> Seq.sum
  5. let average = testData |> Seq.average
  6. let min = testData |> Seq.min
  7. let max = testData |> Seq.max
  8. let evens = testData |> Seq.filter(fun number -> number % 2. = 0.)
  9. let addOne = testData |> Seq.map(fun number -> number + 1.)
  10.  
  11.  
  12. //http://www.mathsisfun.com/data/standard-deviation.html
  13. let variance (source:IEnumerable<double>) =
  14.     let mean = Seq.average source
  15.     let deltas = Seq.map(fun x -> pown(x-mean) 2) source
  16.     Seq.average deltas
  17.  
  18. let standardDeviation(values:IEnumerable<double>) =
  19.     sqrt(variance(values))
  20.  
  21. let movingAverage(values:IEnumerable<double>, windowSize:int)=
  22.     values
  23.         |> Seq.windowed (windowSize)
  24.         |> Seq.map(fun window -> window |> Seq.average)
  25.  
  26. let movingStandardDeviation(values:IEnumerable<double>, windowSize:int)=
  27.     values
  28.         |> Seq.windowed (windowSize)
  29.         |> Seq.map(fun window -> window |> standardDeviation)
  30.  
  31. let bollingerBands (values:IEnumerable<double>, windowSize:int)=
  32.     let movingAverage = movingAverage(values,windowSize)
  33.     let movingStandardDeviation = movingStandardDeviation(values,windowSize)
  34.     let movingStandardDeviation' = movingStandardDeviation |> Seq.map(fun window -> window * 2.)
  35.     Seq.zip movingAverage movingStandardDeviation'

Finally, we have a WPF application that does some basic charting and graphing.  The point of this lab is not about building a snazzy UI.  The UI (and in fact, the data layer) are just plug-ins to the heart of the application – the analytical module.  Also, a majority of the TRINUG’ content focuses on the UI so there is plenty of that already.   In any event, here is the code behind in C#.

  1. private void GoButton_Click(object sender, RoutedEventArgs e)
  2. {
  3.     FileSystemStockProvider provider = new FileSystemStockProvider(@"C:\Data\TEST.txt");
  4.     var stockPrices = provider.GetData().Take(20);
  5.     this.StockPriceDataGrid.ItemsSource = stockPrices;
  6.  
  7.     var adjustedClosePrices = from stockPrice in stockPrices
  8.             select stockPrice.Item7;
  9.  
  10.     var dates = from stockPrice in stockPrices.Skip(2)
  11.                              select new { stockPrice.Item1 };
  12.  
  13.     var calculations = new Calculations();
  14.     var movingAverage = calculations.MovingAverage(adjustedClosePrices, 3);
  15.     var movingAverages = dates.Zip(movingAverage, (d, p) => new { date=d.Item1, price=p});
  16.  
  17.     var bollingerBands = calculations.BollingerBands(adjustedClosePrices, 3);
  18.     var upperBandBands = dates.Zip(bollingerBands, (d, bb) => new { date = d.Item1, upperBand = bb.Item1 + (bb.Item2 * 2) });
  19.     var lowerBandBands = dates.Zip(bollingerBands, (d, bb) => new { date = d.Item1, lowerBand = bb.Item1 + (bb.Item2 * 2) * -1 });
  20.  
  21.     this.stockPriceLineGraph.DependentValuePath = "price";
  22.     this.stockPriceLineGraph.IndependentValuePath = "date";
  23.     this.stockPriceLineGraph.ItemsSource = movingAverages;
  24.  
  25.     this.stockPriceLineGraph2.DependentValuePath = "upperBand";
  26.     this.stockPriceLineGraph2.IndependentValuePath = "date";
  27.     this.stockPriceLineGraph2.ItemsSource = upperBandBands;
  28.  
  29.     this.stockPriceLineGraph3.DependentValuePath = "lowerBand";
  30.     this.stockPriceLineGraph3.IndependentValuePath = "date";
  31.     this.stockPriceLineGraph3.ItemsSource = lowerBandBands;
  32. }

 

I am toying of not using Linq and doing this all via imperative code, which would really drive home the point and power of a functional approach.  Here is the UI when running:

image

This was a alot fun to do and I am looking forward to the next lab, which is implementing the remainder of Astborg’s book.

 

 

One Response to TRINUG F# Analytics SIG Prep

  1. Pingback: F# Weekly #24-#25, 2014 | Sergey Tihon's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: