Functional Fun Calculating SMA and EMA

 

To try out F#I decided to make a function to calculate  simple moving average (SMA) and exponential moving average (EMA).  The SMA and EMA have enough math to try many of the features of F# and functional programming.

The first thing I learned was F# has a way to quickly execute code. If you haven’t played with F#’s Interactive it’s sort of like a REPL loop. While coding you can highlight the code and do a Alt-Enter to execute it. It’s very convenient.

FSharpCapture

To keep with the functional style of programming I put the SMA and EMA into a type. In OO this would be the equivalent of using a base class for moving averages and then creating classes for SMA and EMA. As you can see in F# this is a very small amount of code using type declaration / discriminators. You can see comments in my code below for things I learned and picked up while doing this exercise.

 

type movingAverage =
  | Simple of int * seq<float>
  | Exponential of int * float list



// sma is an example of using a private / utility function
// pipelining operator |> allows execution of a series of operations
let sma(size, seq) =                                  
    Seq.windowed size seq
    |> Seq.map Array.average  



// example of Matching on discriminated unions
let calculate(movingAverage) =
    match movingAverage with

    |Simple(size, seq) -> sma(size, seq)

    |Exponential(period, data) -> 

            let multiplier =  2.0 / (1.0 + (float period))
            
//Calc a sum to use in the SMA to prime the EMA calculation
//http://bit.ly/bG73sx Slice like functionality from a List
            let iniSum =  
                data 
                |> List.toSeq 
                |> Seq.take (int period) 
                |> Seq.sum

//first float from list using period as the start
            let firstItem = 
                data 
                |> List.toSeq 
                |> Seq.skip (int period)  
                |> Seq.head 

//setup first ema with sma
            let firstEma = (iniSum / (float period))

            let out : float array = Array.zeroCreate (List.length data)

//setup initial Ema to previous day
            out.[period - 2] <- firstEma

//calculate the rest of the Ema's
            for i in period - 1 .. (List.length data - 1) do
                let close = data.[i]
                let prev = out.[i - 1]
                out.[i] <- multiplier * (close - prev) + prev

            Array.toSeq out

// F# Note - intrinsic type extensions adds the calculate member to the movingAverage type
type movingAverage with                                                
   member x.calculate() = calculate(x)  


//Test Simple
let simpleMovingAverage = Simple(10, (Seq.map float [|1..30|]))

let avgs = simpleMovingAverage.calculate();

for avg in avgs do
    printfn "%f" avg

//Test Exponential
let expMovingAverage = Exponential(10, [1.0..30.0])

let expAvgs = expMovingAverage.calculate();

for e in expAvgs do
    printfn "%f" e

a big thanks to this F# technical indicator series.

Leave a Reply

Your email address will not be published. Required fields are marked *