defmodule Tai.VenueAdapters.OkEx.Product do
alias ExOkex.{Futures, Swap, Spot}
@iso_date_format "{ISOdate}"
@zone "Etc/UTC"
def build(%Futures.Instrument{} = instrument, venue_id) do
listing = instrument.listing |> Timex.parse!(@iso_date_format) |> DateTime.from_naive!(@zone)
expiry = instrument.delivery |> Timex.parse!(@iso_date_format) |> DateTime.from_naive!(@zone)
is_inverse = instrument.is_inverse == "true"
build_product(
type: :future,
venue_id: venue_id,
venue_symbol: instrument.instrument_id,
alias: instrument.alias,
base: instrument.base_currency,
quote: instrument.quote_currency,
listing: listing,
expiry: expiry,
venue_price_increment: instrument.tick_size,
venue_size_increment: instrument.trade_increment,
value: instrument.contract_val,
value_side: :quote,
is_inverse: is_inverse,
is_quanto: false
)
end
@iso_extended_format "{ISO:Extended}"
def build(%Swap.Instrument{} = instrument, venue_id) do
listing = Timex.parse!(instrument.listing, @iso_extended_format)
is_inverse = instrument.is_inverse == "true"
build_product(
type: :swap,
venue_id: venue_id,
venue_symbol: instrument.instrument_id,
base: instrument.base_currency,
quote: instrument.quote_currency,
listing: listing,
venue_price_increment: instrument.tick_size,
venue_size_increment: instrument.size_increment,
value: instrument.contract_val,
value_side: :quote,
is_inverse: is_inverse,
is_quanto: false
)
end
def build(%Spot.Instrument{} = instrument, venue_id) do
build_product(
type: :spot,
venue_id: venue_id,
venue_symbol: instrument.instrument_id,
base: instrument.base_currency,
quote: instrument.quote_currency,
venue_price_increment: instrument.tick_size,
venue_size_increment: instrument.size_increment,
venue_min_size: instrument.min_size,
value: 1,
value_side: :base,
is_inverse: false,
is_quanto: false
)
end
def to_symbol(instrument_id) do
instrument_id
|> String.replace("-", "_")
|> downcase_and_atom
end
defp downcase_and_atom(str), do: str |> String.downcase() |> String.to_atom()
defp build_product(args) do
venue_symbol = Keyword.fetch!(args, :venue_symbol)
product_alias = args |> Keyword.get(:alias)
venue_size_increment = Keyword.fetch!(args, :venue_size_increment)
symbol = venue_symbol |> to_symbol()
price_increment = args |> Keyword.fetch!(:venue_price_increment) |> Tai.Utils.Decimal.cast!()
size_increment = venue_size_increment |> Tai.Utils.Decimal.cast!()
min_size = args |> Keyword.get(:venue_min_size, venue_size_increment) |> Tai.Utils.Decimal.cast!()
value = args |> Keyword.fetch!(:value) |> Tai.Utils.Decimal.cast!()
value_side = args |> Keyword.fetch!(:value_side)
listing = args |> Keyword.get(:listing)
expiry = args |> Keyword.get(:expiry)
base_asset = Keyword.fetch!(args, :base)
quote_asset = Keyword.fetch!(args, :quote)
%Tai.Venues.Product{
venue_id: Keyword.fetch!(args, :venue_id),
symbol: symbol,
venue_symbol: venue_symbol,
alias: product_alias,
base: base_asset |> downcase_and_atom(),
quote: quote_asset |> downcase_and_atom(),
venue_base: base_asset,
venue_quote: quote_asset,
status: :trading,
type: Keyword.fetch!(args, :type),
listing: listing,
expiry: expiry,
collateral: false,
price_increment: price_increment,
size_increment: size_increment,
min_price: price_increment,
min_size: min_size,
value: value,
value_side: value_side,
is_quanto: Keyword.fetch!(args, :is_quanto),
is_inverse: Keyword.fetch!(args, :is_inverse)
}
end
end