Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert bitmex product types #344

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions apps/tai/lib/tai/venue_adapters/bitmex/product.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule Tai.VenueAdapters.Bitmex.Product do

def build(instrument, venue_id) do
symbol = instrument.symbol |> downcase_and_atom
type = instrument.expiry |> type()
type = Tai.VenueAdapters.Bitmex.ProductType.normalize(instrument.typ)
status = Tai.VenueAdapters.Bitmex.ProductStatus.normalize(instrument.state)
listing = instrument.listing && Timex.parse!(instrument.listing, @format)
expiry = instrument.expiry && Timex.parse!(instrument.expiry, @format)
Expand Down Expand Up @@ -45,7 +45,4 @@ defmodule Tai.VenueAdapters.Bitmex.Product do
end

def downcase_and_atom(str), do: str |> String.downcase() |> String.to_atom()

defp type(nil), do: :swap
defp type(_), do: :future
end
31 changes: 31 additions & 0 deletions apps/tai/lib/tai/venue_adapters/bitmex/product_type.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
defmodule Tai.VenueAdapters.Bitmex.ProductType do
@type type :: Tai.Venues.Product.type()

@doc """
Maps Bitmex product types to Tai product types.

https://www.bitmex.com/api/explorer/#!/Instrument/Instrument_get

Perpetual Contracts - FFWCSX
Perpetual Contracts (FX underliers) - FFWCSF
Spot - IFXXXP
Futures - FFCCSX
BitMEX Basket Index - MRBXXX
BitMEX Crypto Index - MRCXXX
BitMEX FX Index - MRFXXX
BitMEX Lending/Premium Index - MRRXXX
BitMEX Volatility Index - MRIXXX

## Examples

iex> Tai.VenueAdapters.Bitmex.ProductType.normalize("FFWCSX")
:swap

"""

@spec normalize(bitmex_product_type :: String.t()) :: type
def normalize("FFWCS" <> _), do: :swap # FFWCSX, FFWCSF
def normalize("FFCCS" <> _), do: :future # FFCCSX
def normalize("IF" <> _), do: :spot # IFXXXP
def normalize(_), do: :future
end
20 changes: 3 additions & 17 deletions apps/tai/test/tai/venue_adapters/bitmex/product_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ defmodule Tai.VenuesAdapters.Bitmex.ProductTest do
quote_currency: "USD",
state: "Open",
lot_size: 1,
tick_size: 0.5
tick_size: 0.5,
typ: "FFWCSX"
}

test "returns a product struct from a venue instrument" do
Expand All @@ -28,28 +29,13 @@ defmodule Tai.VenuesAdapters.Bitmex.ProductTest do
assert product.symbol == :xbtusd
assert product.venue_symbol == "XBTUSD"
assert product.status == :trading
assert product.type == :swap
assert product.price_increment == Decimal.new("0.5")
assert product.min_price == Decimal.new("0.5")
assert product.size_increment == Decimal.new(1)
assert product.value == Decimal.new(1)
end

test "type is :future when there is an expiry" do
attrs = Map.merge(@base_attrs, %{expiry: "2020-06-26T12:00:00.000Z"})
instrument = struct(ExBitmex.Instrument, attrs)

product = Tai.VenueAdapters.Bitmex.Product.build(instrument, :venue_a)
assert product.type == :future
end

test "type is :swap when there is no expiry" do
attrs = Map.merge(@base_attrs, %{expiry: nil})
instrument = struct(ExBitmex.Instrument, attrs)

product = Tai.VenueAdapters.Bitmex.Product.build(instrument, :venue_a)
assert product.type == :swap
end

test "assigns maker/taker fee when present" do
attrs = Map.merge(@base_attrs, %{maker_fee: "-0.025", taker_fee: "0.05"})
instrument = struct(ExBitmex.Instrument, attrs)
Expand Down
13 changes: 13 additions & 0 deletions apps/tai/test/tai/venue_adapters/bitmex/product_type_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
defmodule Tai.VenueAdapters.Bitmex.ProductTypeTest do
use ExUnit.Case, async: true
alias Tai.VenueAdapters.Bitmex

test ".normalize/1 converts product type" do
assert Bitmex.ProductType.normalize("FFWCSX") == :swap
assert Bitmex.ProductType.normalize("FFWCSF") == :swap
assert Bitmex.ProductType.normalize("IFXXXP") == :spot
assert Bitmex.ProductType.normalize("FFCCSX") == :future

assert Bitmex.ProductType.normalize("XXXXXX") == :future, "fallback to future"
end
end
3 changes: 3 additions & 0 deletions apps/tai/test/tai/venues/adapters/products_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ defmodule Tai.Venues.Adapters.ProductsTest do
assert product.venue_id == @venue.id
assert product.symbol != nil
assert product.status != nil
assert product.type != nil
assert %Decimal{} = product.min_size
assert %Decimal{} = product.min_price
assert %Decimal{} = product.size_increment
Expand All @@ -50,6 +51,7 @@ defmodule Tai.Venues.Adapters.ProductsTest do
min_price: Decimal.new("0.01"),
size_increment: Decimal.new("0.001"),
price_increment: Decimal.new("0.01"),
type: :spot
},
%{
symbol: :ltc_usd,
Expand All @@ -59,6 +61,7 @@ defmodule Tai.Venues.Adapters.ProductsTest do
min_price: Decimal.new("0.01"),
size_increment: Decimal.new("0.001"),
price_increment: Decimal.new("0.01"),
type: :spot
}
]
)
Expand Down