Skip to content

Commit cba5340

Browse files
authored
chapter 21 finished (#24)
* test are working * sync with franton code
1 parent f9240b8 commit cba5340

12 files changed

Lines changed: 108 additions & 127 deletions

File tree

apps/indicator/lib/indicator/ohlc.ex

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ defmodule Indicator.Ohlc do
22
require Logger
33
alias Core.Struct.TradeEvent
44

5-
@pubsub_client Application.compile_env(:core, :pubsub_client)
65
@enforce_keys [:symbol, :start_time, :duration]
76
defstruct [:symbol, :start_time, :duration, :open, :high, :low, :close]
87

@@ -71,7 +70,7 @@ defmodule Indicator.Ohlc do
7170
defp maybe_broadcast(%__MODULE__{} = ohlc) do
7271
Logger.debug("Broadcasting OHLC: #{inspect(ohlc)}")
7372

74-
@pubsub_client.broadcast(
73+
Phoenix.PubSub.broadcast(
7574
Core.PubSub,
7675
"OHLC:#{ohlc.symbol}",
7776
ohlc

apps/indicator/lib/indicator/ohlc/worker.ex

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,15 @@ defmodule Indicator.Ohlc.Worker do
33
require Logger
44
alias Core.Struct.TradeEvent
55

6-
@logger Application.compile_env(:core, :logger)
7-
@pubsub_client Application.compile_env(:core, :pubsub_client)
8-
96
def start_link(symbol) do
107
GenServer.start_link(__MODULE__, symbol)
118
end
129

1310
def init(symbol) do
1411
symbol = String.upcase(symbol)
15-
@logger.debug("Initializing a new OHLC worker for #{symbol}")
12+
Logger.info("Initializing a new OHLC worker for #{symbol}")
1613

17-
@pubsub_client.subscribe(
14+
Phoenix.PubSub.subscribe(
1815
Core.PubSub,
1916
"TRADE_EVENTS:#{symbol}"
2017
)

apps/naive/lib/naive/strategy.ex

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@ defmodule Naive.Strategy do
33
Module in charge of making and executing decisions
44
"""
55
alias Core.Struct.TradeEvent
6+
alias Naive.Repo
67
alias Naive.Schema.Settings
78

89
require Logger
910

1011
@binance_client Application.compile_env(:naive, :binance_client)
11-
@logger Application.compile_env(:core, :logger)
12-
@pubsub_client Application.compile_env(:core, :pubsub_client)
13-
@repo Application.compile_env(:naive, :repo)
1412

1513
defmodule Position do
1614
@enforce_keys [
@@ -255,7 +253,7 @@ defmodule Naive.Strategy do
255253
} = position,
256254
_settings
257255
) do
258-
@logger.info(
256+
Logger.info(
259257
"Position (#{symbol}/#{id}): " <>
260258
"Placing a BUY order @ #{price}, quantity: #{quantity}"
261259
)
@@ -279,7 +277,7 @@ defmodule Naive.Strategy do
279277
} = position,
280278
_settings
281279
) do
282-
@logger.info(
280+
Logger.info(
283281
"Position (#{symbol}/#{id}): The BUY order is now filled. " <>
284282
"Placing a SELL order @ #{sell_price}, quantity: #{quantity}"
285283
)
@@ -305,7 +303,7 @@ defmodule Naive.Strategy do
305303
} = position,
306304
_settings
307305
) do
308-
@logger.info("Position (#{symbol}/#{id}): The BUY order is now partially filled")
306+
Logger.info("Position (#{symbol}/#{id}): The BUY order is now partially filled")
309307

310308
{:ok, %Binance.Order{} = current_buy_order} =
311309
@binance_client.get_order(symbol, timestamp, order_id)
@@ -324,7 +322,7 @@ defmodule Naive.Strategy do
324322
settings
325323
) do
326324
new_position = generate_fresh_position(settings)
327-
@logger.info("Position (#{symbol}/#{id}): Trade cycle finished")
325+
Logger.info("Position (#{symbol}/#{id}): Trade cycle finished")
328326
{:ok, new_position}
329327
end
330328

@@ -341,7 +339,7 @@ defmodule Naive.Strategy do
341339
} = position,
342340
_settings
343341
) do
344-
@logger.info("Position (#{symbol}/#{id}): The SELL order is now partially filled")
342+
Logger.info("Position (#{symbol}/#{id}): The SELL order is now partially filled")
345343

346344
{:ok, %Binance.Order{} = current_sell_order} =
347345
@binance_client.get_order(symbol, timestamp, order_id)
@@ -360,7 +358,7 @@ defmodule Naive.Strategy do
360358
settings
361359
) do
362360
new_position = generate_fresh_position(settings)
363-
@logger.info("Position (#{symbol}/#{id}): Rebuy triggered. Starting a new position")
361+
Logger.info("Position (#{symbol}/#{id}): Rebuy triggered. Starting a new position")
364362
{:ok, new_position}
365363
end
366364

@@ -375,7 +373,7 @@ defmodule Naive.Strategy do
375373
end
376374

377375
defp broadcast_order(%Binance.Order{} = order) do
378-
@pubsub_client.broadcast(Core.PubSub, "ORDERS:#{order.symbol}", order)
376+
Phoenix.PubSub.broadcast(Core.PubSub, "ORDERS:#{order.symbol}", order)
379377
end
380378

381379
defp convert_to_order(%Binance.OrderResponse{} = response) do
@@ -395,7 +393,7 @@ defmodule Naive.Strategy do
395393
exchange_info =
396394
@binance_client.get_exchange_info()
397395

398-
db_settings = @repo.get_by!(Settings, symbol: symbol)
396+
db_settings = Repo.get_by!(Settings, symbol: symbol)
399397

400398
merge_filters_into_settings(exchange_info, db_settings, symbol)
401399
end
@@ -437,8 +435,8 @@ defmodule Naive.Strategy do
437435
end
438436

439437
def update_status(symbol, status) when is_binary(symbol) and is_binary(status) do
440-
@repo.get_by(Settings, symbol: symbol)
438+
Repo.get_by(Settings, symbol: symbol)
441439
|> Ecto.Changeset.change(%{status: status})
442-
|> @repo.update()
440+
|> Repo.update()
443441
end
444442
end

apps/naive/lib/naive/trader.ex

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ defmodule Naive.Trader do
1010

1111
require Logger
1212

13-
@logger Application.compile_env(:core, :logger)
14-
@pubsub_client Application.compile_env(:core, :pubsub_client)
1513
@registry :naive_traders
1614
defmodule State do
1715
@moduledoc """
@@ -27,9 +25,9 @@ defmodule Naive.Trader do
2725
end
2826

2927
def init(symbol) do
30-
@logger.info("Initializing new trader for #{symbol}")
28+
Logger.info("Initializing new trader for #{symbol}")
3129

32-
@pubsub_client.subscribe(Core.PubSub, "TRADE_EVENTS:#{symbol}")
30+
Phoenix.PubSub.subscribe(Core.PubSub, "TRADE_EVENTS:#{symbol}")
3331

3432
{:ok, nil, {:continue, {:start_position, symbol}}}
3533
end

apps/naive/mix.exs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ defmodule Naive.MixProject do
1515
elixirc_options: [
1616
warnings_as_errors: true
1717
],
18-
aliases: aliases(),
19-
elixirc_paths: elixirc_paths(Mix.env())
18+
aliases: aliases()
2019
]
2120
end
2221

@@ -44,13 +43,10 @@ defmodule Naive.MixProject do
4443
{:decimal, "~> 2.0"},
4544
{:ecto_sql, "~> 3.0"},
4645
{:ecto_enum, "~> 1.4"},
46+
{:mimic, "~> 1.7", only: [:test, :integration]},
4747
{:phoenix_pubsub, "~> 2.0"},
4848
{:postgrex, ">= 0.0.0"},
49-
{:sobelow, "~> 0.13", only: [:dev, :test], runtime: false},
50-
{:mox, "~> 1.0", only: [:test, :integration]}
49+
{:sobelow, "~> 0.13", only: [:dev, :test], runtime: false}
5150
]
5251
end
53-
54-
defp elixirc_paths(:test), do: ["test/support", "lib"]
55-
defp elixirc_paths(_), do: ["lib"]
5652
end
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
defmodule Naive.StrategyTest do
2+
use ExUnit.Case, async: true
3+
use Mimic
4+
5+
alias Core.Struct.TradeEvent
6+
alias Naive.Strategy
7+
import ExUnit.CaptureLog
8+
9+
@tag :unit
10+
test "Strategy places a buy order" do
11+
expected_order = %Binance.OrderResponse{
12+
client_order_id: "1",
13+
executed_qty: "0.000",
14+
order_id: "x1",
15+
orig_qty: "50.000",
16+
price: "0.800000",
17+
side: "BUY",
18+
status: "NEW",
19+
symbol: "ABC"
20+
}
21+
22+
BinanceMock
23+
|> stub(
24+
:order_limit_buy,
25+
fn "ABC", "50.000", "0.800000", "GTC" -> {:ok, expected_order} end
26+
)
27+
28+
Phoenix.PubSub
29+
|> stub(
30+
:broadcast,
31+
fn _pubsub, _topic, _message -> :ok end
32+
)
33+
34+
settings = %{
35+
symbol: "ABC",
36+
chunks: "5",
37+
budget: "200",
38+
buy_down_interval: "0.2",
39+
profit_interval: "0.1",
40+
rebuy_interval: "0.5",
41+
tick_size: "0.000001",
42+
step_size: "0.001",
43+
status: :on
44+
}
45+
46+
{{:ok, new_positions}, log} =
47+
with_log(fn ->
48+
Naive.Strategy.execute(
49+
%TradeEvent{
50+
price: "1.00000"
51+
},
52+
[
53+
Strategy.generate_fresh_position(settings)
54+
],
55+
settings
56+
)
57+
end)
58+
59+
assert log =~ "0.8"
60+
61+
assert length(new_positions) == 1
62+
63+
%{buy_order: buy_order} = List.first(new_positions)
64+
assert buy_order == expected_order
65+
end
66+
end

apps/naive/test/naive/trader_test.exs

Lines changed: 0 additions & 73 deletions
This file was deleted.

apps/naive/test/test_helper.exs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
ExUnit.start()
1+
Application.ensure_all_started(:mimic)
22

3-
Application.ensure_all_started(:mox)
4-
# here I differed a little bit from the book cause in has
5-
# warning_as_errors turned on and i needed compile time checks
6-
# Mox.defmock(Test.BinanceMock, for: BinanceMock)
7-
# Mox.defmock(Test.Naive.LeaderMock, for: Naive.Leader)
8-
# Mox.defmock(Test.LoggerMock, for: Core.Test.Logger)
9-
# Mox.defmock(Test.PubSubMock, for: Core.Test.PubSub)
3+
Mimic.copy(BinanceMock)
4+
Mimic.copy(Phoenix.PubSub)
5+
6+
ExUnit.start(capture_log: true)

config/config.exs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ import Config
33
config :binance_mock,
44
use_cached_exchange_info: false
55

6-
config :core,
7-
logger: Logger,
8-
pubsub_client: Phoenix.PubSub
9-
106
config :data_warehouse,
117
ecto_repos: [DataWarehouse.Repo]
128

@@ -29,8 +25,6 @@ config :streamer, Streamer.Repo,
2925
config :naive,
3026
binance_client: BinanceMock,
3127
ecto_repos: [Naive.Repo],
32-
leader: Naive.Leader,
33-
repo: Naive.Repo,
3428
trading: %{
3529
defaults: %{
3630
chunks: 5,

config/test.exs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1 @@
11
import Config
2-
3-
config :core,
4-
logger: Test.LoggerMock,
5-
pubsub_client: Test.PubSubMock
6-
7-
config :naive,
8-
binance_client: Test.BinanceMock,
9-
leader: Test.Naive.LeaderMock,
10-
repo: Test.Naive.RepoMock

0 commit comments

Comments
 (0)