Skip to content

Commit

Permalink
Merge pull request #11 from nicholasbair/manual-models
Browse files Browse the repository at this point in the history
GET models
  • Loading branch information
nicholasbair authored Oct 4, 2024
2 parents 04625c4 + d4df878 commit 867e10a
Show file tree
Hide file tree
Showing 39 changed files with 1,437 additions and 67 deletions.
84 changes: 42 additions & 42 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,26 @@ interfaces:
description: "Get a list of accounts."
http_method: "GET"
path: "/accounts"
response_schema: "ListAccounts"
- function_name: "find"
description: "Fetch an account."
http_method: "GET"
path: "/accounts/:account_id"
response_schema: "FindAccount"
arguments:
- "account_id"
- function_name: "summary"
description: "Get a summary of an account."
http_method: "GET"
path: "/accounts/:account_id/summary"
response_schema: "AccountSummary"
arguments:
- "account_id"
- function_name: "list_instruments"
description: "Get a list of tradeable instruments for the given account."
http_method: "GET"
path: "/accounts/:account_id/instruments"
response_schema: "AccountInstruments"
arguments:
- "account_id"
parameters:
Expand All @@ -39,10 +43,11 @@ interfaces:
description: "Get a list of changes to an account."
http_method: "GET"
path: "/accounts/:account_id/changes"
response_schema: "AccountChanges"
arguments:
- "account_id"
parameters:
- name: "sinceTransactionID"
- name: "since_transaction_id"
type: "string"
doc: "ID of the Transaction to get Account changes since."
- module_name: "Instruments"
Expand All @@ -52,6 +57,7 @@ interfaces:
description: "Get candlestick data for an instrument."
http_method: "GET"
path: "/instruments/:instrument/candles"
response_schema: "ListCandles"
arguments:
- "instrument"
parameters:
Expand All @@ -77,33 +83,23 @@ interfaces:
type: "boolean"
doc: "A flag that controls whether the candlestick is smoothed or not."
default: false
- name: "includeFirst"
- name: "include_first"
type: "boolean"
doc: "A flag that controls whether the candlestick that is covered by the from time should be included in the results."
default: true
- name: "dailyAlignment"
- name: "daily_alignment"
type: "non_neg_integer"
doc: "The hour of the day (in the specified timezone) to use for granularities that have daily alignments, minimum 0, maximum 23."
default: 17
- name: "alignmentTimezone"
- name: "alignment_timezone"
type: "string"
doc: "The timezone to use for the dailyAlignment parameter, note that the returned times will still be represented in UTC."
default: "America/New_York"
- name: "weeklyAlignment"
- name: "weekly_alignment"
type: "string"
doc: "The day of the week used for granularities that have weekly alignment."
default: "Friday"
- function_name: "list_order_book"
description: "Get order book data for an instrument."
http_method: "GET"
path: "/instruments/:instrument/orderBook"
arguments:
- "instrument"
parameters:
- name: "time"
type: "string"
doc: "The time of the snapshot to fetch using either RFC 3339 or Unix format. If not specified, then the most recent snapshot is fetched."
- function_name: "list_position_book"

description: "Get position book data for an instrument."
http_method: "GET"
path: "/instruments/:instrument/positionBook"
Expand All @@ -127,6 +123,7 @@ interfaces:
description: "Get a list of orders for an account."
http_method: "GET"
path: "/accounts/:account_id/orders"
response_schema: "ListOrders"
arguments:
- "account_id"
parameters:
Expand All @@ -143,19 +140,21 @@ interfaces:
type: "non_neg_integer"
doc: "The maximum number of Orders to return."
default: 50
- name: "beforeID"
- name: "before_id"
type: "string"
doc: "The maximum Order ID to return. If not provided the most recent Orders in the Account are returned."
- function_name: "list_pending"
description: "Get a list of pending orders for an account."
http_method: "GET"
path: "/accounts/:account_id/pendingOrders"
response_schema: "ListPendingOrders"
arguments:
- "account_id"
- function_name: "find"
description: "Get details for a single order in an account."
http_method: "GET"
path: "/accounts/:account_id/orders/:order_id"
response_schema: "FindOrder"
arguments:
- "account_id"
- "order_id"
Expand Down Expand Up @@ -189,6 +188,7 @@ interfaces:
description: "Get a list of trades for an account."
http_method: "GET"
path: "/accounts/:account_id/trades"
response_schema: "ListTrades"
arguments:
- "account_id"
parameters:
Expand All @@ -205,19 +205,21 @@ interfaces:
type: "non_neg_integer"
doc: "The maximum number of Trades to return."
default: 50
- name: "beforeID"
- name: "before_id"
type: "string"
doc: "The maximum Trade ID to return. If not provided the most recent Trades in the Account are returned."
- function_name: "list_open"
description: "Get a list of open trades for an account."
http_method: "GET"
path: "/accounts/:account_id/openTrades"
response_schema: "ListTrades"
arguments:
- "account_id"
- function_name: "find"
description: "Get details for a single trade in an account."
http_method: "GET"
path: "/accounts/:account_id/trades/:trade_id"
response_schema: "FindTrade"
arguments:
- "account_id"
- "trade_id"
Expand Down Expand Up @@ -252,18 +254,21 @@ interfaces:
description: "Get a list of positions for an account."
http_method: "GET"
path: "/accounts/:account_id/positions"
response_schema: "ListPositions"
arguments:
- "account_id"
- function_name: "list_open"
description: "Get a list of open positions for an account."
http_method: "GET"
path: "/accounts/:account_id/openPositions"
response_schema: "ListPositions"
arguments:
- "account_id"
- function_name: "find"
description: "Get the details of a single instrument's position in an account."
http_method: "GET"
path: "/accounts/:account_id/positions/:instrument"
response_schema: "ListPositions"
arguments:
- "account_id"
- "instrument"
Expand All @@ -282,6 +287,7 @@ interfaces:
description: "Get a list of transactions for an account."
http_method: "GET"
path: "/accounts/:account_id/transactions"
response_schema: "ListTransactions"
arguments:
- "account_id"
parameters:
Expand All @@ -291,7 +297,7 @@ interfaces:
- name: "to"
type: "string"
doc: "The ending time (inclusive) of the time range for the Transactions being queried. Defaults to current time."
- name: "pageSize"
- name: "page_size"
type: "non_neg_integer"
doc: "The number of Transactions to include in each page. [default=100, maximum=1000]."
default: 100
Expand All @@ -302,13 +308,15 @@ interfaces:
description: "Get the details of a single transaction in an account."
http_method: "GET"
path: "/accounts/:account_id/transactions/:transaction_id"
response_schema: "FindTransaction"
arguments:
- "account_id"
- "transaction_id"
- function_name: "list_id_range"
description: "Get a list of transactions for an account within a specific TransactionID range."
http_method: "GET"
path: "/accounts/:account_id/transactions/idrange"
response_schema: "ListTransactionsIdRange"
arguments:
- "account_id"
parameters:
Expand All @@ -325,6 +333,7 @@ interfaces:
description: "Get a list of transactions for an account since a specific TransactionID."
http_method: "GET"
path: "/accounts/:account_id/transactions/sinceid"
response_schema: "ListTransactionsIdRange"
arguments:
- "account_id"
- "transaction_id"
Expand All @@ -339,10 +348,11 @@ interfaces:
description: "Get most recently completed candles within an account for specified combinations of instrument, granularity and price component."
http_method: "GET"
path: "/accounts/:account_id/candles/latest"
response_schema: "LatestCandles"
arguments:
- "account_id"
parameters:
- name: "candleSpecifications"
- name: "candle_specifications"
type: "string"
doc: "The specification of the candles to fetch."
required: true
Expand All @@ -354,22 +364,23 @@ interfaces:
type: "boolean"
doc: "A flag that controls whether the candlestick is smoothed or not."
default: false
- name: "dailyAlignment"
- name: "daily_alignment"
type: "non_neg_integer"
doc: "The hour of the day (in the specified timezone) to use for granularities that have daily alignments, minimum 0, maximum 23."
default: 17
- name: "alignmentTimezone"
- name: "alignment_timezone"
type: "string"
doc: "The timezone to use for the dailyAlignment parameter, note that the returned times will still be represented in UTC."
default: "America/New_York"
- name: "weeklyAlignment"
- name: "weekly_alignment"
type: "string"
doc: "The day of the week used for granularities that have weekly alignment."
default: "Friday"
- function_name: "list"
description: "Get pricing information for a list of instruments."
http_method: "GET"
path: "/accounts/:account_id/pricing"
response_schema: "ListPricing"
arguments:
- "account_id"
parameters:
Expand All @@ -380,18 +391,19 @@ interfaces:
- name: "since"
type: "string"
doc: "The time of the snapshot to fetch using either RFC 3339 or Unix format. If not specified, then the most recent snapshot is fetched."
- name: "includeUnitsAvailable"
- name: "include_units_available"
type: "boolean"
doc: "Flag that enables the inclusion of the unitsAvailable field in the returned Price objects."
default: false
- name: "includeHomeConversion"
- name: "include_home_conversion"
type: "boolean"
doc: "Flag that enables the inclusion of the homeConversions field in the returned response."
default: false
- function_name: "list_candles"
description: "Fetch candlestick data for an instrument."
http_method: "GET"
path: "/accounts/:account_id/instruments/:instrument/candles"
response_schema: "ListCandles"
arguments:
- "account_id"
- "instrument"
Expand All @@ -418,35 +430,23 @@ interfaces:
type: "boolean"
doc: "A flag that controls whether the candlestick is smoothed or not."
default: false
- name: "includeFirst"
- name: "include_first"
type: "boolean"
doc: "A flag that controls whether the candlestick that is covered by the from time should be included in the results."
default: true
- name: "dailyAlignment"
- name: "daily_alignment"
type: "non_neg_integer"
doc: "The hour of the day (in the specified timezone) to use for granularities that have daily alignments, minimum 0, maximum 23."
default: 17
- name: "alignmentTimezone"
- name: "alignment_timezone"
type: "string"
doc: "The timezone to use for the dailyAlignment parameter, note that the returned times will still be represented in UTC."
default: "America/New_York"
- name: "weeklyAlignment"
- name: "weekly_alignment"
type: "string"
doc: "The day of the week used for granularities that have weekly alignment."
default: "Friday"
- name: "units"
type: "string"
doc: "The number of units used to calculate the volume-weighted average bid and ask prices."
default: 1


# schemas:
# - module_name: "Account"
# description: "Schema for Oanda account"
# properties:
# - name: "id"
# type: "string"
# description: "The account id"
# - name: "name"
# type: "string"
# description: "The account name"
default: 1
39 changes: 31 additions & 8 deletions lib/code_gen/code_generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,11 @@ defmodule ExOanda.CodeGenerator do
end

defp generate_function(config) do
%{function_name: name, description: desc, http_method: method, path: path, arguments: args, parameters: parameters} = config
%{function_name: name, description: desc, http_method: method, path: path, arguments: args, parameters: parameters, response_schema: response_schema} = config
formatted_args = format_args(args)
formatted_params = format_params(parameters)
arg_types = generate_arg_types(args)
model = generate_module_name(response_schema)

quote do
@doc"""
Expand Down Expand Up @@ -130,11 +131,11 @@ defmodule ExOanda.CodeGenerator do
path_params: path_params,
method: unquote(method),
headers: API.base_headers(),
params: params
params: ExOanda.CodeGenerator.convert_params(params)
)
|> API.maybe_attach_telemetry(conn)
|> Req.request(conn.options)
|> API.handle_response()
|> API.handle_response(unquote(model))

{:error, reason} ->
{:error, reason}
Expand Down Expand Up @@ -169,6 +170,24 @@ defmodule ExOanda.CodeGenerator do
|> String.to_atom()
end

@doc false
def convert_params(params) do
params
|> Enum.into(%{})
|> Recase.Enumerable.convert_keys(&Recase.to_camel/1)
|> Enum.map(fn {k, v} ->
k = maybe_convert_to_string(k)

case String.ends_with?(k, "Id") do
true -> {String.replace(k, "Id", "ID"), v}
false -> {k, v}
end
end)
end

def maybe_convert_to_string(val) when is_atom(val), do: Atom.to_string(val)
def maybe_convert_to_string(val), do: val

defp generate_module_name(module_name), do: Module.concat([ExOanda, module_name])

defp format_args(args) do
Expand All @@ -177,11 +196,15 @@ defmodule ExOanda.CodeGenerator do

defp format_params(params) do
Enum.reduce(params, [], fn %{name: name, type: type, required: required, default: default, doc: doc}, acc ->
acc
|> Keyword.put(
String.to_atom(name),
[type: String.to_atom(type), required: required, default: default, doc: doc]
)
params_list = [
type: String.to_atom(type),
required: required,
default: default,
doc: doc
]

filtered_params = Enum.reject(params_list, fn {_, value} -> is_nil(value) end)
Keyword.put(acc, String.to_atom(name), filtered_params)
end)
end

Expand Down
Loading

0 comments on commit 867e10a

Please sign in to comment.