Skip to content

Commit 871972f

Browse files
committed
switch to TestItemRunner
1 parent ce475c0 commit 871972f

7 files changed

Lines changed: 172 additions & 276 deletions

File tree

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "Fastback"
22
uuid = "2b92286b-cbc8-46f1-be48-a629b4baefca"
33
authors = ["Rino Beeli <40661605+rbeeli@users.noreply.github.com>"]
44
repo = "https://github.com/rbeeli/fastback.jl.git"
5-
version = "0.2.0"
5+
version = "0.3.0"
66

77
[deps]
88
Crayons = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
@@ -19,6 +19,7 @@ PrettyTables = "3"
1919

2020
[extras]
2121
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
22+
TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"
2223

2324
[targets]
24-
test = ["Test"]
25+
test = ["Test", "TestItemRunner"]

test/account.jl

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,158 +1,127 @@
1-
using Fastback
2-
using Test
31
using Dates
2+
using TestItemRunner
43

5-
@testset "Account long order w/o commission" begin
4+
@testitem "Account long order w/o commission" begin
5+
using Test, Fastback, Dates
66
# create trading account
77
acc = Account()
88
add_cash!(acc, Cash(:USD), 100_000.0)
99

1010
@test cash(acc, :USD) == 100_000.0
1111
@test equity(acc, :USD) == 100_000.0
1212
@test length(acc.cash) == 1
13-
1413
# create instrument
1514
DUMMY = register_instrument!(acc, Instrument(Symbol("DUMMY/USD"), :DUMMY, :USD))
16-
1715
pos = get_position(acc, DUMMY)
18-
1916
# generate data
2017
dates = collect(DateTime(2018, 1, 2):Day(1):DateTime(2018, 1, 4))
2118
prices = [100.0, 100.5, 102.5]
22-
2319
# buy order
2420
qty = 100.0
2521
order = Order(oid!(acc), DUMMY, dates[1], prices[1], qty)
2622
exe1 = fill_order!(acc, order, dates[1], prices[1])
27-
2823
@test exe1 == acc.trades[end]
2924
@test exe1.commission == 0.0
3025
@test nominal_value(exe1) == qty * prices[1]
3126
@test exe1.realized_pnl == 0.0
3227
# @test realized_return(exe1) == 0.0
3328
@test pos.avg_price == 100.0
34-
3529
# update position and account P&L
3630
update_pnl!(acc, pos, prices[2])
37-
3831
@test pos.pnl_local (prices[2] - prices[1]) * pos.quantity
3932
@test cash(acc, :USD) 100_000.0
4033
@test equity(acc, :USD) 100_000.0 + (prices[2] - prices[1]) * pos.quantity
41-
4234
# close position
4335
order = Order(oid!(acc), DUMMY, dates[3], prices[3], -pos.quantity)
4436
fill_order!(acc, order, dates[3], prices[3])
45-
4637
# update position and account P&L
4738
update_pnl!(acc, pos, prices[3])
48-
4939
@test pos.pnl_local 0
5040
@test cash(acc, :USD) 100_000.0 + (prices[3] - prices[1]) * qty
5141
@test equity(acc, :USD) cash(acc, :USD)
52-
5342
show(acc)
5443
end
5544

56-
@testset "Account long order w/ commission ccy" begin
45+
@testitem "Account long order w/ commission ccy" begin
46+
using Test, Fastback, Dates
5747
# create trading account
5848
acc = Account()
5949
add_cash!(acc, Cash(:USD), 100_000.0)
6050

6151
@test cash(acc, :USD) == 100_000.0
6252
@test equity(acc, :USD) == 100_000.0
6353
@test length(acc.cash) == 1
64-
6554
# create instrument
6655
DUMMY = register_instrument!(acc, Instrument(Symbol("DUMMY/USD"), :DUMMY, :USD))
67-
6856
pos = get_position(acc, DUMMY)
69-
7057
# generate data
7158
dates = collect(DateTime(2018, 1, 2):Day(1):DateTime(2018, 1, 4))
7259
prices = [100.0, 100.5, 102.5]
73-
7460
# buy order
7561
qty = 100.0
7662
order = Order(oid!(acc), DUMMY, dates[1], prices[1], qty)
7763
commission = 1.0
7864
exe1 = fill_order!(acc, order, dates[1], prices[1]; commission=commission)
79-
8065
@test exe1 == acc.trades[end]
8166
@test nominal_value(exe1) == qty * prices[1]
8267
@test exe1.commission == commission
8368
@test exe1.realized_pnl == -commission
8469
# @test realized_return(exe1) == 0.0
8570
@test pos.avg_price == 100.0
86-
8771
# update position and account P&L
8872
update_pnl!(acc, pos, prices[2])
8973

9074
@test pos.pnl_local (prices[2] - prices[1]) * pos.quantity # does not include commission!
9175
@test cash(acc, :USD) 100_000.0 - commission
9276
@test equity(acc, :USD) 100_000.0+ (prices[2] - prices[1]) * pos.quantity - commission
93-
9477
# close position
9578
order = Order(oid!(acc), DUMMY, dates[3], prices[3], -pos.quantity)
9679
exe2 = fill_order!(acc, order, dates[3], prices[3]; commission=0.5)
97-
9880
# update position and account P&L
9981
update_pnl!(acc, pos, prices[3])
100-
10182
@test pos.pnl_local 0
10283
@test cash(acc, :USD) 100_000.0 + (prices[3] - prices[1]) * qty - commission - 0.5
10384
@test equity(acc, :USD) cash(acc, :USD)
104-
10585
show(acc)
10686
end
10787

108-
@testset "Account long order w/ commission pct" begin
88+
@testitem "Account long order w/ commission pct" begin
89+
using Test, Fastback, Dates
10990
# create trading account
110-
acc = Account()
111-
add_cash!(acc, Cash(:USD), 100_000.0)
112-
91+
acc = Account(); add_cash!(acc, Cash(:USD), 100_000.0)
11392
@test cash(acc, :USD) == 100_000.0
11493
@test equity(acc, :USD) == 100_000.0
11594
@test length(acc.cash) == 1
116-
11795
# create instrument
11896
DUMMY = register_instrument!(acc, Instrument(Symbol("DUMMY/USD"), :DUMMY, :USD))
119-
12097
pos = get_position(acc, DUMMY)
121-
12298
# generate data
12399
dates = collect(DateTime(2018, 1, 2):Day(1):DateTime(2018, 1, 4))
124100
prices = [100.0, 100.5, 102.5]
125-
126101
# buy order
127102
qty = 100.0
128103
order = Order(oid!(acc), DUMMY, dates[1], prices[1], qty)
129104
commission_pct1 = 0.001
130105
exe1 = fill_order!(acc, order, dates[1], prices[1]; commission_pct=commission_pct1)
131-
132106
@test nominal_value(exe1) == qty * prices[1]
133107
@test exe1.commission == commission_pct1*nominal_value(exe1)
134108
@test acc.trades[end].realized_pnl == -commission_pct1*nominal_value(exe1)
135109
# @test realized_return(acc.trades[end]) == 0.0
136110
@test pos.avg_price == 100.0
137-
138111
# update position and account P&L
139112
update_pnl!(acc, pos, prices[2])
140113

141114
@test pos.pnl_local (prices[2] - prices[1]) * pos.quantity # does not include commission!
142115
@test cash(acc, :USD) 100_000.0 - exe1.commission
143116
@test equity(acc, :USD) 100_000.0+ (prices[2] - prices[1]) * pos.quantity - exe1.commission
144-
145117
# close position
146118
order = Order(oid!(acc), DUMMY, dates[3], prices[3], -pos.quantity)
147119
exe2 = fill_order!(acc, order, dates[3], prices[3]; commission_pct=0.0005)
148-
149120
# update position and account P&L
150121
update_pnl!(acc, pos, prices[3])
151-
152122
@test pos.pnl_local 0
153123
@test cash(acc, :USD) 100_000.0 + (prices[3] - prices[1]) * qty - exe1.commission - exe2.commission
154124
@test equity(acc, :USD) cash(acc, :USD)
155-
156125
show(acc)
157126
end
158127

test/collectors.jl

Lines changed: 68 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,97 @@
1-
using Fastback
2-
using Test
31
using Dates
2+
using TestItemRunner
43

5-
@testset "periodic_collector" begin
4+
@testitem "periodic_collector" begin
5+
using Test, Fastback, Dates
66
# every 500 ms from 1 sec to 5 sec
77
dts = map(x -> DateTime(2000, 1, 1) + Millisecond(x), 1000:500:5000)
88
data = [100.0, 110.0, 99.0, 102.0, 105.0, 105.0, 105.0, 120.0, 110.0]
9-
10-
begin
11-
# periodic_collector
12-
f, collected = periodic_collector(Float64, Second(1))
13-
14-
for i in eachindex(dts)
15-
should_collect(collected, dts[i]) && f(dts[i], data[i])
16-
end
17-
18-
@test length(values(collected)) == 5
19-
@test all(dates(collected) .== map(x -> DateTime(2000, 1, 1) + Second(x), 1:5))
20-
@test collected.last_dt == dts[end]
9+
# periodic_collector
10+
f, collected = periodic_collector(Float64, Second(1))
11+
for i in eachindex(dts)
12+
should_collect(collected, dts[i]) && f(dts[i], data[i])
2113
end
14+
@test length(values(collected)) == 5
15+
@test all(dates(collected) .== map(x -> DateTime(2000, 1, 1) + Second(x), 1:5))
16+
@test collected.last_dt == dts[end]
2217
end
2318

24-
25-
@testset "predicate_collector" begin
19+
@testitem "predicate_collector" begin
20+
using Test, Fastback, Dates
2621
# every 500 ms from 1 sec to 5 sec
2722
dts = map(x -> DateTime(2000, 1, 1) + Millisecond(x), 1000:500:5000)
2823
data = [100.0, 110.0, 99.0, 102.0, 105.0, 105.0, 105.0, 120.0, 110.0]
29-
30-
begin
31-
# predicate_collector
32-
predicate = (collected, dt) -> (dt - collected.last_dt) >= Second(1)
33-
f, collected = predicate_collector(Float64, predicate, 0.0)
34-
35-
for i in eachindex(dts)
36-
should_collect(collected, dts[i]) && f(dts[i], data[i])
37-
end
38-
39-
@test length(dates(collected)) == 5
40-
@test all(dates(collected) .== map(x -> DateTime(2000, 1, 1) + Second(x), 1:5))
41-
@test collected.last_dt == dts[end]
24+
# predicate_collector
25+
predicate = (collected, dt) -> (dt - collected.last_dt) >= Second(1)
26+
f, collected = predicate_collector(Float64, predicate, 0.0)
27+
for i in eachindex(dts)
28+
should_collect(collected, dts[i]) && f(dts[i], data[i])
4229
end
30+
@test length(dates(collected)) == 5
31+
@test all(dates(collected) .== map(x -> DateTime(2000, 1, 1) + Second(x), 1:5))
32+
@test collected.last_dt == dts[end]
4333
end
4434

45-
46-
@testset "min/max_value_collector" begin
35+
@testitem "min_value_collector" begin
36+
using Test, Fastback, Dates
4737
# every 500 ms from 1 sec to 5 sec
4838
dts = map(x -> DateTime(2000, 1, 1) + Millisecond(x), 1000:500:5000)
4939
data = [100.0, 110.0, 99.0, 102.0, 105.0, 105.0, 105.0, 120.0, 110.0]
50-
51-
begin
52-
# min_value_collector
53-
f, collected = min_value_collector(Float64)
54-
55-
for i in eachindex(dts)
56-
f(dts[i], data[i])
57-
end
58-
59-
@test collected.min_value == minimum(data)
60-
@test collected.dt == dts[indexin(minimum(data), data)][1]
40+
# min_value_collector
41+
f, collected = min_value_collector(Float64)
42+
for i in eachindex(dts)
43+
f(dts[i], data[i])
6144
end
45+
@test collected.min_value == minimum(data)
46+
@test collected.dt == dts[indexin(minimum(data), data)][1]
47+
end
6248

63-
begin
64-
# max_value_collector
65-
f, collected = max_value_collector(Float64)
66-
67-
for i in eachindex(dts)
68-
f(dts[i], data[i])
69-
end
70-
71-
@test collected.max_value == maximum(data)
72-
@test collected.dt == dts[indexin(maximum(data), data)][1]
49+
@testitem "max_value_collector" begin
50+
using Test, Fastback, Dates
51+
# every 500 ms from 1 sec to 5 sec
52+
dts = map(x -> DateTime(2000, 1, 1) + Millisecond(x), 1000:500:5000)
53+
data = [100.0, 110.0, 99.0, 102.0, 105.0, 105.0, 105.0, 120.0, 110.0]
54+
# max_value_collector
55+
f, collected = max_value_collector(Float64)
56+
for i in eachindex(dts)
57+
f(dts[i], data[i])
7358
end
59+
@test collected.max_value == maximum(data)
60+
@test collected.dt == dts[indexin(maximum(data), data)][1]
7461
end
7562

76-
@testset "drawdown_collector" begin
63+
@testitem "drawdown_collector_pnl" begin
64+
using Test, Fastback, Dates
7765
# every 500 ms from 1 sec to 5 sec
7866
dts = map(x -> DateTime(2000, 1, 1) + Millisecond(x), 1000:500:5000)
7967
data = [100.0, 110.0, 99.0, 102.0, 105.0, 105.0, 105.0, 120.0, 110.0]
80-
81-
begin
82-
# drawdown_collector (P&L)
83-
p = (v, dt, equity) -> dt - v.last_dt >= Second(1)
84-
f, collected = drawdown_collector(DrawdownMode.PnL, p)
85-
86-
for i in eachindex(dts)
87-
f(dts[i], data[i])
88-
end
89-
90-
@test length(dates(collected)) == 5
91-
@test length(values(collected)) == 5
92-
@test all(dates(collected) .== map(x -> DateTime(2000, 1, 1) + Second(x), 1:5))
93-
@test collected.last_dt == dts[end]
94-
@test all(values(collected) .== [0.0, -11, -5, -5, -10])
68+
# drawdown_collector (P&L)
69+
p = (v, dt, equity) -> dt - v.last_dt >= Second(1)
70+
f, collected = drawdown_collector(DrawdownMode.PnL, p)
71+
for i in eachindex(dts)
72+
f(dts[i], data[i])
9573
end
74+
@test length(dates(collected)) == 5
75+
@test length(values(collected)) == 5
76+
@test all(dates(collected) .== map(x -> DateTime(2000, 1, 1) + Second(x), 1:5))
77+
@test collected.last_dt == dts[end]
78+
@test all(values(collected) .== [0.0, -11, -5, -5, -10])
79+
end
9680

97-
begin
98-
# drawdown_collector (%)
99-
p = (dv, dt, equity) -> dt - dv.last_dt >= Second(1)
100-
f, collected = drawdown_collector(DrawdownMode.Percentage, p)
101-
102-
for i in eachindex(dts)
103-
f(dts[i], data[i])
104-
end
105-
106-
@test length(dates(collected)) == 5
107-
@test length(values(collected)) == 5
108-
@test all(dates(collected) .== map(x -> DateTime(2000, 1, 1) + Second(x), 1:5))
109-
@test collected.last_dt == dts[end]
110-
@test all(values(collected) .≈ [0.0, -11 / 110, -5 / 110, -5 / 110, -10 / 120])
81+
@testitem "drawdown_collector_pct" begin
82+
using Test, Fastback, Dates
83+
# every 500 ms from 1 sec to 5 sec
84+
dts = map(x -> DateTime(2000, 1, 1) + Millisecond(x), 1000:500:5000)
85+
data = [100.0, 110.0, 99.0, 102.0, 105.0, 105.0, 105.0, 120.0, 110.0]
86+
# drawdown_collector (%)
87+
p = (dv, dt, equity) -> dt - dv.last_dt >= Second(1)
88+
f, collected = drawdown_collector(DrawdownMode.Percentage, p)
89+
for i in eachindex(dts)
90+
f(dts[i], data[i])
11191
end
92+
@test length(dates(collected)) == 5
93+
@test length(values(collected)) == 5
94+
@test all(dates(collected) .== map(x -> DateTime(2000, 1, 1) + Second(x), 1:5))
95+
@test collected.last_dt == dts[end]
96+
@test all(values(collected) .≈ [0.0, -11 / 110, -5 / 110, -5 / 110, -10 / 120])
11297
end

0 commit comments

Comments
 (0)