Current section
Files
Jump to
Current section
Files
lib/alpa/trading/market.ex
defmodule Alpa.Trading.Market do
@moduledoc """
Market clock and calendar operations for the Alpaca Trading API.
"""
alias Alpa.Client
alias Alpa.Models.Calendar
alias Alpa.Models.Clock
@doc """
Get the current market clock.
Returns whether the market is open and the next open/close times.
## Examples
iex> Alpa.Trading.Market.get_clock()
{:ok, %Alpa.Models.Clock{
timestamp: ~U[2024-01-15 14:30:00Z],
is_open: true,
next_open: ~U[2024-01-16 14:30:00Z],
next_close: ~U[2024-01-15 21:00:00Z]
}}
"""
@spec get_clock(keyword()) :: {:ok, Clock.t()} | {:error, Alpa.Error.t()}
def get_clock(opts \\ []) do
case Client.get("/v2/clock", opts) do
{:ok, data} -> {:ok, Clock.from_map(data)}
{:error, _} = error -> error
end
end
@doc """
Check if the market is currently open.
## Examples
iex> Alpa.Trading.Market.open?()
{:ok, true}
"""
@spec open?(keyword()) :: {:ok, boolean()} | {:error, Alpa.Error.t()}
def open?(opts \\ []) do
case get_clock(opts) do
{:ok, %Clock{is_open: is_open}} -> {:ok, is_open}
{:error, _} = error -> error
end
end
@doc """
Get the market calendar.
Returns trading days and their open/close times for a date range.
## Options
* `:start` - Start date (format: "YYYY-MM-DD" or Date)
* `:end` - End date (format: "YYYY-MM-DD" or Date)
## Examples
iex> Alpa.Trading.Market.get_calendar(start: ~D[2024-01-01], end: ~D[2024-01-31])
{:ok, [
%{"date" => "2024-01-02", "open" => "09:30", "close" => "16:00", ...},
...
]}
"""
@spec get_calendar(keyword()) :: {:ok, [Calendar.t()]} | {:error, Alpa.Error.t()}
def get_calendar(opts \\ []) do
params =
opts
|> Keyword.take([:start, :end])
|> Enum.map(fn
{k, %Date{} = d} -> {k, Date.to_string(d)}
other -> other
end)
|> Enum.reject(fn {_, v} -> is_nil(v) end)
|> Map.new()
case Client.get("/v2/calendar", Keyword.put(opts, :params, params)) do
{:ok, data} when is_list(data) -> {:ok, Enum.map(data, &Calendar.from_map/1)}
{:ok, data} -> {:error, Alpa.Error.invalid_response(data)}
{:error, _} = error -> error
end
end
@doc """
Get the next market open time.
## Examples
iex> Alpa.Trading.Market.next_open()
{:ok, ~U[2024-01-16 14:30:00Z]}
"""
@spec next_open(keyword()) :: {:ok, DateTime.t()} | {:error, Alpa.Error.t()}
def next_open(opts \\ []) do
case get_clock(opts) do
{:ok, %Clock{next_open: next_open}} -> {:ok, next_open}
{:error, _} = error -> error
end
end
@doc """
Get the next market close time.
## Examples
iex> Alpa.Trading.Market.next_close()
{:ok, ~U[2024-01-15 21:00:00Z]}
"""
@spec next_close(keyword()) :: {:ok, DateTime.t()} | {:error, Alpa.Error.t()}
def next_close(opts \\ []) do
case get_clock(opts) do
{:ok, %Clock{next_close: next_close}} -> {:ok, next_close}
{:error, _} = error -> error
end
end
end