.Net · F# · Finance · Functional Programming · Uncategorized

Historical Volatility

The code snippet is capable of calculating historical volatility using Close Price, High Low Price and Close High Low Price methods. Simply provide symbol, start date and end date of the specific volatility method and it extracts the market data from the yahoo service and calculated the volatility.

open System
open System.IO
open System.Xml
open System.Text
open System.Net
open System.Globalization

let makeUrl symbol (dfrom:DateTime) (dto:DateTime) =
    //Uses the not-so-known chart-data:
    new Uri("http://ichart.finance.yahoo.com/table.csv?s=" + symbol +
       "&e=" + dto.Day.ToString() + "&d=" + dto.Month.ToString() + "&f=" + dto.Year.ToString() +
       "&g=d&b=" + dfrom.Day.ToString() + "&a=" + dfrom.Month.ToString() + "&c=" + dfrom.Year.ToString() +
       "&ignore=.csv")

let fetch (url : Uri) =
    let req = WebRequest.Create (url) :?> HttpWebRequest
    use stream = req.GetResponse().GetResponseStream()
    use reader = new StreamReader(stream)
    reader.ReadToEnd()

let reformat (response:string) =
    let split (mark:char) (data:string) =
        data.Split(mark) |> Array.toList
    response |> split '\n'
    |> List.filter (fun f -> f<>"")
    |> List.map (split ',') 

let getRequest uri = (fetch >> reformat) uri

type MarketData =
    {Date: DateTime;
     Open: double;
     High: double;
     Low: double;
     Close: double;
     Volume: int;
     AdjClose: double;}

let converter (data:List<List<string>>) =
    [for dataArray in data.Tail do
        yield {Date = DateTime.ParseExact(dataArray.[0],"yyyy-MM-dd",CultureInfo.InvariantCulture);
          Open = System.Convert.ToDouble(dataArray.[1]);
          High = System.Convert.ToDouble(dataArray.[2]);
          Low = System.Convert.ToDouble(dataArray.[3]);
          Close = System.Convert.ToDouble(dataArray.[4]);
          Volume = System.Convert.ToInt32(dataArray.[5]);
          AdjClose = System.Convert.ToDouble(dataArray.[6])}]

//Example: Microsoft, from 2010-03-20 to 2010-04-21
//getMarketData "MSFT" (new DateTime(2010,1,1)) (new DateTime(2010,1,30));;
let getMarketData symbol fromDate toDate = makeUrl symbol fromDate toDate  |> getRequest |> converter

//highLowVolatility "MSFT" (new DateTime(2010,1,1)) (new DateTime(2010,1,30));;
let highLowVolatility symbol (fromDate:DateTime) (toDate:DateTime) =
    let data = getMarketData symbol fromDate toDate
    data
    |> List.fold (fun acc mktdata -> acc + Math.Log(mktdata.High / mktdata.Low) )  0.0
    |> (*) ( 1.0 / ( ( 2.0 * System.Convert.ToDouble(data.Length)) * System.Math.Sqrt(System.Math.Log(2.0)) ) )
    |> (*) (System.Math.Sqrt 252.0)

//closeVolatility "MSFT" (new DateTime(2010,1,1)) (new DateTime(2010,1,30));;
let closeVolatility symbol (fromDate:DateTime) (toDate:DateTime) =
        let data = getMarketData symbol fromDate toDate
        let rec close (dt: MarketData list)  =
            match dt with
            | x::y::[] -> System.Math.Pow(System.Math.Log((y.Close / x.Close)),2.0)
            | x::y::tail -> System.Math.Pow(System.Math.Log((y.Close / x.Close)),2.0)  + (close (List.append [y] tail))
            | [] -> 0.0

        let rec close1 (dt: MarketData list)  =
            match dt with
            | x::y::[] -> System.Math.Log(y.Close / x.Close)
            | x::y::tail -> System.Math.Log(y.Close / x.Close)  + (close1 (List.append [y] tail))
            | [] -> 0.0

        let firstValue = data
                            |> close
                            |> (*) (1.0 / (System.Convert.ToDouble(data.Length - 1) - 1.0))

        let secondValue = (System.Math.Pow((close1 data), 2.0)) * ( 1.0 / (System.Convert.ToDouble(data.Length - 1) *(System.Convert.ToDouble(data.Length - 1) - 1.0 )))

        System.Math.Sqrt (firstValue - secondValue) * System.Math.Sqrt(252.0)     

//highLowCloseVolatility "MSFT" (new DateTime(2010,1,1)) (new DateTime(2010,1,30));;
let highLowCloseVolatility symbol (fromDate:DateTime) (toDate:DateTime) =
        let data = getMarketData symbol fromDate toDate
        let highLow (dt: MarketData list) =
                    dt
                    |> List.fold (fun acc x -> acc + (0.5) * System.Math.Pow(System.Math.Log(x.High / x.Low),2.0))  0.0
                    |> (*) ( 1.0 / System.Convert.ToDouble(data.Length - 1))

        let rec closeCalc (dt: MarketData list)  =
                    match dt with
                    | x::y::[] -> ((2.0 * System.Math.Log(2.0)) - 1.0) * System.Math.Pow(System.Math.Log((y.Close / x.Close)),2.0)
                    | x::y::tail -> ((2.0 * System.Math.Log(2.0)) - 1.0) * System.Math.Pow(System.Math.Log((y.Close / x.Close)),2.0)  + (closeCalc (List.append [y] tail))
                    | [] -> 0.0

        let close (dt: MarketData list) =
                dt
                |> closeCalc
                |> (*) ( 1.0 / System.Convert.ToDouble(data.Length - 1))

        System.Math.Sqrt(252.0) * System.Math.Sqrt((highLow data.Tail) - (close data))

 

Advertisements

One thought on “Historical Volatility

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s