Skip to content

Commit 09e455f

Browse files
committed
Suppport ReqSecDefOptParams and its corresponding responses
This involves supporting messages without a version field, since the more recent messages eschew "version" for some reason.
1 parent 6a75972 commit 09e455f

File tree

3 files changed

+185
-45
lines changed

3 files changed

+185
-45
lines changed

eclientsocket.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ const (
132132
mUpdateDisplayGroup = 69
133133
mUnsubscribeFromGroupEvents = 70
134134
mStartAPI = 71
135+
mRequestSecDefOptParams = 78
135136
)
136137

137138
type serverHandshake struct {
@@ -1363,6 +1364,40 @@ func (c *CancelPositions) code() OutgoingMessageID { return mCancelPositions
13631364
func (c *CancelPositions) version() int64 { return 1 }
13641365
func (c *CancelPositions) write(b *bytes.Buffer) error { return nil }
13651366

1367+
// RequestSecDefOptParams is equivalent of IB API EClientSocket.reqSecDefOptParams
1368+
type RequestSecDefOptParams struct {
1369+
id int64
1370+
Symbol string
1371+
Exchange string
1372+
SecType string
1373+
ContractId int64
1374+
}
1375+
1376+
func (r *RequestSecDefOptParams) SetID(id int64) { r.id = id }
1377+
1378+
func (r *RequestSecDefOptParams) ID() int64 { return r.id }
1379+
func (r *RequestSecDefOptParams) code() OutgoingMessageID { return mRequestSecDefOptParams }
1380+
func (r *RequestSecDefOptParams) version() int64 { return -1 }
1381+
func (r *RequestSecDefOptParams) write(b *bytes.Buffer) error {
1382+
if err := writeInt(b, r.id); err != nil {
1383+
return err
1384+
}
1385+
1386+
if err := writeString(b, r.Symbol); err != nil {
1387+
return err
1388+
}
1389+
1390+
if err := writeString(b, r.Exchange); err != nil {
1391+
return err
1392+
}
1393+
1394+
if err := writeString(b, r.SecType); err != nil {
1395+
return err
1396+
}
1397+
1398+
return writeInt(b, r.ContractId)
1399+
}
1400+
13661401
// RequestAccountSummary is equivalent of IB API EClientSocket.reqAccountSummary()
13671402
type RequestAccountSummary struct {
13681403
id int64

engine.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,11 @@ func (v *header) write(b *bytes.Buffer) error {
538538
if err := writeInt(b, v.code); err != nil {
539539
return err
540540
}
541-
return writeInt(b, v.version)
541+
542+
if v.version != -1 {
543+
return writeInt(b, v.version)
544+
}
545+
return nil
542546
}
543547

544548
func (v *header) read(b *bufio.Reader) error {
@@ -547,7 +551,13 @@ func (v *header) read(b *bufio.Reader) error {
547551
if v.code, err = readInt(b); err != nil {
548552
return err
549553
}
550-
v.version, err = readInt(b)
554+
555+
if msgHasVersion(v.code) {
556+
v.version, err = readInt(b)
557+
} else {
558+
v.version = -1
559+
}
560+
551561
return err
552562
}
553563

ereader.go

Lines changed: 138 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,49 +14,51 @@ type IncomingMessageID int64
1414

1515
// Message types enum
1616
const (
17-
mTickPrice IncomingMessageID = 1
18-
mTickSize = 2
19-
mOrderStatus = 3
20-
mErrorMessage = 4
21-
mOpenOrder = 5
22-
mAccountValue = 6
23-
mPortfolioValue = 7
24-
mAccountUpdateTime = 8
25-
mNextValidID = 9
26-
mContractData = 10
27-
mExecutionData = 11
28-
mMarketDepth = 12
29-
mMarketDepthL2 = 13
30-
mNewsBulletins = 14
31-
mManagedAccounts = 15
32-
mReceiveFA = 16
33-
mHistoricalData = 17
34-
mBondContractData = 18
35-
mScannerParameters = 19
36-
mScannerData = 20
37-
mTickOptionComputation = 21
38-
mTickGeneric = 45
39-
mTickString = 46
40-
mTickEFP = 47
41-
mCurrentTime = 49
42-
mRealtimeBars = 50
43-
mFundamentalData = 51
44-
mContractDataEnd = 52
45-
mOpenOrderEnd = 53
46-
mAccountDownloadEnd = 54
47-
mExecutionDataEnd = 55
48-
mDeltaNeutralValidation = 56
49-
mTickSnapshotEnd = 57
50-
mMarketDataType = 58
51-
mCommissionReport = 59
52-
mPosition = 61
53-
mPositionEnd = 62
54-
mAccountSummary = 63
55-
mAccountSummaryEnd = 64
56-
mVerifyMessageAPI = 65
57-
mVerifyCompleted = 66
58-
mDisplayGroupList = 67
59-
mDisplayGroupUpdated = 68
17+
mTickPrice IncomingMessageID = 1
18+
mTickSize = 2
19+
mOrderStatus = 3
20+
mErrorMessage = 4
21+
mOpenOrder = 5
22+
mAccountValue = 6
23+
mPortfolioValue = 7
24+
mAccountUpdateTime = 8
25+
mNextValidID = 9
26+
mContractData = 10
27+
mExecutionData = 11
28+
mMarketDepth = 12
29+
mMarketDepthL2 = 13
30+
mNewsBulletins = 14
31+
mManagedAccounts = 15
32+
mReceiveFA = 16
33+
mHistoricalData = 17
34+
mBondContractData = 18
35+
mScannerParameters = 19
36+
mScannerData = 20
37+
mTickOptionComputation = 21
38+
mTickGeneric = 45
39+
mTickString = 46
40+
mTickEFP = 47
41+
mCurrentTime = 49
42+
mRealtimeBars = 50
43+
mFundamentalData = 51
44+
mContractDataEnd = 52
45+
mOpenOrderEnd = 53
46+
mAccountDownloadEnd = 54
47+
mExecutionDataEnd = 55
48+
mDeltaNeutralValidation = 56
49+
mTickSnapshotEnd = 57
50+
mMarketDataType = 58
51+
mCommissionReport = 59
52+
mPosition = 61
53+
mPositionEnd = 62
54+
mAccountSummary = 63
55+
mAccountSummaryEnd = 64
56+
mVerifyMessageAPI = 65
57+
mVerifyCompleted = 66
58+
mDisplayGroupList = 67
59+
mDisplayGroupUpdated = 68
60+
mSecurityDefinitionOptionParameter = 75
61+
mSecurityDefinitionOptionParameterEnd = 76
6062
)
6163

6264
// code2Msg is equivalent of EReader.processMsg() switch statement cases.
@@ -148,12 +150,28 @@ func code2Msg(code int64) (r Reply, err error) {
148150
r = &DisplayGroupList{}
149151
case int64(mDisplayGroupUpdated):
150152
r = &DisplayGroupUpdated{}
153+
case int64(mSecurityDefinitionOptionParameter):
154+
r = &SecurityDefinitionOptionParameter{}
155+
case int64(mSecurityDefinitionOptionParameterEnd):
156+
r = &SecurityDefinitionOptionParameterEnd{}
151157
default:
152158
err = fmt.Errorf("Unsupported incoming message type %d", code)
153159
}
154160
return r, err
155161
}
156162

163+
func msgHasVersion(code int64) bool {
164+
switch code {
165+
case int64(mSecurityDefinitionOptionParameter):
166+
return false
167+
case int64(mSecurityDefinitionOptionParameterEnd):
168+
return false
169+
default:
170+
}
171+
172+
return true
173+
}
174+
157175
// TickPrice holds bid, ask, last, etc. price information
158176
type TickPrice struct {
159177
id int64
@@ -1893,3 +1911,80 @@ func (d *DisplayGroupUpdated) read(b *bufio.Reader) (err error) {
18931911
d.ContractInfo, err = readString(b)
18941912
return err
18951913
}
1914+
1915+
type SecurityDefinitionOptionParameter struct {
1916+
id int64
1917+
Exchange string
1918+
ContractId int64
1919+
TradingClass string
1920+
Multiplier string
1921+
Expirations []string
1922+
Strikes []float64
1923+
}
1924+
1925+
func (s *SecurityDefinitionOptionParameter) ID() int64 { return s.id }
1926+
func (s *SecurityDefinitionOptionParameter) code() IncomingMessageID {
1927+
return mSecurityDefinitionOptionParameter
1928+
}
1929+
func (s *SecurityDefinitionOptionParameter) read(b *bufio.Reader) (err error) {
1930+
if s.id, err = readInt(b); err != nil {
1931+
return err
1932+
}
1933+
1934+
if s.Exchange, err = readString(b); err != nil {
1935+
return err
1936+
}
1937+
1938+
if s.ContractId, err = readInt(b); err != nil {
1939+
return err
1940+
}
1941+
1942+
if s.TradingClass, err = readString(b); err != nil {
1943+
return err
1944+
}
1945+
1946+
if s.Multiplier, err = readString(b); err != nil {
1947+
return err
1948+
}
1949+
1950+
numExpirations, err := readInt(b)
1951+
if err != nil {
1952+
return err
1953+
}
1954+
1955+
s.Expirations = make([]string, numExpirations)
1956+
for i := int64(0); i < numExpirations; i += 1 {
1957+
if s.Expirations[i], err = readString(b); err != nil {
1958+
return err
1959+
}
1960+
}
1961+
1962+
numStrikes, err := readInt(b)
1963+
if err != nil {
1964+
return err
1965+
}
1966+
1967+
s.Strikes = make([]float64, numStrikes)
1968+
for i := int64(0); i < numStrikes; i += 1 {
1969+
if s.Strikes[i], err = readFloat(b); err != nil {
1970+
return err
1971+
}
1972+
}
1973+
1974+
return nil
1975+
1976+
}
1977+
1978+
type SecurityDefinitionOptionParameterEnd struct {
1979+
id int64
1980+
}
1981+
1982+
// ID contains the TWS "reqId", which is used for reply correlation.
1983+
func (s *SecurityDefinitionOptionParameterEnd) ID() int64 { return s.id }
1984+
func (s *SecurityDefinitionOptionParameterEnd) code() IncomingMessageID {
1985+
return mSecurityDefinitionOptionParameterEnd
1986+
}
1987+
func (s *SecurityDefinitionOptionParameterEnd) read(b *bufio.Reader) (err error) {
1988+
s.id, err = readInt(b)
1989+
return err
1990+
}

0 commit comments

Comments
 (0)