Current section

Files

Jump to
bingex lib bingex order.ex
Raw

lib/bingex/order.ex

defmodule Bingex.Order do
@moduledoc """
Defines the structure and types for orders in BingX.
This module provides the `Bingex.Order` struct along with associated types
for order properties such as type, status, side, position side, and margin mode.
It also includes functions to create and validate orders.
"""
import Bingex.Order.Validators
@fields [
:type,
:symbol,
:side,
:position_side,
:quantity,
:price,
:stop_price,
:working_type
]
defstruct @fields
@typedoc """
Represents an order in BingX.
Fields:
- `type` - The type of order (e.g., market, limit, stop-loss).
- `symbol` - The trading pair symbol.
- `side` - The order side, either `:buy` or `:sell`.
- `position_side` - Specifies whether the position is `:long`, `:short`, or `:both`.
- `quantity` - The amount of the asset to be traded.
- `price` - The order price.
- `stop_price` - The stop price for stop-loss or take-profit orders.
- `working_type` - The price type used (`:mark_price`, `:index_price`, or `:contract_price`).
"""
@type t() :: %__MODULE__{
:type => type(),
:symbol => binary(),
:side => side(),
:position_side => position_side(),
:quantity => float(),
:price => nil | float(),
:stop_price => nil | float(),
:working_type => nil | working_type()
}
@type type() ::
:market
| :trigger_market
| :stop_loss
| :take_profit
| :limit
| :stop_loss_market
| :take_profit_market
@type status() ::
:placed
| :triggered
| :filled
| :partially_filled
| :canceled
| :canceled
| :expired
@type side() :: :buy | :sell
@type position_side() :: :long | :short | :both
@type working_type() :: :mark_price | :index_price | :contract_price
@type execution_type() ::
:placed
| :canceled
| :calculated
| :expired
| :trade
@type margin_mode() :: :isolated | :crossed
@doc """
Creates `Bingex.Order` struct using the provided parameters.
Note that it only performs validation for the specified values,
leaving `nil` for the rest.
"""
def new(params) do
with {:ok, params} <- validate_params(params) do
{:ok, struct(__MODULE__, params)}
end
end
@doc """
The same as new/1 but returns struct and raises error instead of tuples.
"""
def new!(params) do
case validate_params(params) do
{:ok, params} -> struct(__MODULE__, params)
{:error, reason} -> raise ArgumentError, reason
end
end
#
# Helpers
#
defp validate_params(params) do
Enum.reduce_while(params, {:ok, %{}}, &validate_param/2)
end
defp validate_param({k, v} = kv, {:ok, acc}) when k in @fields do
case validate(k, v) do
{:ok, _} -> {:cont, {:ok, merge_kv(acc, kv)}}
{:error, reason} -> {:halt, {:error, reason}}
end
end
defp validate_param(_, acc), do: {:cont, acc}
defp merge_kv(acc, {_, _} = kv) do
Map.merge(acc, Map.new([kv]))
end
end