diff --git a/src/Makefile b/src/Makefile index f550b9fcf..003346a14 100644 --- a/src/Makefile +++ b/src/Makefile @@ -113,6 +113,7 @@ UTILS_LIB_INTFS := \ utils/lwt_utils.mli \ utils/lwt_pipe.mli \ utils/IO.mli \ + utils/moving_average.mli \ UTILS_LIB_IMPLS := \ utils/mBytes.ml \ @@ -131,6 +132,7 @@ UTILS_LIB_IMPLS := \ utils/lwt_utils.ml \ utils/lwt_pipe.ml \ utils/IO.ml \ + utils/moving_average.ml \ UTILS_PACKAGES := \ base64 \ diff --git a/src/utils/moving_average.ml b/src/utils/moving_average.ml new file mode 100644 index 000000000..00b79977c --- /dev/null +++ b/src/utils/moving_average.ml @@ -0,0 +1,37 @@ +(**************************************************************************) +(* *) +(* Copyright (c) 2014 - 2016. *) +(* Dynamic Ledger Solutions, Inc. *) +(* *) +(* All rights reserved. No warranty, explicit or implicit, provided. *) +(* *) +(**************************************************************************) + +class type ma = object + method add_float : float -> unit + method add_int : int -> unit + method get : float +end + +class virtual base ?(init = 0.) () = object (self) + val mutable acc : float = init + method virtual add_float : float -> unit + method add_int x = self#add_float (float_of_int x) + method get = acc +end + +class sma ?init () = object + inherit base ?init () + val mutable i = match init with None -> 0 | _ -> 1 + method add_float x = + acc <- (acc +. (x -. acc) /. (float_of_int @@ succ i)) ; + i <- succ i +end + +class ema ?init ~alpha () = object + inherit base ?init () + val alpha = alpha + method add_float x = + acc <- alpha *. x +. (1. -. alpha) *. acc +end + diff --git a/src/utils/moving_average.mli b/src/utils/moving_average.mli new file mode 100644 index 000000000..a5768ee51 --- /dev/null +++ b/src/utils/moving_average.mli @@ -0,0 +1,34 @@ +(**************************************************************************) +(* *) +(* Copyright (c) 2014 - 2016. *) +(* Dynamic Ledger Solutions, Inc. *) +(* *) +(* All rights reserved. No warranty, explicit or implicit, provided. *) +(* *) +(**************************************************************************) + +(** Moving averages. The formulas are from Wikipedia + [https://en.wikipedia.org/wiki/Moving_average] *) + +class type ma = object + method add_float : float -> unit + method add_int : int -> unit + method get : float +end +(** Common class type for objects computing a cumulative moving + average of some flavor. In a cumulative moving average, the data + arrive in an ordered datum stream, and the user would like to get + the average of all of the data up until the current datum + point. The method [add_float] and [add_int] are used to add the + next datum. The method [get] and [get_exn] are used to compute the + moving average up until the current datum point. *) + +class sma : ?init:float -> unit -> ma +(** [sma ?init ()] is an object that computes the Simple Moving + Average of a datum stream. [SMA(n+1) = SMA(n) + (x_(n+1) / SMA(n)) + / (n+1)] *) + +class ema : ?init:float -> alpha:float -> unit -> ma +(** [ema ?init ~alpha ()] is an object that computes the Exponential + Moving Average of a datum stream. [EMA(n+1) = alpha * x_(n+1) + + (1 - alpha) * x_n] *)