diff --git a/lib/xtb_client/connection.ex b/lib/xtb_client/connection.ex index 6961a7e..0c27bb6 100644 --- a/lib/xtb_client/connection.ex +++ b/lib/xtb_client/connection.ex @@ -62,11 +62,13 @@ defmodule XtbClient.Connection do alias XtbClient.{MainSocket, StreamingSocket, StreamingMessage} alias XtbClient.Messages.{ + Candle, Candles, ChartLast, ChartRange, DateRange, ProfitCalculation, + RateInfos, Quotations, SymbolInfo, SymbolVolume, @@ -509,7 +511,7 @@ defmodule XtbClient.Connection do ref_string = inspect(ref) MainSocket.query(mpid, self(), ref_string, method) - clients = Map.put(clients, ref_string, from) + clients = Map.put(clients, ref_string, {from, method, nil}) state = %State{state | clients: clients} {:noreply, state} @@ -524,17 +526,32 @@ defmodule XtbClient.Connection do ref_string = inspect(ref) MainSocket.query(mpid, self(), ref_string, method, params) - clients = Map.put(clients, ref_string, from) + clients = Map.put(clients, ref_string, {from, method, params}) state = %State{state | clients: clients} {:noreply, state} end @impl true - def handle_cast({:response, ref, resp} = _message, %State{clients: clients} = state) do - {client, clients} = Map.pop!(clients, ref) - GenServer.reply(client, resp) - state = %State{state | clients: clients} + def handle_cast( + {:response, ref, %RateInfos{data: data} = resp} = _message, + %State{clients: clients} = state + ) do + {_client, _method, %{info: %ChartRange.Query{symbol: symbol}}} = Map.get(clients, ref) + + resp = %RateInfos{ + resp + | data: Enum.map(data, &%Candle{&1 | symbol: symbol}) + } + + state = handle_query_response(ref, resp, state) + + {:noreply, state} + end + + @impl true + def handle_cast({:response, ref, resp} = _message, %State{} = state) do + state = handle_query_response(ref, resp, state) {:noreply, state} end @@ -581,6 +598,13 @@ defmodule XtbClient.Connection do {:noreply, state} end + defp handle_query_response(ref, response, %State{clients: clients} = state) do + {{client, _method, _params}, clients} = Map.pop!(clients, ref) + GenServer.reply(client, response) + + %State{state | clients: clients} + end + @impl true def handle_info({:EXIT, pid, reason}, state) do Logger.error( diff --git a/lib/xtb_client/messages/candle.ex b/lib/xtb_client/messages/candle.ex index b913aa7..a6d84dc 100644 --- a/lib/xtb_client/messages/candle.ex +++ b/lib/xtb_client/messages/candle.ex @@ -56,19 +56,26 @@ defmodule XtbClient.Messages.Candle do %{ "vol" => vol, "ctm" => ctm_value, - "ctmString" => ctm_string, - "symbol" => symbol + "ctmString" => ctm_string } = args ) when is_number(vol) and is_number(ctm_value) do - value = args |> Map.drop(["vol", "ctm", "ctmString", "symbol"]) |> new() + value = args |> Map.drop(["vol", "ctm", "ctmString"]) |> new() %{ value | vol: vol, ctm: DateTime.from_unix!(ctm_value, :millisecond), - ctm_string: ctm_string || "", - symbol: symbol || "" + ctm_string: ctm_string || "" + } + end + + def new(%{"symbol" => symbol} = args) do + value = args |> Map.drop(["symbol"]) |> new() + + %{ + value + | symbol: symbol || "" } end @@ -107,22 +114,19 @@ defmodule XtbClient.Messages.Candle do "high" => high, "low" => low, "close" => close - }, + } = args, digits ) when is_number(open) and is_number(high) and is_number(low) and is_number(close) and is_number(digits) do - %__MODULE__{ - open: to_base_currency(open, digits), - high: to_base_currency(open + high, digits), - low: to_base_currency(open + low, digits), - close: to_base_currency(open + close, digits), - vol: 0.0, - ctm: nil, - ctm_string: nil, - quote_id: nil, - symbol: nil - } + args + |> Map.merge(%{ + "open" => to_base_currency(open, digits), + "high" => to_base_currency(open + high, digits), + "low" => to_base_currency(open + low, digits), + "close" => to_base_currency(open + close, digits) + }) + |> new() end defp to_base_currency(value, digits) do diff --git a/test/xtb_client/connection_test.exs b/test/xtb_client/connection_test.exs index cb1e085..e6196bd 100644 --- a/test/xtb_client/connection_test.exs +++ b/test/xtb_client/connection_test.exs @@ -115,11 +115,13 @@ defmodule XtbClient.ConnectionTest do end test "get chart range", %{pid: pid} do + now = DateTime.utc_now() + args = %{ range: DateRange.new(%{ - from: DateTime.utc_now() |> DateTime.add(-2 * 30 * 24 * 60 * 60), - to: DateTime.utc_now() + from: DateTime.add(now, -2 * 30 * 24 * 60 * 60), + to: now }), period: :h1, symbol: "EURPLN" @@ -131,7 +133,28 @@ defmodule XtbClient.ConnectionTest do assert %RateInfos{} = result assert is_number(result.digits) assert [elem | _] = result.data - assert %Candle{} = elem + + assert %Candle{ + symbol: symbol, + open: open, + high: high, + low: low, + close: close, + vol: vol, + ctm: ctm, + ctm_string: ctm_string, + quote_id: quote_id + } = elem + + assert "EURPLN" == symbol + assert is_number(open) + assert is_number(high) + assert is_number(low) + assert is_number(close) + assert is_number(vol) + assert DateTime.before?(ctm, now) + assert is_binary(ctm_string) + refute quote_id end test "get commission definition", %{pid: pid} do