Packages

Trading technical indicators library for Gleam. SMA, EMA, MACD, RSI, Stochastic, Bollinger Bands, ATR, VWAP, OBV.

Current section

Files

Jump to
ursatoro src ursatoro@trend.erl
Raw

src/ursatoro@trend.erl

-module(ursatoro@trend).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/ursatoro/trend.gleam").
-export([sma/2, ema/2, macd/4]).
-export_type([macd_result/0]).
-type macd_result() :: {macd_result, float(), float(), float()}.
-file("src/ursatoro/trend.gleam", 16).
-spec sma(list(ursatoro@candle:candle()), integer()) -> {ok, list(float())} |
{error, ursatoro@util:indicator_error()}.
sma(Candles, Period) ->
Closes = gleam@list:map(Candles, fun ursatoro@candle:close/1),
gleam@result:'try'(
ursatoro@util:sma_values(Closes, Period),
fun(Values) -> {ok, ursatoro@util:bds_to_floats(Values)} end
).
-file("src/ursatoro/trend.gleam", 63).
-spec ema_multiplier(integer()) -> bigdecimal:big_decimal().
ema_multiplier(Period) ->
Two = ursatoro@util:int_to_bd(2),
Period_plus_one = ursatoro@util:int_to_bd(Period + 1),
bigdecimal:divide(Two, Period_plus_one, half_up).
-file("src/ursatoro/trend.gleam", 115).
-spec list_split(list(HXH), integer()) -> {list(HXH), list(HXH)}.
list_split(Items, At) ->
{gleam@list:take(Items, At), gleam@list:drop(Items, At)}.
-file("src/ursatoro/trend.gleam", 36).
-spec ema_from_values(list(bigdecimal:big_decimal()), integer()) -> {ok,
list(bigdecimal:big_decimal())} |
{error, ursatoro@util:indicator_error()}.
ema_from_values(Values, Period) ->
gleam@result:'try'(
ursatoro@util:validate_period(Period),
fun(_) ->
gleam@result:'try'(
ursatoro@util:validate_length(Values, Period),
fun(_) ->
K = ema_multiplier(Period),
One_minus_k = bigdecimal:subtract(bigdecimal:one(), K),
{Initial, Rest} = list_split(Values, Period),
gleam@result:'try'(
ursatoro@util:bd_mean(Initial),
fun(First_ema) ->
{Results@1, _} = gleam@list:fold(
Rest,
{[First_ema], First_ema},
fun(Acc, Value) ->
{Results, Prev_ema} = Acc,
New_ema = bigdecimal:add(
bigdecimal:multiply(Value, K),
bigdecimal:multiply(
Prev_ema,
One_minus_k
)
),
{[New_ema | Results], New_ema}
end
),
{ok, lists:reverse(Results@1)}
end
)
end
)
end
).
-file("src/ursatoro/trend.gleam", 27).
-spec ema(list(ursatoro@candle:candle()), integer()) -> {ok, list(float())} |
{error, ursatoro@util:indicator_error()}.
ema(Candles, Period) ->
Closes = gleam@list:map(Candles, fun ursatoro@candle:close/1),
gleam@result:'try'(
ema_from_values(Closes, Period),
fun(Values) -> {ok, ursatoro@util:bds_to_floats(Values)} end
).
-file("src/ursatoro/trend.gleam", 71).
-spec macd(list(ursatoro@candle:candle()), integer(), integer(), integer()) -> {ok,
list(macd_result())} |
{error, ursatoro@util:indicator_error()}.
macd(Candles, Fast, Slow, Signal) ->
gleam@result:'try'(
ursatoro@util:validate_period(Fast),
fun(_) ->
gleam@result:'try'(
ursatoro@util:validate_period(Slow),
fun(_) ->
gleam@result:'try'(
ursatoro@util:validate_period(Signal),
fun(_) ->
Closes = gleam@list:map(
Candles,
fun ursatoro@candle:close/1
),
gleam@result:'try'(
ursatoro@util:validate_length(
Closes,
(Slow + Signal) - 1
),
fun(_) ->
gleam@result:'try'(
ema_from_values(Closes, Fast),
fun(Fast_ema) ->
gleam@result:'try'(
ema_from_values(Closes, Slow),
fun(Slow_ema) ->
Fast_len = erlang:length(
Fast_ema
),
Slow_len = erlang:length(
Slow_ema
),
Offset = Fast_len - Slow_len,
Aligned_fast = gleam@list:drop(
Fast_ema,
Offset
),
Macd_line = gleam@list:map2(
Aligned_fast,
Slow_ema,
fun bigdecimal:subtract/2
),
gleam@result:'try'(
ema_from_values(
Macd_line,
Signal
),
fun(Signal_ema) ->
Macd_len = erlang:length(
Macd_line
),
Signal_len = erlang:length(
Signal_ema
),
Macd_offset = Macd_len
- Signal_len,
Aligned_macd = gleam@list:drop(
Macd_line,
Macd_offset
),
Results = gleam@list:map2(
Aligned_macd,
Signal_ema,
fun(M, S) ->
Histogram = bigdecimal:subtract(
M,
S
),
{macd_result,
ursatoro@util:bd_to_float(
M
),
ursatoro@util:bd_to_float(
S
),
ursatoro@util:bd_to_float(
Histogram
)}
end
),
{ok, Results}
end
)
end
)
end
)
end
)
end
)
end
)
end
).