-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patherlyfix_test09.erl
100 lines (93 loc) · 3.51 KB
/
erlyfix_test09.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
-module(erlyfix_test09).
-include_lib("eunit/include/eunit.hrl").
-include("erlyfix.hrl").
-include("debug.hrl").
-record(quote, {
price,
volume,
source
}).
-record(tick, {
symbol,
bid,
ask
}).
load() ->
{ok, P} = erlyfix_protocol:load("test/FIX44.xml"),
P.
sample_test() ->
P = load(),
{ok, IoList} = erlyfix_protocol:serialize(P, 'MarketDataSnapshotFullRefresh', [
{'SenderCompID', <<"me">>},
{'TargetCompID', <<"you">>},
{'MsgSeqNum', 1},
{'SendingTime', <<"20171109-16:19:07.541">>},
{'Instrument', [{'Symbol', <<"EURCHF">>}] },
{'MDReqID', <<"31955:1510225047.01637:EURCHF">>},
{'MDFullGrp', [{'NoMDEntries', [
[{'MDEntryType', <<"BID">>}, {'MDEntryPx', <<"1.07509">>},
{'MDEntrySize', <<"200000">>}, {'QuoteCondition', <<"OPEN">>},
{'MDEntryOriginator', <<"PromoXM">>, {'QuoteEntryID', <<"82837831">>}}],
[{'MDEntryType', <<"OFFER">>}, {'MDEntryPx', <<"1.07539">>},
{'MDEntrySize', <<"100000">>}, {'QuoteCondition', <<"OPEN">>},
{'MDEntryOriginator', <<"PromoXM1">>, {'QuoteEntryID', <<"82837832">>}}]
]}]}
]),
Msg = iolist_to_binary(IoList),
{ok, 'MarketDataSnapshotFullRefresh', Markup, <<>>} = erlyfix_parser:parse(Msg, P),
M2Q = fun(M) ->
#quote{
price = maps:get(price, M),
volume = maps:get(volume, M),
source = maps:get(source, M)
}
end,
F = fun(E, {Result, Stack} = Acc ) ->
case E of
{field, 'Symbol', _F, V} -> {ok, [ {symbol, V} | Stack ]};
{field, 'MDEntryType', F, V} ->
case erlyfix_fields:as_label(V, F) of
<<"BID">> -> {ok, [{bid, #{} } | Stack]};
<<"OFFER">> -> {ok, [{ask, #{}} | Stack]}
end;
{field, 'MDEntryPx', _F, V} ->
[{Type, Map0} | T] = Stack,
Price = binary_to_float(V),
{ok, [ {Type, Map0#{price => Price} } | T ] };
{field, 'MDEntrySize', _F, V} ->
[{Type, Map0} | T] = Stack,
Volume = binary_to_integer(V),
{ok, [ {Type, Map0#{volume => Volume} } | T ] };
{field, 'MDEntryOriginator', _F, V} ->
[{Type, Map0} | T] = Stack,
{ok, [ {Type, Map0#{source => V} } | T ] };
{start,group,{'NoMDEntries', 2}} -> Acc;
{start,group,{'NoMDEntries', _}} -> {error, Stack};
{finish,group,{'NoMDEntries', 2}} ->
[E1, E2 | T] = Stack,
{T1, M1} = E1,
Q1 = M2Q(M1),
{T2, M2} = E2,
Q2 = M2Q(M2),
case {T1, T2} of
{bid, ask} -> {ok, [Q1, Q2 | T]};
{ask, bid} -> {ok, [Q2, Q1 | T]}
end;
{finish,trailer,_} ->
case Result of
ok ->
[Bid, Ask, {symbol, Symbol}] = Stack,
Tick = #tick{ bid = Bid, ask = Ask, symbol = Symbol },
{ok, Tick};
_ -> Acc
end;
_ -> Acc
end
end,
{ok, Tick} = lists:foldl(F, {ok, []}, Markup),
% ?DEBUG(Tick),
?assertEqual(#tick{
symbol = <<"EURCHF">>,
bid = #quote{ price = 1.07509, volume = 200000, source = <<"PromoXM">> },
ask = #quote{ price = 1.07539, volume = 100000, source = <<"PromoXM1">> }
}, Tick).