Packages
tai
0.0.41
0.0.75
0.0.74
0.0.73
0.0.72
0.0.71
0.0.70
0.0.69
0.0.68
0.0.67
0.0.66
0.0.65
0.0.64
0.0.63
0.0.62
0.0.61
0.0.60
0.0.59
0.0.58
0.0.57
0.0.56
0.0.55
0.0.54
0.0.53
0.0.52
0.0.51
0.0.50
0.0.49
0.0.48
0.0.47
0.0.46
0.0.45
0.0.44
0.0.43
0.0.42
0.0.41
0.0.40
0.0.39
0.0.38
0.0.37
0.0.36
0.0.35
0.0.34
0.0.33
0.0.32
0.0.31
0.0.30
0.0.29
0.0.28
0.0.27
0.0.26
0.0.25
0.0.24
0.0.23
0.0.22
0.0.21
0.0.20
0.0.19
0.0.18
0.0.17
0.0.16
0.0.15
0.0.14
0.0.13
0.0.12
0.0.11
0.0.10
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
A composable, real time, market data and trade execution toolkit
Current section
Files
Jump to
Current section
Files
lib/tai/advisors/groups.ex
defmodule Tai.Advisors.Groups do
alias Tai.Advisors.Groups
@type product :: Tai.Venues.Product.t()
@type advisor_group :: Tai.AdvisorGroup.t()
@type provider :: Groups.RichConfig.provider()
@spec from_config(map, provider) :: {:ok, [advisor_group]} | {:error, map}
def from_config(advisor_groups, provider \\ Groups.RichConfigProvider) do
venue_indexed_symbols = Tai.Transforms.ProductSymbolsByVenue.all(provider.products)
groups = advisor_groups |> Enum.map(&build(&1, provider, venue_indexed_symbols))
errors = groups |> Enum.reduce(%{}, &validate/2)
if Enum.empty?(errors), do: {:ok, groups}, else: {:error, errors}
end
defp build({id, group_config}, provider, venue_indexed_symbols) do
products_query = group_config |> Keyword.get(:products, "")
filtered_venue_indexed_symbols = Juice.squeeze(venue_indexed_symbols, products_query)
filtered_products = filtered_venue_indexed_symbols |> filter_products(provider.products)
rich_config = group_config |> parse_group_config(provider)
%Tai.AdvisorGroup{
id: id,
start_on_boot: !!(group_config |> Keyword.get(:start_on_boot)),
restart: group_config |> Keyword.get(:restart, :temporary),
shutdown: group_config |> Keyword.get(:shutdown, 5000),
advisor: group_config |> Keyword.get(:advisor),
factory: group_config |> Keyword.get(:factory),
products: filtered_products,
config: rich_config,
trades: group_config |> Keyword.get(:trades, [])
}
end
defp parse_group_config(group_config, provider) do
group_config
|> Keyword.get(:config, %{})
|> case do
{s, c} -> struct!(s, c |> Groups.RichConfig.parse(provider))
c -> c |> Groups.RichConfig.parse(provider)
end
end
defp filter_products(filtered_venue_indexed_symbols, products) do
filtered_venue_indexed_symbols
|> Enum.flat_map(fn {venue_id, product_symbols} ->
products
|> Enum.filter(fn p ->
p.venue_id == venue_id && Enum.member?(product_symbols, p.symbol)
end)
end)
end
defp validate(group, errors) do
if Vex.valid?(group) do
errors
else
validation_errors =
group
|> Vex.errors()
|> Enum.map(fn {:error, k, _, m} -> {k, m} end)
Map.put(errors, group.id, validation_errors)
end
end
end