blob: e9e043c8920238fa2914c7179ab859004ec5f80d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
import Data.Aeson
import qualified Data.Text as T
import GHC.Generics
import Porcupine
import Prelude hiding (id, (.))
-- This example uses the porcupine to read a data that represents the evloution of a given stock in given data and
-- gives back the average and standard deviation of the stock on that date.
data Stockdaily = Stockdaily {date :: String , close :: Double}
deriving (Generic)
instance FromJSON Stockdaily
newtype Stock = Stock { chart :: [Stockdaily] }
deriving (Generic)
instance FromJSON Stock
getCloseStock :: Stock -> [Double]
getCloseStock s = map close (chart s)
-- | How to load Stock prices
stockFile :: DataSource Stock
stockFile = dataSource ["Inputs", "Stock"]
(somePureDeserial JSONSerial)
-- | How to write the smoothed stock prices
globalMatrix :: DataSink (Tabular [[Double]])
globalMatrix = dataSink ["Outputs" , "globalData"]
(somePureSerial (CSVSerial (T.pack "csv") False ','))
avg :: [Double] -> Double
avg list = let s = sum list
n = fromIntegral (length list)
in s/n
msliding :: Int -> [a] -> [[a]]
msliding n p = case p of
[] -> []
(_:xs) -> [take n p] ++ (msliding n xs)
-- | The simple computation we want to perform
computeSmoothedCurve :: Stock -> [Double]
computeSmoothedCurve s = curve
where
price = getCloseStock s
curve = map avg (msliding 10 price)
analyseStocks :: (LogThrow m) => PTask m () ()
analyseStocks =
arr (const ["aapl"::TRIndex, "fb" , "googl"]) -- We want the stocks for some
-- fixed set of companies
>>> loadDataList "company" stockFile
>>> arr (Tabular Nothing . map (\(_idx,stock) -> computeSmoothedCurve stock))
>>> writeData globalMatrix
main :: IO ()
main = runPipelineTask (FullConfig "example2" "porcupine-example2.yaml" "porcupine-core/examples/example2/data" ())
-- The CLI/Yaml configuration to use (prog name,
-- default config file to create, and default root to
-- use for the porcupine tree)
(baseContexts "")
-- The contexts to use. 'baseContexts' is the
-- minimum. It gives out katip logging and local files
-- access (through ResourceT). The string param is the
-- top namespace for the logger. When we use
-- FullConfig (and therefore CLI), the progName for
-- the CLI given above ("example1") will be inherited
-- by the logger, so we can leave it blank
analyseStocks ()
|