simfin-1.0.0: examples/Prices.hs
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main
( main
) where
import Control.Monad
import Data.Time.Calendar
import Data.Time.LocalTime
import Data.Maybe
import Data.Either
import qualified Data.Text as T
import Graphics.Rendering.Chart.Easy hiding (close)
import Graphics.Rendering.Chart.Backend.Diagrams
import SimFin.Free
to5pm :: Day -> LocalTime
to5pm = flip LocalTime $ dayFractionToTimeOfDay $ 17 / 24
toDataPoint :: PricesRow Double -> Maybe (LocalTime, Double)
toDataPoint row = do
day <- date row
pure (to5pm day, close row)
stonks :: [StockRef]
stonks = ["GOOG", "AAPL", "TWTR", "NFLX"]
type LineData = (String, [(LocalTime, Double)])
toLine :: [PricesRow Double] -> Maybe LineData
toLine [] = Nothing
toLine pts@(PricesRow{ticker = t} : _) = Just
( T.unpack t
, catMaybes $ toDataPoint <$> pts
)
main :: IO ()
main = do
ctx <- createDefaultContext
pricesRes :: [ApiResult [PricesRow Double]] <- traverse (fetchPrices ctx) stonks
let prices :: [LineData] = catMaybes $ toLine <$> rights pricesRes
toFile def "prices.svg" $ do
layout_title .= "Price History"
layout_background .= solidFillStyle (opaque white)
layout_foreground .= opaque black
layout_left_axis_visibility . axis_show_ticks .= False
layout_x_axis . laxis_title .= "Date"
layout_y_axis . laxis_title .= "Price ($)"
forM_ prices $ \(name, pts) -> plot $ line name [pts]
pure ()