File: ma.h

package info (click to toggle)
linuxtrade 3.65-6
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,880 kB
  • ctags: 1,969
  • sloc: ansic: 30,091; sh: 2,278; perl: 566; makefile: 126
file content (61 lines) | stat: -rw-r--r-- 1,365 bytes parent folder | download | duplicates (2)
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

typedef struct smaint *SMAINT;

SMAINT	smaint_new(int size, int initval);
int	smaint_add(SMAINT sma, int value);
int	smaint(SMAINT sma);
void	smaint_free(SMAINT sma);

static inline double
ema(int n, double oldema, double val)
{
    return (val*2.0/(n+1)) + oldema*(1-2.0/(n+1));
}

/*

Now the Exponential Moving Average (EMA) is easy to compute and defined as:

        EMA(N) = VALUE(N)*K + EMA(N-1)*(1-K)

Where:
	K = 2 / (N+1)

If you limit the possible values of 1/K to powers of two *AND* you
don't care if it ever decays back down to zero, then the EMA is very
easily computed using two integer adds and two shifts.  For N=15, which
is a K value of (2/16 = 1/8), you get:

	ema -= ema >> 3;
	ema += value >> 3;

If you want the ema value to have the characteristic that it decays
down to zero (eventually), then you can do rounding arithmetic.

*/

typedef struct
{
    int	ema;
    int	k_order;
    int	k_inverted_minus_1;
    int round;
} EMAINT;

static inline void
emaint_init(EMAINT *ema, int k_order, int initval)
{
    ema->ema = initval;
    ema->k_order = k_order;
    ema->k_inverted_minus_1 = (1 << k_order) - 1;
    ema->round = 0;
}

static inline int
emaint(EMAINT *ema, int val)
{
    ema->round ^= ema->k_inverted_minus_1;
    ema->ema -= (ema->ema + ema->round) >> ema->k_order;
    ema->ema += val >> ema->k_order;
    return ema->ema;
}