Current section
Files
Jump to
Current section
Files
lib/ibkr_api/client_portal/order.ex
defmodule IbkrApi.ClientPortal.Order do
@moduledoc """
`IbkrApi.ClientPortal.Order` module for managing order placement and monitoring.
"""
defmodule LiveOrder do
defstruct [:execution_id, :symbol, :side, :order_description, :trade_time, :trade_time_r, :size, :price, :order_ref, :submitter, :exchange, :commission, :net_amount, :account, :acountCode, :company_name, :contract_description_1, :sec_type, :conid, :conidex, :position, :clearing_id, :clearing_name, :liquidation_trade]
end
defmodule OrderResponse do
defstruct [:filters, :orders, :snapshot]
end
defmodule OrderStatusResponse do
defstruct [:sub_type, :request_id, :order_id, :conidex, :symbol, :side, :contract_description_1, :listing_exchange, :option_acct, :company_name, :size, :total_size, :currency, :account, :order_type, :limit_price, :stop_price, :cum_fill, :order_status, :order_status_description, :tif, :fg_color, :bg_color, :order_not_editable, :editable_fields, :cannot_cancel_order, :outside_rth, :deactivate_order, :use_price_mgmt_algo, :sec_type, :available_chart_periods, :order_description, :order_description_with_contract, :alert_active, :child_order_type, :size_and_fills, :exit_strategy_display_price, :exit_strategy_chart_description, :exit_strategy_tool_availability, :allowed_duplicate_opposite, :order_time, :oca_group_id]
end
defmodule ModifyOrderRequest do
@moduledoc """
Struct representing a request to modify an existing order.
"""
@typedoc """
Type representing a modify order request struct.
"""
@type t :: %__MODULE__{
acct_id: String.t() | nil,
conid: integer() | nil,
order_type: String.t() | nil,
outside_rth: boolean() | nil,
price: float() | nil,
aux_price: float() | nil,
side: String.t() | nil,
listing_exchange: String.t() | nil,
ticker: String.t() | nil,
tif: String.t() | nil,
quantity: integer() | nil,
deactivated: boolean() | nil
}
defstruct [
acct_id: nil,
conid: nil,
order_type: nil,
outside_rth: nil,
price: nil,
aux_price: nil,
side: nil,
listing_exchange: nil,
ticker: nil,
tif: nil,
quantity: nil,
deactivated: nil
]
end
defmodule ModifyOrderResponse do
defstruct [
order_id: nil,
local_order_id: nil,
order_status: nil
]
end
defmodule CancelOrderResponse do
defstruct [
order_id: nil,
msg: nil,
conid: nil,
account: nil
]
end
defmodule OrderPreviewRequest do
@moduledoc """
Struct representing a request to preview an order before placement.
"""
@typedoc """
Type representing an order preview request struct.
"""
@type t :: %__MODULE__{
acct_id: String.t() | nil,
conid: integer() | nil,
conidex: String.t() | nil,
sec_type: String.t() | nil,
c_oid: String.t() | nil,
parent_id: String.t() | nil,
order_type: String.t() | nil,
listing_exchange: String.t() | nil,
is_single_group: boolean() | nil,
outside_rth: boolean() | nil,
price: float() | nil,
aux_price: float() | nil,
side: String.t() | nil,
ticker: String.t() | nil,
tif: String.t() | nil,
trailing_amt: float() | nil,
trailing_type: String.t() | nil,
referrer: String.t() | nil,
quantity: integer() | nil,
cash_qty: float() | nil,
fx_qty: float() | nil,
use_adaptive: boolean() | nil,
is_ccy_conv: boolean() | nil,
allocation_method: String.t() | nil,
strategy: String.t() | nil,
strategy_parameters: map()
}
defstruct [
acct_id: nil,
conid: nil,
conidex: nil,
sec_type: nil,
c_oid: nil,
parent_id: nil,
order_type: nil,
listing_exchange: nil,
is_single_group: nil,
outside_rth: nil,
price: nil,
aux_price: nil,
side: nil,
ticker: nil,
tif: nil,
trailing_amt: nil,
trailing_type: nil,
referrer: nil,
quantity: nil,
cash_qty: nil,
fx_qty: nil,
use_adaptive: nil,
is_ccy_conv: nil,
allocation_method: nil,
strategy: nil,
strategy_parameters: %{}
]
end
defmodule OrderPreviewResponse do
defstruct [
amount: %{},
equity: %{},
initial: %{},
maintenance: %{},
warn: nil,
error: nil
]
end
defmodule OrderRequest do
@moduledoc """
Struct representing a request to place a new order.
"""
@typedoc """
Type representing an order request struct.
"""
@type t :: %__MODULE__{
acct_id: String.t() | nil,
conid: integer() | nil,
conidex: String.t() | nil,
sec_type: String.t() | nil,
c_oid: String.t() | nil,
parent_id: String.t() | nil,
order_type: String.t() | nil,
listing_exchange: String.t() | nil,
is_single_group: boolean() | nil,
outside_rth: boolean() | nil,
price: float() | nil,
aux_price: float() | nil,
side: String.t() | nil,
ticker: String.t() | nil,
tif: String.t() | nil,
trailing_amt: float() | nil,
trailing_type: String.t() | nil,
referrer: String.t() | nil,
quantity: integer() | nil,
cash_qty: float() | nil,
fx_qty: float() | nil,
use_adaptive: boolean() | nil,
is_ccy_conv: boolean() | nil,
allocation_method: String.t() | nil,
strategy: String.t() | nil,
strategy_parameters: map()
}
defstruct [
acct_id: nil, conid: nil, conidex: nil, sec_type: nil, c_oid: nil,
parent_id: nil, order_type: nil, listing_exchange: nil, is_single_group: nil,
outside_rth: nil, price: nil, aux_price: nil, side: nil, ticker: nil, tif: nil,
trailing_amt: nil, trailing_type: nil, referrer: nil, quantity: nil, cash_qty: nil,
fx_qty: nil, use_adaptive: nil, is_ccy_conv: nil, allocation_method: nil,
strategy: nil, strategy_parameters: %{}
]
end
defmodule OrderReplyResponse do
defstruct order_id: nil, order_status: nil, local_order_id: nil
end
defmodule OrderPlacementResponse do
defstruct id: nil, message: []
end
alias IbkrApi.HTTP
@base_url IbkrApi.Config.base_url()
@spec get_live_orders() :: ErrorMessage.t_res()
def get_live_orders do
with {:ok, response} <- HTTP.get(Path.join(@base_url, "iserver/account/orders")) do
{:ok, struct(OrderResponse, response)}
end
end
@spec get_order_status(String.t()) :: ErrorMessage.t_res()
def get_order_status(order_id) do
with {:ok, response} <- HTTP.get(Path.join(@base_url, "iserver/account/order/status/#{order_id}")) do
{:ok, struct(OrderStatusResponse, response)}
end
end
@spec modify_order(String.t(), String.t(), ModifyOrderRequest.t()) :: ErrorMessage.t_res()
def modify_order(account_id, order_id, %ModifyOrderRequest{} = modify_order_request) do
with {:ok, response} <- HTTP.post(Path.join(@base_url, "/iserver/account/#{account_id}/order/#{order_id}"), modify_order_request) do
{:ok, struct(ModifyOrderResponse, response)}
end
end
@spec cancel_order(String.t(), String.t()) :: ErrorMessage.t_res()
def cancel_order(account_id, order_id) do
with {:ok, response} <- HTTP.delete(Path.join(@base_url, "/iserver/account/#{account_id}/order/#{order_id}")) do
{:ok, struct(CancelOrderResponse, response)}
end
end
@spec preview_order(String.t(), list(OrderPreviewRequest.t())) :: ErrorMessage.t_res()
def preview_order(account_id, orders) do
body = %{"orders" => orders}
with {:ok, response} <- HTTP.post(Path.join(@base_url, "/iserver/account/#{account_id}/orders/whatif"), body) do
{:ok, struct(OrderPreviewResponse, response)}
end
end
@spec place_orders(String.t(), list(OrderRequest.t())) :: ErrorMessage.t_res()
def place_orders(account_id, orders) do
body = %{"orders" => orders}
with {:ok, response} <- HTTP.post(Path.join(@base_url, "/iserver/account/#{account_id}/orders"), body) do
{:ok, Enum.map(response, &struct(OrderPlacementResponse, &1))}
end
end
@spec place_orders_for_fa(String.t(), list(OrderRequest.t())) :: ErrorMessage.t_res()
def place_orders_for_fa(fa_group, orders) do
body = %{"orders" => orders}
with {:ok, response} <- HTTP.post(Path.join(@base_url, "/iserver/account/orders/#{fa_group}"), body) do
{:ok, Enum.map(response, &struct(OrderPlacementResponse, &1))}
end
end
@spec reply_to_order_query(String.t(), boolean) :: ErrorMessage.t_res()
def reply_to_order_query(reply_id, confirmed) do
body = %{"confirmed" => confirmed}
with {:ok, response} <- HTTP.post(Path.join(@base_url, "/iserver/reply/#{reply_id}"), body) do
{:ok, struct(OrderReplyResponse, response)}
end
end
end