generated from hyperjiang/go-tpl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsdk.go
580 lines (474 loc) · 18.5 KB
/
sdk.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
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
package futu
import (
"context"
"time"
"github.com/hyperjiang/futu/adapt"
"github.com/hyperjiang/futu/client"
"github.com/hyperjiang/futu/pb/getglobalstate"
"github.com/hyperjiang/futu/pb/qotcommon"
"github.com/hyperjiang/futu/pb/qotgetbroker"
"github.com/hyperjiang/futu/pb/qotgetcapitaldistribution"
"github.com/hyperjiang/futu/pb/qotgetcapitalflow"
"github.com/hyperjiang/futu/pb/qotgetfutureinfo"
"github.com/hyperjiang/futu/pb/qotgetipolist"
"github.com/hyperjiang/futu/pb/qotgetkl"
"github.com/hyperjiang/futu/pb/qotgetmarketstate"
"github.com/hyperjiang/futu/pb/qotgetoptionchain"
"github.com/hyperjiang/futu/pb/qotgetoptionexpirationdate"
"github.com/hyperjiang/futu/pb/qotgetorderbook"
"github.com/hyperjiang/futu/pb/qotgetownerplate"
"github.com/hyperjiang/futu/pb/qotgetpricereminder"
"github.com/hyperjiang/futu/pb/qotgetrt"
"github.com/hyperjiang/futu/pb/qotgetsecuritysnapshot"
"github.com/hyperjiang/futu/pb/qotgetsubinfo"
"github.com/hyperjiang/futu/pb/qotgetticker"
"github.com/hyperjiang/futu/pb/qotgetusersecuritygroup"
"github.com/hyperjiang/futu/pb/qotgetwarrant"
"github.com/hyperjiang/futu/pb/qotrequesthistorykl"
"github.com/hyperjiang/futu/pb/qotrequesthistoryklquota"
"github.com/hyperjiang/futu/pb/qotrequestrehab"
"github.com/hyperjiang/futu/pb/qotrequesttradedate"
"github.com/hyperjiang/futu/pb/qotstockfilter"
"github.com/hyperjiang/futu/pb/trdcommon"
"github.com/hyperjiang/futu/pb/trdgetmarginratio"
"github.com/hyperjiang/futu/pb/trdmodifyorder"
"github.com/hyperjiang/futu/pb/trdplaceorder"
)
const defaultTimeout = time.Second * 5
const (
DateFormat = "2006-01-02"
TimeFormat = "2006-01-02 15:04:05"
)
// SDK is Futu SDK.
type SDK struct {
client.Options
cli *client.Client
}
// NewSDK creates a new Futu SDK.
func NewSDK(opts ...client.Option) (*SDK, error) {
cli, err := client.New(opts...)
if err != nil {
return nil, err
}
return &SDK{cli: cli}, nil
}
// Close closes the client.
func (sdk *SDK) Close() error {
return sdk.cli.Close()
}
// GetClient returns the client.
func (sdk *SDK) GetClient() *client.Client {
return sdk.cli
}
// RegisterHandler registers a handler for notifications of a specified protoID.
func (sdk *SDK) RegisterHandler(protoID uint32, h client.Handler) *SDK {
sdk.cli.RegisterHandler(protoID, h)
return sdk
}
// GetGlobalState 1002 - gets the global state.
func (sdk *SDK) GetGlobalState() (*getglobalstate.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetGlobalStateWithContext(ctx)
}
// GetAccList 2001 - gets the trading account list.
func (sdk *SDK) GetAccList(opts ...adapt.Option) ([]*trdcommon.TrdAcc, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetAccListWithContext(ctx, opts...)
}
// UnlockTrade 2005 - unlocks or locks the trade.
//
// unlock: true for unlock, false for lock
//
// pwdMD5: MD5 of the password
//
// securityFirm: security firm
func (sdk *SDK) UnlockTrade(unlock bool, pwdMD5 string, securityFirm int32) error {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.UnlockTradeWithContext(ctx, unlock, pwdMD5, securityFirm)
}
// SubscribeAccPush 2008 - subscribes the trading account push data.
//
// accIDList: account ID list
func (sdk *SDK) SubscribeAccPush(accIDList []uint64) error {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.SubscribeAccPushWithContext(ctx, accIDList)
}
// GetFunds 2101 - gets the funds.
func (sdk *SDK) GetFunds(header *trdcommon.TrdHeader, opts ...adapt.Option) (*trdcommon.Funds, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetFundsWithContext(ctx, header, opts...)
}
// GetPositionList 2102 - gets the position list.
func (sdk *SDK) GetPositionList(header *trdcommon.TrdHeader, opts ...adapt.Option) ([]*trdcommon.Position, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetPositionListWithContext(ctx, header, opts...)
}
// GetOrderList 2111 - gets the maximum available trading quantities.
//
// header: trading header
//
// orderType: order type
//
// code: security code, e.g. US.AAPL
//
// price: price
func (sdk *SDK) GetMaxTrdQtys(header *trdcommon.TrdHeader, orderType int32, code string, price float64, opts ...adapt.Option) (*trdcommon.MaxTrdQtys, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetMaxTrdQtysWithContext(ctx, header, orderType, code, price, opts...)
}
// GetOpenOrderList 2201 - gets the open order list.
func (sdk *SDK) GetOpenOrderList(header *trdcommon.TrdHeader, opts ...adapt.Option) ([]*trdcommon.Order, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetOpenOrderListWithContext(ctx, header, opts...)
}
// PlaceOrder 2202 - places an order.
//
// header: trading header
//
// trdSide: trading side
//
// orderType: order type
//
// code: security code, e.g. US.AAPL
//
// qty: quantity
//
// price: price
func (sdk *SDK) PlaceOrder(header *trdcommon.TrdHeader, trdSide int32, orderType int32, code string, qty float64, price float64, opts ...adapt.Option) (*trdplaceorder.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.PlaceOrderWithContext(ctx, header, trdSide, orderType, code, qty, price, opts...)
}
// ModifyOrder 2205 - modifies an order with context.
//
// header: trading header
//
// orderID: order ID, use 0 if forAll=true
//
// modifyOrderOp: modify order operation
func (sdk *SDK) ModifyOrder(header *trdcommon.TrdHeader, orderID uint64, modifyOrderOp int32, opts ...adapt.Option) (*trdmodifyorder.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.ModifyOrderWithContext(ctx, header, orderID, modifyOrderOp, opts...)
}
// GetHistoryOrderList 2211 - gets the filled order list.
func (sdk *SDK) GetOrderFillList(header *trdcommon.TrdHeader, opts ...adapt.Option) ([]*trdcommon.OrderFill, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetOrderFillListWithContext(ctx, header, opts...)
}
// GetHistoryOrderList 2221 - gets the history order list.
func (sdk *SDK) GetHistoryOrderList(header *trdcommon.TrdHeader, fc *trdcommon.TrdFilterConditions, opts ...adapt.Option) ([]*trdcommon.Order, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetHistoryOrderListWithContext(ctx, header, fc, opts...)
}
// GetHistoryOrderFillList 2222 - gets the history filled order list.
func (sdk *SDK) GetHistoryOrderFillList(header *trdcommon.TrdHeader, fc *trdcommon.TrdFilterConditions, opts ...adapt.Option) ([]*trdcommon.OrderFill, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetHistoryOrderFillListWithContext(ctx, header, fc, opts...)
}
// GetMarginRatio 2223 - gets the margin ratio.
func (sdk *SDK) GetMarginRatio(header *trdcommon.TrdHeader, codes []string) ([]*trdgetmarginratio.MarginRatioInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetMarginRatioWithContext(ctx, header, codes)
}
// GetOrderFee 2225 - gets the order fee.
func (sdk *SDK) GetOrderFee(header *trdcommon.TrdHeader, orderIdExList []string) ([]*trdcommon.OrderFee, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetOrderFeeWithContext(ctx, header, orderIdExList)
}
// Subscribe 3001 - subscribes or unsubscribes.
//
// codes: security codes
//
// subTypes: subscription types
//
// isSub: true for subscribe, false for unsubscribe
func (sdk *SDK) Subscribe(codes []string, subTypes []int32, isSub bool, opts ...adapt.Option) error {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.SubscribeWithContext(ctx, codes, subTypes, isSub, opts...)
}
// GetSubInfo 3003 - gets the subscription information.
func (sdk *SDK) GetSubInfo(opts ...adapt.Option) (*qotgetsubinfo.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetSubInfoWithContext(ctx, opts...)
}
// GetBasicQot 3004 - gets the basic quotes of given securities.
func (sdk *SDK) GetBasicQot(codes []string) ([]*qotcommon.BasicQot, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetBasicQotWithContext(ctx, codes)
}
// GetKL 3006 - gets K-line data.
//
// code: security code
//
// klType: K-line type
func (sdk *SDK) GetKL(code string, klType int32, opts ...adapt.Option) (*qotgetkl.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetKLWithContext(ctx, code, klType, opts...)
}
// GetRT 3008 - gets real-time data.
//
// code: security code
func (sdk *SDK) GetRT(code string) (*qotgetrt.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetRTWithContext(ctx, code)
}
// GetTicker 3010 - gets ticker data.
//
// code: security code
func (sdk *SDK) GetTicker(code string, opts ...adapt.Option) (*qotgetticker.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetTickerWithContext(ctx, code, opts...)
}
// GetOrderBook 3012 - gets order book data.
//
// code: security code
func (sdk *SDK) GetOrderBook(code string, opts ...adapt.Option) (*qotgetorderbook.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetOrderBookWithContext(ctx, code, opts...)
}
// GetBroker 3014 - gets broker data.
//
// code: security code
func (sdk *SDK) GetBroker(code string) (*qotgetbroker.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetBrokerWithContext(ctx, code)
}
// RequestHistoryKL 3103 - requests the history K-line data.
//
// code: security code
//
// klType: K-line type
//
// beginTime: begin time, format: "yyyy-MM-dd"
//
// endTime: end time, format: "yyyy-MM-dd"
func (sdk *SDK) RequestHistoryKL(code string, klType int32, beginTime string, endTime string, opts ...adapt.Option) (*qotrequesthistorykl.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.RequestHistoryKLWithContext(ctx, code, klType, beginTime, endTime, opts...)
}
// RequestHistoryKLQuota 3104 - requests the history K-line quota.
func (sdk *SDK) RequestHistoryKLQuota(opts ...adapt.Option) (*qotrequesthistoryklquota.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.RequestHistoryKLQuotaWithContext(ctx, opts...)
}
// RequestRehab 3105 - requests the rehab data.
func (sdk *SDK) RequestRehab(code string) (*qotrequestrehab.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.RequestRehabWithContext(ctx, code)
}
// GetStaticInfo 3202 - gets the static information.
func (sdk *SDK) GetStaticInfo(opts ...adapt.Option) ([]*qotcommon.SecurityStaticInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetStaticInfoWithContext(ctx, opts...)
}
// GetSecuritySnapshot 3203 - gets the security snapshot.
//
// codes: security codes
func (sdk *SDK) GetSecuritySnapshot(codes []string) ([]*qotgetsecuritysnapshot.Snapshot, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetSecuritySnapshotWithContext(ctx, codes)
}
// GetPlateSet 3204 - gets the plate set.
//
// market: market
//
// plateSetType: plate set type
func (sdk *SDK) GetPlateSet(market int32, plateSetType int32) ([]*qotcommon.PlateInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetPlateSetWithContext(ctx, market, plateSetType)
}
// GetPlateSecurity 3205 - gets the plate securities.
//
// plateCode: plate code
func (sdk *SDK) GetPlateSecurity(plateCode string, opts ...adapt.Option) ([]*qotcommon.SecurityStaticInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetPlateSecurityWithContext(ctx, plateCode, opts...)
}
// GetReference 3206 - gets the reference data.
//
// code: security code
//
// refType: reference type
func (sdk *SDK) GetReference(code string, refType int32) ([]*qotcommon.SecurityStaticInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetReferenceWithContext(ctx, code, refType)
}
// GetOwnerPlate 3207 - gets the owner plate.
//
// codes: security codes
func (sdk *SDK) GetOwnerPlate(codes []string) ([]*qotgetownerplate.SecurityOwnerPlate, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetOwnerPlateWithContext(ctx, codes)
}
// GetOptionChain 3209 - gets the option chain with context.
//
// code: security code
//
// beginTime: begin time, format: "yyyy-MM-dd"
//
// endTime: end time, format: "yyyy-MM-dd"
func (sdk *SDK) GetOptionChain(code string, beginTime string, endTime string, opts ...adapt.Option) ([]*qotgetoptionchain.OptionChain, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetOptionChainWithContext(ctx, code, beginTime, endTime, opts...)
}
// GetWarrant 3210 - gets the warrant, only available in Hong Kong market.
// Sort by score in descending order by default.
//
// begin: begin index
//
// num: number of warrants
func (sdk *SDK) GetWarrant(begin int32, num int32, opts ...adapt.Option) (*qotgetwarrant.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetWarrantWithContext(ctx, begin, num, opts...)
}
// GetCapitalFlow 3211 - gets the capital flow.
//
// code: security code
func (sdk *SDK) GetCapitalFlow(code string, opts ...adapt.Option) (*qotgetcapitalflow.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetCapitalFlowWithContext(ctx, code, opts...)
}
// GetCapitalDistribution 3212 - gets the capital distribution.
//
// code: security code
func (sdk *SDK) GetCapitalDistribution(code string) (*qotgetcapitaldistribution.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetCapitalDistributionWithContext(ctx, code)
}
// GetUserSecurity 3213 - gets the user security.
//
// groupName: group name
func (sdk *SDK) GetUserSecurity(groupName string) ([]*qotcommon.SecurityStaticInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetUserSecurityWithContext(ctx, groupName)
}
// ModifyUserSecurity 3214 - modifies the user security.
//
// groupName: group name
//
// codes: security codes
//
// op: operation, 1 for add, 2 for delete
func (sdk *SDK) ModifyUserSecurity(groupName string, codes []string, op int32) error {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.ModifyUserSecurityWithContext(ctx, groupName, codes, op)
}
// StockFilter 3215 - filters the stocks.
//
// market: market
func (sdk *SDK) StockFilter(market int32, opts ...adapt.Option) (*qotstockfilter.S2C, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.StockFilterWithContext(ctx, market, opts...)
}
// GetIpoList 3217 - gets the IPO list.
//
// market: market
func (sdk *SDK) GetIpoList(market int32) ([]*qotgetipolist.IpoData, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetIpoListWithContext(ctx, market)
}
// GetFutureInfo 3218 - gets the future information.
//
// codes: security codes
func (sdk *SDK) GetFutureInfo(codes []string) ([]*qotgetfutureinfo.FutureInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetFutureInfoWithContext(ctx, codes)
}
// RequestTradeDate 3219 - requests the trade date.
//
// market: market
//
// code: security code
//
// beginTime: begin time, format: "yyyy-MM-dd"
//
// endTime: end time, format: "yyyy-MM-dd"
func (sdk *SDK) RequestTradeDate(market int32, code string, beginTime string, endTime string) ([]*qotrequesttradedate.TradeDate, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.RequestTradeDateWithContext(ctx, market, code, beginTime, endTime)
}
// SetPriceReminder 3220 - sets the price reminder.
//
// code: security code
//
// op: operation, 1 for add, 2 for delete
func (sdk *SDK) SetPriceReminder(code string, op int32, opts ...adapt.Option) (int64, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.SetPriceReminderWithContext(ctx, code, op, opts...)
}
// GetPriceReminder 3221 - gets the price reminder.
//
// code: security code
//
// market: market, if security is set, this param is ignored
func (sdk *SDK) GetPriceReminder(code string, market int32) ([]*qotgetpricereminder.PriceReminder, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetPriceReminderWithContext(ctx, code, market)
}
// GetUserSecurityGroup 3222 - gets the user security group.
//
// groupType: group type
func (sdk *SDK) GetUserSecurityGroup(groupType int32) ([]*qotgetusersecuritygroup.GroupData, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetUserSecurityGroupWithContext(ctx, groupType)
}
// GetMarketState 3223 - gets the market state.
//
// codes: security codes
func (sdk *SDK) GetMarketState(codes []string) ([]*qotgetmarketstate.MarketInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetMarketStateWithContext(ctx, codes)
}
// GetOptionExpirationDate 3224 - gets the option expiration date.
//
// code: security code
func (sdk *SDK) GetOptionExpirationDate(code string, opts ...adapt.Option) ([]*qotgetoptionexpirationdate.OptionExpirationDate, error) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
return sdk.GetOptionExpirationDateWithContext(ctx, code, opts...)
}