-
Notifications
You must be signed in to change notification settings - Fork 1
/
msg_server_trading_session_list.go
293 lines (246 loc) · 14.1 KB
/
msg_server_trading_session_list.go
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
package keeper
import (
"context"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/jim380/Re/utils/constants"
"github.com/jim380/Re/x/fix/types"
)
// TradingSessionListRequest creates Trading Session List Request
func (k msgServer) TradingSessionListRequest(goCtx context.Context, msg *types.MsgTradingSessionListRequest) (*types.MsgTradingSessionListRequestResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// Validate the message creator
_, err := sdk.AccAddressFromBech32(msg.Creator)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Creator)
}
// check for if the provided session ID exists
session, found := k.GetSessions(ctx, msg.SessionID)
if !found {
return nil, sdkerrors.Wrapf(types.ErrEmptySession, "SessionID: %s", msg.SessionID)
}
// check that logon is established between both parties and that logon status equals to "loggedIn"
if session.Status != constants.LoggedInStatus {
return nil, sdkerrors.Wrapf(types.ErrSessionIsNotLoggedIn, "Status of Session: %s", msg.SessionID)
}
// check that the parties involved in a session are the ones using the sessionID and are able to create trading session list request
if session.LogonInitiator.Header.SenderCompID != msg.Creator && session.LogonAcceptor.Header.SenderCompID != msg.Creator {
return nil, sdkerrors.Wrapf(types.ErrNotAccountCreator, "Session Creator: %s", msg.Creator)
}
// check that the mandatory Trading Session list Request field is not empty
if msg.SubscriptionRequestType == "" {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListEmptyField, "SubscriptionRequestType: %s", msg.SubscriptionRequestType)
}
// when TradSesReqID is from the previous Trading Session Status Request (g)
if msg.TradSesReqID != "" {
// check that the provided TradSesReqID exists from the Trading Session
tradingSession, found := k.GetTradingSession(ctx, msg.TradSesReqID)
if !found {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionIsNotFound, ": %s", tradingSession.TradingSessionStatusRequest)
}
}
tradingSessionListRequest := types.TradingSessionList{
SessionID: msg.SessionID,
TradingSessionListRequest: &types.TradingSessionListRequest{
TradSesReqID: msg.TradSesReqID,
TradingSessionID: msg.TradingSessionID,
TradingSessionSubID: msg.TradingSessionSubID,
SecurityExchange: msg.SecurityExchange,
TradSesMethod: msg.TradSesMethod,
TradSesMode: msg.TradSesMode,
SubscriptionRequestType: msg.SubscriptionRequestType,
},
}
// fetch Header from existing session
// In the FIX Protocol, Trading Session List Request is sent by the client and the client is the party that initiates the logon request
// set the header and make changes to the header
// calculate and include all changes to the header
// MsgType (35) is set to "BI" to indicate a Trading Session List Request.
// SenderCompID (49) contains the ID of the sender (client).
// TargetCompID (56) contains the ID of the target (trading venue).
// BodyLength should be calculated using the BodyLength function
// set sending time to current time at creating Trading Session List Request
tradingSessionListRequest.TradingSessionListRequestReject.Header = session.LogonInitiator.Header
tradingSessionListRequest.TradingSessionListRequestReject.Header.MsgType = "BI"
tradingSessionListRequest.TradingSessionListRequestReject.Header.SendingTime = constants.SendingTime
// fetch Trailer from existing session
// TODO
// checksum in the trailer can be recalculated using CalculateChecksum function
tradingSessionListRequest.TradingSessionListRequestReject.Trailer = session.LogonInitiator.Trailer
// set Trade Session List Request to store
k.SetTradingSessionList(ctx, msg.TradSesReqID, tradingSessionListRequest)
// emit event
err = ctx.EventManager().EmitTypedEvent(msg)
return &types.MsgTradingSessionListRequestResponse{}, err
}
// TradingSessionListResponse creates Trading Session List Response
// TradingSessionListResponse is used for responding to TradingSessionListRequest
func (k msgServer) TradingSessionListResponse(goCtx context.Context, msg *types.MsgTradingSessionListResponse) (*types.MsgTradingSessionListResponseResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// Validate the message creator
_, err := sdk.AccAddressFromBech32(msg.Creator)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Creator)
}
// check for if the provided session ID exists
session, found := k.GetSessions(ctx, msg.SessionID)
if !found {
return nil, sdkerrors.Wrapf(types.ErrEmptySession, "SessionID: %s", msg.SessionID)
}
// check that the sessionID provided by the creator of Trading Session List Response matches with the sessionID for Trading Session List Request
if session.SessionID != msg.SessionID {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListSession, "SessionID: %s", msg.SessionID)
}
// check that the user responding is the recipient of the Trading Session List Request
if session.LogonInitiator.Header.SenderCompID != msg.Creator && session.LogonAcceptor.Header.SenderCompID != msg.Creator {
return nil, sdkerrors.Wrapf(types.ErrNotAccountCreator, "Trading Session List Response Creator: %s", msg.Creator)
}
// get Trading Session List
tradingSessionList, found := k.GetTradingSessionList(ctx, msg.TradSesReqID)
if !found {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListIsNotFound, ": %s", tradingSessionList.TradingSessionListRequest)
}
// same account can not used for creating Trading Session List Request and Trading Session List Response with the same TradSesReqID
if tradingSessionList.TradingSessionListRequest.Header.SenderCompID == msg.Creator {
return nil, sdkerrors.Wrap(sdkerrors.ErrKeyNotFound, fmt.Sprintf("key %s This account can not be used to create Trading Session List Response", msg.Creator))
}
// check that the Trading Session List Request is not rejected already
if tradingSessionList.TradingSessionListRequestReject != nil {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListRequestIsRejected, "Trading Session List: %s", tradingSessionList.TradingSessionListRequestReject)
}
// check that the Trading Session List Request is not acknowledged already
if tradingSessionList.TradingSessionListResponse != nil {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListRequestIsAcknowledged, "Trading Session List: %s", tradingSessionList.TradingSessionListResponse)
}
// check that the mandatory Trading Session list Response field are not empty
if msg.NoTradingSessions == "" {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListEmptyField, "NoTradingSessions: %s", msg.NoTradingSessions)
}
if msg.TradingSessionID == "" {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListEmptyField, "TradingSessionID: %s", msg.TradingSessionID)
}
if msg.TradSesStatus == "" {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListEmptyField, "TradSesStatus: %s", msg.TradSesStatus)
}
tradingSessionListResponse := types.TradingSessionList{
SessionID: msg.SessionID,
TradingSessionListRequest: tradingSessionList.TradingSessionListRequest,
TradingSessionListResponse: &types.TradingSessionListResponse{
TradSesReqID: msg.TradSesReqID,
NoTradingSessions: msg.NoTradingSessions,
TradingSessionID: msg.TradingSessionID,
TradingSessionSubID: msg.TradingSessionSubID,
SecurityExchange: msg.SecurityExchange,
TradSesMethod: msg.TradSesMethod,
TradSesMode: msg.TradSesMode,
UnsolicitedIndicator: msg.UnsolicitedIndicator,
TradSesStatus: msg.TradSesStatus,
TradSesStatusRejReason: msg.TradSesStatusRejReason,
TradSesStartTime: msg.TradSesStartTime,
TradSesOpenTime: msg.TradSesOpenTime,
TradSesPreCloseTime: msg.TradSesPreCloseTime,
TradSesCloseTime: msg.TradSesCloseTime,
TradSesEndTime: msg.TradSesEndTime,
},
}
// fetch Header from existing session
// In the FIX Protocol, Trading Session List Response is sent by the server(trading venue) and the server is the party that accepts the logon request
// set the header and make changes to the header
// calculate and include all changes to the header
// MsgType (35) is set to "BJ" to indicate a Trading Session List Response.
// SenderCompID (49) contains the ID of the sender (trading venue).
// TargetCompID (56) contains the ID of the target (client).
// BodyLength should be calculated using the BodyLength function
// set sending time to current time at creating Trading Session List Response
tradingSessionListResponse.TradingSessionListResponse.Header = session.LogonAcceptor.Header
tradingSessionListResponse.TradingSessionListResponse.Header.MsgType = "BJ"
tradingSessionListResponse.TradingSessionListResponse.Header.SendingTime = constants.SendingTime
// fetch Trailer from existing session
// TODO
// checksum in the trailer can be recalculated using CalculateChecksum function
tradingSessionListResponse.TradingSessionListResponse.Trailer = session.LogonAcceptor.Trailer
// set new Trading Session List Response to store
k.SetTradingSessionList(ctx, msg.TradSesReqID, tradingSessionListResponse)
// emit event
err = ctx.EventManager().EmitTypedEvent(msg)
return &types.MsgTradingSessionListResponseResponse{}, err
}
// TradingSessionListRequestReject creates Trading Session List Request Reject
func (k msgServer) TradingSessionListRequestReject(goCtx context.Context, msg *types.MsgTradingSessionListRequestReject) (*types.MsgTradingSessionListRequestRejectResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// Validate the message creator
_, err := sdk.AccAddressFromBech32(msg.Creator)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, msg.Creator)
}
// check for if the provided session ID exists
session, found := k.GetSessions(ctx, msg.SessionID)
if !found {
return nil, sdkerrors.Wrapf(types.ErrEmptySession, "SessionID: %s", msg.SessionID)
}
// check that the sessionID provided by the creator of Trading Session List Request Reject matches with the sessionID for Trading Session List Request
if session.SessionID != msg.SessionID {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListSession, "SessionID: %s", msg.SessionID)
}
// check that the user responding is the recipient of the Trading Session List Request
if session.LogonInitiator.Header.SenderCompID != msg.Creator && session.LogonAcceptor.Header.SenderCompID != msg.Creator {
return nil, sdkerrors.Wrapf(types.ErrNotAccountCreator, "Trading Session List Request Reject Creator: %s", msg.Creator)
}
// get Trading Session List
tradingSessionList, found := k.GetTradingSessionList(ctx, msg.TradSesReqID)
if !found {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListIsNotFound, ": %s", tradingSessionList.TradingSessionListRequest)
}
// same account can not used for creating Trading Session List Request and Trading Session List Request Reject with the same TradSesReqID
if tradingSessionList.TradingSessionListRequest.Header.SenderCompID == msg.Creator {
return nil, sdkerrors.Wrap(sdkerrors.ErrKeyNotFound, fmt.Sprintf("key %s This account can not be used to create Trading Session List Request Reject", msg.Creator))
}
// check that the Trading Session List Request is not rejected already
if tradingSessionList.TradingSessionListRequestReject != nil {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListRequestIsRejected, "Trading Session List: %s", tradingSessionList.TradingSessionListRequestReject)
}
// check that the Trading Session List Request is not acknowledged already
if tradingSessionList.TradingSessionListResponse != nil {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListRequestIsAcknowledged, "Trading Session List: %s", tradingSessionList.TradingSessionListResponse)
}
// check that the mandatory Trading Session Request Reject fields are not empty
if msg.TradSesStatus == "" {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListEmptyField, "TradSesStatus: %s", msg.TradSesStatus)
}
if msg.TradSesStatusRejReason == "" {
return nil, sdkerrors.Wrapf(types.ErrTradingSessionListEmptyField, "TradSesStatusRejReason: %s", msg.TradSesStatusRejReason)
}
tradingSessionListRequestReject := types.TradingSessionList{
SessionID: msg.SessionID,
TradingSessionListRequest: tradingSessionList.TradingSessionListRequest,
TradingSessionListResponse: tradingSessionList.TradingSessionListResponse,
TradingSessionListRequestReject: &types.TradingSessionListRequestReject{
TradSesReqID: msg.TradSesReqID,
TradSesStatus: msg.TradSesStatus,
TradSesStatusRejReason: msg.TradSesStatusRejReason,
Text: msg.Text,
},
}
// fetch Header from existing session
// In the FIX Protocol, Trading Session List Request Reject is sent by the server(trading venue) and the server is the party that accepts the logon request
// set the header and make changes to the header
// calculate and include all changes to the header
// MsgType (35) is set to "BK" to indicate a Trading Session List Request Reject.
// SenderCompID (49) contains the ID of the sender (trading venue).
// TargetCompID (56) contains the ID of the target (client).
// BodyLength should be calculated using the BodyLength function
// set sending time to current time at creating Trading Session List Request Reject
tradingSessionListRequestReject.TradingSessionListRequestReject.Header = session.LogonAcceptor.Header
tradingSessionListRequestReject.TradingSessionListRequestReject.Header.MsgType = "BK"
tradingSessionListRequestReject.TradingSessionListRequestReject.Header.SendingTime = constants.SendingTime
// fetch Trailer from existing session
// TODO
// checksum in the trailer can be recalculated using CalculateChecksum function
tradingSessionListRequestReject.TradingSessionListRequestReject.Trailer = session.LogonAcceptor.Trailer
// set new Trading Session List Request Reject to store
k.SetTradingSessionList(ctx, msg.TradSesReqID, tradingSessionListRequestReject)
// emit event
err = ctx.EventManager().EmitTypedEvent(msg)
return &types.MsgTradingSessionListRequestRejectResponse{}, err
}