Packages
tai
0.0.46
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/markets/quote.ex
defmodule Tai.Markets.Quote do
@moduledoc """
Represents the inside bid & ask price point within the order book
"""
alias __MODULE__
alias Tai.Markets.PricePoint
@type price_point :: PricePoint.t()
@type venue_id :: Tai.Venues.Adapter.venue_id()
@type product_symbol :: Tai.Venues.Product.symbol()
@type t :: %Quote{
venue_id: venue_id,
product_symbol: product_symbol,
bids: [price_point],
asks: [price_point],
last_received_at: DateTime.t() | nil,
last_venue_timestamp: DateTime.t() | nil
}
@enforce_keys ~w(venue_id product_symbol)a
defstruct venue_id: nil,
product_symbol: nil,
bids: [],
asks: [],
last_received_at: nil,
last_venue_timestamp: nil
@spec inside_bid(t) :: price_point | nil
def inside_bid(market_quote), do: market_quote.bids |> List.first()
@spec inside_ask(t) :: price_point | nil
def inside_ask(market_quote), do: market_quote.asks |> List.first()
@spec mid_price(t) :: {:ok, Decimal.t()} | {:error, :no_inside_bid | :no_inside_ask}
@spec mid_price(bid :: price_point, ask :: price_point) ::
{:ok, Decimal.t()} | {:error, :no_inside_bid | :no_inside_ask | :no_inside_bid_or_ask}
def mid_price(%Quote{} = market_quote) do
bid = market_quote |> inside_bid
ask = market_quote |> inside_ask
mid_price(bid, ask)
end
@two Decimal.new(2)
def mid_price(%PricePoint{} = bid, %PricePoint{} = ask) do
ask_price = Decimal.cast(ask.price)
bid_price = Decimal.cast(bid.price)
mid =
ask_price
|> Decimal.sub(bid_price)
|> Decimal.div(@two)
|> Decimal.add(bid_price)
{:ok, mid}
end
def mid_price(nil, %PricePoint{}), do: {:error, :no_inside_bid}
def mid_price(%PricePoint{}, nil), do: {:error, :no_inside_ask}
def mid_price(nil, nil), do: {:error, :no_inside_bid_or_ask}
end
defimpl Stored.Item, for: Tai.Markets.Quote do
@type market_quote :: Tai.Markets.Quote.t()
@type venue_id :: Tai.Venues.Adapter.venue_id()
@type product_symbol :: Tai.Venues.Product.symbol()
@spec key(market_quote) :: {venue_id, product_symbol}
def key(q), do: {q.venue_id, q.product_symbol}
end