callmekohei
10/20/2016 - 8:15 PM

volatility for FX market (using OANDA server)

volatility for FX market (using OANDA server)

#if INTERACTIVE
#r "../Oanda.dll"
#I "../packages/FSharp.Data/lib/net40/"
#r "FSharp.Data.DesignTime.dll"
#r "FSharp.Data.dll"
#endif

open System
open System.IO
open System.Reflection
open Oanda
open FSharp.Data
open FSharp.Data.JsonExtensions
open System.Text
open System.Text.RegularExpressions

module Util =

    let Justify lst =
        let swapRowColumn lst =
            lst
            |> List.collect List.indexed
            |> List.groupBy fst
            |> List.map snd
            |> List.map (List.map snd)

        let sjis = Encoding.GetEncoding "Shift_JIS"

        let justify lst =
            let lst = List.map (fun (str : string) -> str, sjis.GetByteCount str) lst
            let max =
                lst
                |> List.map snd
                |> List.max
            List.map (fun (str, len) -> str + String.replicate (max - len) " ") lst

        lst
        |> swapRowColumn
        |> List.map justify
        |> swapRowColumn

    // http://www.fssnip.net/r6
    let toDateTime (timestamp:int) =
        let start = DateTime(1970,1,1,0,0,0,DateTimeKind.Utc)
        start.AddSeconds(float timestamp).ToLocalTime()

    let csv (fileName:string) : array<string> =
        let curdir = string ( Directory.GetParent ( Assembly.GetEntryAssembly().Location ) )
        let filePath_csv = Path.Combine( curdir  , fileName )
        System.IO.File.ReadAllLines(fileName)

module Oanda_Live =

    // account info.
    let fileName = "OandaABC.csv"
    let account = Util.csv fileName
    let accountId   = account.[0]
    let accessToken = account.[1]

    // connecting OANDA server
    Oanda.API.Init ( Oanda.Live ,accountId, accessToken )


    let currency = "USD_JPY"

    let response = Oanda.Rates.Get_history [("instrument",currency)
                                           ;("count","500")
                                           ;("candleFormat","midpoint")
                                           ;("granularity","H1")
                                           ;("dailyAlignment","21")
                                           ;("alignmentTimezone","America/New_York")]

    let jsonValue = FSharp.Data.JsonValue.Parse response
    let candles   = jsonValue.GetProperty "candles"
    let highMid   = candles.AsArray() |> Array.map ( fun jv -> jv.GetProperty("highMid").AsFloat()) |> Array.toList
    let lowMid    = candles.AsArray() |> Array.map ( fun jv -> jv.GetProperty("lowMid").AsFloat())  |> Array.toList
    let time      = candles.AsArray() |> Array.map ( fun jv -> jv.GetProperty("time").AsString() )  |> Array.toList

    (*
        groupByDairy

        [   ("23",
                [(9/23/2016 1:00:00 AM, 101.247); (9/23/2016 2:00:00 AM, 101.2385);
                 (9/23/2016 7:00:00 PM, 101.1655); (9/23/2016 8:00:00 PM, 101.073)]);
            ("25",
                [(9/25/2016 9:00:00 PM, 101.091); (9/25/2016 10:00:00 PM, 101.0405);
                 (9/25/2016 11:00:00 PM, 101.026)]);
    *)

    let groupByDairy tpl =
        tpl ||> List.map2    ( fun x y   -> ( DateTime.Parse(x).ToUniversalTime(), y) )
            |>  List.groupBy ( fun (x,y) -> x.ToString("dd"))


    (*
        toHourDisplay

        [[  ("01", 101.247); ("02", 101.2385); ("03", 101.2225); ("04", 101.1995);
            ("05", 101.1125); ("06", 101.005); ("07", 101.1095); ("08", 101.003);
    *)

    let toHourDisplay l:list<_> =
        l |> List.map ( fun (x, lst) ->
            lst |> List.map ( fun (( x:DateTime), y) -> ( x.ToString("HH"), y)))

    let market ( l:list<_>, start:int, last:int) =
        l |> List.map ( fun l ->
            l |> List.choose ( fun (time, price) ->
                match time with
                | time when (int time ) >= start  && (int time) <= last -> Some price
                | _ -> None)
              |> (fun l -> if List.isEmpty(l) then [0.] else l)
        )

    let MarketHigh (start:int, last:int) =
        (time,highMid)
        |> groupByDairy
        |> toHourDisplay
        |> fun l -> market( l, start, last)
        |> List.map ( List.max)

    let MarketLow (start:int, last:int) =
        (time,lowMid)
        |> groupByDairy
        |> toHourDisplay
        |> fun l -> market( l, start, last)
        |> List.map ( List.min)

    let volatility tpl = tpl ||> List.map2 ( fun x y -> System.Math.Floor( 1000. * (x - y)))



    let TokyoHigh   = MarketHigh(0,6)
    let TokyoLow    = MarketLow (0,6)
    let LondonHigh  = MarketHigh(7,15)
    let LondonLow   = MarketLow (7,15)
    let NewYorkHigh = MarketHigh(12,20)
    let NewYorkLow  = MarketLow (12,20)

    let Tokyo   = (TokyoHigh,TokyoLow)     |> volatility |> List.rev |> List.map ( fun n -> string n)
    let London  = (LondonHigh,LondonLow)   |> volatility |> List.rev |> List.map ( fun n -> string n)
    let NewYork = (NewYorkHigh,NewYorkLow) |> volatility |> List.rev |> List.map ( fun n -> string n)

    let Volatility = (Tokyo,London,NewYork) |||> List.map3 ( fun x y z -> [x;y;z])

    [["Tokyo";"London";"NewYork"]] @ [["-------";"-------";"-------"]] @ Volatility
    |> Util.Justify
    |> List.iter ( fun [a;b;c] -> printfn "%s\t%s\t%s" a b c )