Skip to content

Commit 83171c6

Browse files
committed
Ma indicator conduit wip
1 parent 4504c0a commit 83171c6

File tree

1 file changed

+57
-12
lines changed
  • pub/bfx/src/Bfx/Indicator

1 file changed

+57
-12
lines changed

pub/bfx/src/Bfx/Indicator/Ma.hs

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
module Bfx.Indicator.Ma
44
( Ma (..),
55
MaPeriod (..),
6-
ma,
6+
defMaPeriod,
7+
mkMaConduit,
8+
mkMa,
79
)
810
where
911

1012
import Bfx.Data.Type
13+
import Conduit ((.|))
14+
import qualified Conduit as C
1115
import qualified Data.Map as Map
1216
import qualified Data.Vector as V
1317
import Functora.Money
@@ -20,29 +24,70 @@ newtype Ma = Ma
2024
deriving stock
2125
( Eq,
2226
Ord,
27+
Show,
28+
Read,
2329
Data,
2430
Generic
2531
)
2632

2733
newtype MaPeriod = MaPeriod
2834
{ unMaPeriod :: Natural
2935
}
30-
deriving newtype
36+
deriving stock
3137
( Eq,
3238
Ord,
3339
Show,
34-
Num,
35-
Real,
36-
Enum,
37-
Integral
38-
)
39-
deriving stock
40-
( Data,
40+
Read,
41+
Data,
4142
Generic
4243
)
4344

44-
ma :: MaPeriod -> NonEmpty Candle -> Map UTCTime Ma
45-
ma period candles =
45+
defMaPeriod :: MaPeriod
46+
defMaPeriod = MaPeriod 14
47+
48+
mkMaConduit ::
49+
( Monad m
50+
) =>
51+
(a -> Candle) ->
52+
MaPeriod ->
53+
C.ConduitT a (a, Ma) m ()
54+
mkMaConduit mkCandle per =
55+
C.slidingWindowC period
56+
.| ( whileM $ do
57+
mcandles <- fmap (>>= nonEmpty) C.await
58+
case mcandles of
59+
Just candles | length candles == period -> do
60+
C.yield
61+
( last candles,
62+
Ma
63+
. QuotePerBase
64+
$ ( sum
65+
$ fmap
66+
( unQuotePerBase
67+
. candleClose
68+
. mkCandle
69+
)
70+
candles
71+
)
72+
/ from @Natural @(Ratio Natural)
73+
( unsafeFrom
74+
@Int
75+
@Natural
76+
period
77+
)
78+
)
79+
pure True
80+
_ ->
81+
pure False
82+
)
83+
where
84+
period =
85+
case unsafeFrom @Natural @Int $ unMaPeriod per of
86+
x | x < 1 -> error $ "Bad MA period " <> inspect period
87+
x -> x
88+
89+
mkMa :: MaPeriod -> NonEmpty Candle -> Map UTCTime Ma
90+
mkMa period candles =
4691
if stopAtIdx < 0 || maPeriod < 1
4792
then mempty
4893
else
@@ -53,7 +98,7 @@ ma period candles =
5398
0
5499
mempty
55100
where
56-
maPeriod = Prelude.fromIntegral period
101+
maPeriod = unsafeFrom @Natural @Int $ unMaPeriod period
57102
stopAtIdx = length candles - maPeriod
58103

59104
unsafeMa ::

0 commit comments

Comments
 (0)