mirror of
				https://github.com/aclindsa/ofxgo.git
				synced 2025-11-03 18:03:25 -05:00 
			
		
		
		
	Add requesting/parsing security list
This commit is contained in:
		@@ -131,12 +131,6 @@ type PendingTransactionList struct {
 | 
				
			|||||||
	Transactions []PendingTransaction `xml:"STMTTRNP,omitempty"`
 | 
						Transactions []PendingTransaction `xml:"STMTTRNP,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Currency struct {
 | 
					 | 
				
			||||||
	XMLName xml.Name // CURRENCY or ORIGCURRENCY
 | 
					 | 
				
			||||||
	CurRate Amount   `xml:"CURRATE"` // Ratio of <CURDEF> currency to <CURSYM> currency
 | 
					 | 
				
			||||||
	CurSym  String   `xml:"CURSYM"`  // ISO-4217 3-character currency identifier
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Balance struct {
 | 
					type Balance struct {
 | 
				
			||||||
	XMLName xml.Name `xml:"BAL"`
 | 
						XMLName xml.Name `xml:"BAL"`
 | 
				
			||||||
	Name    String   `xml:"NAME"`
 | 
						Name    String   `xml:"NAME"`
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,3 +48,9 @@ type InvAcct struct {
 | 
				
			|||||||
	BrokerId String   `xml:"BROKERID"`
 | 
						BrokerId String   `xml:"BROKERID"`
 | 
				
			||||||
	AcctId   String   `xml:"ACCTID"`
 | 
						AcctId   String   `xml:"ACCTID"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Currency struct {
 | 
				
			||||||
 | 
						XMLName xml.Name // CURRENCY or ORIGCURRENCY
 | 
				
			||||||
 | 
						CurRate Amount   `xml:"CURRATE"` // Ratio of <CURDEF> currency to <CURSYM> currency
 | 
				
			||||||
 | 
						CurSym  String   `xml:"CURSYM"`  // ISO-4217 3-character currency identifier
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ type Request struct {
 | 
				
			|||||||
	//<WIREXFERMSGSETV1>
 | 
						//<WIREXFERMSGSETV1>
 | 
				
			||||||
	//<BILLPAYMSGSETV1>
 | 
						//<BILLPAYMSGSETV1>
 | 
				
			||||||
	//<EMAILMSGSETV1>
 | 
						//<EMAILMSGSETV1>
 | 
				
			||||||
	//<SECLISTMSGSETV1>
 | 
						Securities []Message //<SECLISTMSGSETV1>
 | 
				
			||||||
	//<PRESDIRMSGSETV1>
 | 
						//<PRESDIRMSGSETV1>
 | 
				
			||||||
	//<PRESDLVMSGSETV1>
 | 
						//<PRESDLVMSGSETV1>
 | 
				
			||||||
	Profile []Message //<PROFMSGSETV1>
 | 
						Profile []Message //<PROFMSGSETV1>
 | 
				
			||||||
@@ -109,6 +109,9 @@ NEWFILEUID:NONE
 | 
				
			|||||||
	if err := marshalMessageSet(encoder, oq.Investments, "INVSTMTMSGSRQV1"); err != nil {
 | 
						if err := marshalMessageSet(encoder, oq.Investments, "INVSTMTMSGSRQV1"); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if err := marshalMessageSet(encoder, oq.Securities, "SECLISTMSGSRQV1"); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if err := marshalMessageSet(encoder, oq.Profile, "PROFMSGSRQV1"); err != nil {
 | 
						if err := marshalMessageSet(encoder, oq.Profile, "PROFMSGSRQV1"); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,7 @@ type Response struct {
 | 
				
			|||||||
	//<WIREXFERMSGSETV1>
 | 
						//<WIREXFERMSGSETV1>
 | 
				
			||||||
	//<BILLPAYMSGSETV1>
 | 
						//<BILLPAYMSGSETV1>
 | 
				
			||||||
	//<EMAILMSGSETV1>
 | 
						//<EMAILMSGSETV1>
 | 
				
			||||||
	//<SECLISTMSGSETV1>
 | 
						Securities []Message //<SECLISTMSGSETV1>
 | 
				
			||||||
	//<PRESDIRMSGSETV1>
 | 
						//<PRESDIRMSGSETV1>
 | 
				
			||||||
	//<PRESDLVMSGSETV1>
 | 
						//<PRESDLVMSGSETV1>
 | 
				
			||||||
	Profile []Message //<PROFMSGSETV1>
 | 
						Profile []Message //<PROFMSGSETV1>
 | 
				
			||||||
@@ -281,7 +281,12 @@ func ParseResponse(reader io.Reader) (*Response, error) {
 | 
				
			|||||||
			//case "WIREXFERMSGSRSV1":
 | 
								//case "WIREXFERMSGSRSV1":
 | 
				
			||||||
			//case "BILLPAYMSGSRSV1":
 | 
								//case "BILLPAYMSGSRSV1":
 | 
				
			||||||
			//case "EMAILMSGSRSV1":
 | 
								//case "EMAILMSGSRSV1":
 | 
				
			||||||
			//case "SECLISTMSGSRSV1":
 | 
								case "SECLISTMSGSRSV1":
 | 
				
			||||||
 | 
									msgs, err := DecodeSecuritiesMessageSet(decoder, start)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									or.Securities = msgs
 | 
				
			||||||
			//case "PRESDIRMSGSRSV1":
 | 
								//case "PRESDIRMSGSRSV1":
 | 
				
			||||||
			//case "PRESDLVMSGSRSV1":
 | 
								//case "PRESDLVMSGSRSV1":
 | 
				
			||||||
			case "PROFMSGSRSV1":
 | 
								case "PROFMSGSRSV1":
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										260
									
								
								securities.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								securities.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,260 @@
 | 
				
			|||||||
 | 
					package ofxgo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"github.com/golang/go/src/encoding/xml"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SecurityId struct {
 | 
				
			||||||
 | 
						XMLName      xml.Name `xml:"SECID"`
 | 
				
			||||||
 | 
						UniqueId     String   `xml:"UNIQUEID"`     // CUSIP for US FI's
 | 
				
			||||||
 | 
						UniqueIdType String   `xml:"UNIQUEIDTYPE"` // Should always be "CUSIP" for US FI's
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SecurityRequest struct {
 | 
				
			||||||
 | 
						XMLName xml.Name `xml:"SECRQ"`
 | 
				
			||||||
 | 
						// Only one of the next three should be present
 | 
				
			||||||
 | 
						SecId  SecurityId `xml:"SECID,omitempty"`
 | 
				
			||||||
 | 
						Ticker String     `xml:"TICKER,omitempty"`
 | 
				
			||||||
 | 
						FiId   String     `xml:"FIID,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SecListRequest struct {
 | 
				
			||||||
 | 
						XMLName    xml.Name          `xml:"SECLISTTRNRQ"`
 | 
				
			||||||
 | 
						TrnUID     UID               `xml:"TRNUID"`
 | 
				
			||||||
 | 
						CltCookie  String            `xml:"CLTCOOKIE,omitempty"`
 | 
				
			||||||
 | 
						TAN        String            `xml:"TAN,omitempty"` // Transaction authorization number
 | 
				
			||||||
 | 
						Securities []SecurityRequest `xml:"SECLISTRQ>SECRQ,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *SecListRequest) Name() string {
 | 
				
			||||||
 | 
						return "SECLISTTRNRQ"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *SecListRequest) Valid() (bool, error) {
 | 
				
			||||||
 | 
						if ok, err := r.TrnUID.Valid(); !ok {
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SecListResponse struct {
 | 
				
			||||||
 | 
						XMLName   xml.Name `xml:"SECLISTTRNRS"`
 | 
				
			||||||
 | 
						TrnUID    UID      `xml:"TRNUID"`
 | 
				
			||||||
 | 
						Status    Status   `xml:"STATUS"`
 | 
				
			||||||
 | 
						CltCookie String   `xml:"CLTCOOKIE,omitempty"`
 | 
				
			||||||
 | 
						// SECLISTRS is always empty, so we don't parse it here. The actual securities list will be in a top-level element parallel to SECLISTTRNRS
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r SecListResponse) Name() string {
 | 
				
			||||||
 | 
						return "SECLISTTRNRS"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r SecListResponse) Valid() (bool, error) {
 | 
				
			||||||
 | 
						if ok, err := r.TrnUID.Valid(); !ok {
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Security interface {
 | 
				
			||||||
 | 
						SecurityType() string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SecInfo struct {
 | 
				
			||||||
 | 
						XMLName   xml.Name   `xml:"SECINFO"`
 | 
				
			||||||
 | 
						SecId     SecurityId `xml:"SECID"`
 | 
				
			||||||
 | 
						SecName   String     `xml:"SECNAME"`          // Full name of security
 | 
				
			||||||
 | 
						Ticker    String     `xml:"TICKER,omitempty"` // Ticker symbol
 | 
				
			||||||
 | 
						FiId      String     `xml:"FIID,omitempty"`
 | 
				
			||||||
 | 
						Rating    String     `xml:"RATING,omitempty"`
 | 
				
			||||||
 | 
						UnitPrice Amount     `xml:"UNITPRICE,omitempty"` // Current price, as of DTASOF
 | 
				
			||||||
 | 
						DtAsOf    Date       `xml:"DTASOF,omitempty"`    // Date UNITPRICE was for
 | 
				
			||||||
 | 
						Currency  Currency   `xml:"CURRENCY,omitempty"`  // Overriding currency for UNITPRICE
 | 
				
			||||||
 | 
						Memo      String     `xml:"MEMO,omitempty"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DebtInfo struct {
 | 
				
			||||||
 | 
						XMLName      xml.Name `xml:"DEBTINFO"`
 | 
				
			||||||
 | 
						SecInfo      SecInfo  `xml:"SECINFO"`
 | 
				
			||||||
 | 
						ParValue     Amount   `xml:"PARVALUE"`
 | 
				
			||||||
 | 
						DebtType     String   `xml:"DEBTTYPE"`               // One of COUPON, ZERO (zero coupon)
 | 
				
			||||||
 | 
						DebtClass    String   `xml:"DEBTCLASS,omitempty"`    // One of TREASURY, MUNICIPAL, CORPORATE, OTHER
 | 
				
			||||||
 | 
						CouponRate   Amount   `xml:"COUPONRT,omitempty"`     // Bond coupon rate for next closest call date
 | 
				
			||||||
 | 
						DtCoupon     Date     `xml:"DTCOUPON,omitempty"`     // Maturity date for next coupon
 | 
				
			||||||
 | 
						CouponFreq   String   `xml:"COUPONFREQ,omitempty"`   // When coupons mature - one of MONTHLY, QUARTERLY, SEMIANNUAL, ANNUAL, or OTHER
 | 
				
			||||||
 | 
						CallPrice    Amount   `xml:"CALLPRICE,omitempty"`    // Bond call price
 | 
				
			||||||
 | 
						YieldToCall  Amount   `xml:"YIELDTOCALL,omitempty"`  // Yield to next call
 | 
				
			||||||
 | 
						DtCall       Date     `xml:"DTCALL,omitempty"`       // Next call date
 | 
				
			||||||
 | 
						CallType     String   `xml:"CALLTYPE,omitempt"`      // Type of next call. One of CALL, PUT, PREFUND, MATURITY
 | 
				
			||||||
 | 
						YieldToMat   Amount   `xml:"YIELDTOMAT,omitempty"`   // Yield to maturity
 | 
				
			||||||
 | 
						DtMat        Date     `xml:"DTMAT,omitempty"`        // Debt maturity date
 | 
				
			||||||
 | 
						AssetClass   String   `xml:"ASSETCLASS,omitempty"`   // One of DOMESTICBOND, INTLBOND, LARGESTOCK, SMALLSTOCK, INTLSTOCK, MONEYMRKT, OTHER
 | 
				
			||||||
 | 
						FiAssetClass String   `xml:"FIASSETCLASS,omitempty"` // FI-defined asset class
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (i DebtInfo) SecurityType() string {
 | 
				
			||||||
 | 
						return "DEBTINFO"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type AssetPortion struct {
 | 
				
			||||||
 | 
						XMLName    xml.Name `xml:"PORTION"`
 | 
				
			||||||
 | 
						AssetClass String   `xml:"ASSETCLASS"` // One of DOMESTICBOND, INTLBOND, LARGESTOCK, SMALLSTOCK, INTLSTOCK, MONEYMRKT, OTHER
 | 
				
			||||||
 | 
						Percent    Amount   `xml:"PERCENT"`    // Percentage of the fund that falls under this asset class
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FiAssetPortion struct {
 | 
				
			||||||
 | 
						XMLName      xml.Name `xml:"FIPORTION"`
 | 
				
			||||||
 | 
						FiAssetClass String   `xml:"FIASSETCLASS,omitempty"` // FI-defined asset class
 | 
				
			||||||
 | 
						Percent      Amount   `xml:"PERCENT"`                // Percentage of the fund that falls under this asset class
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type MFInfo struct {
 | 
				
			||||||
 | 
						XMLName        xml.Name         `xml:"MFINFO"`
 | 
				
			||||||
 | 
						SecInfo        SecInfo          `xml:"SECINFO"`
 | 
				
			||||||
 | 
						MfType         String           `xml:"MFTYPE"`                // One of OPEN, END, CLOSEEND, OTHER
 | 
				
			||||||
 | 
						Yield          Amount           `xml:"YIELD,omitempty"`       // Current yield reported as the dividend expressed as a portion of the current stock price
 | 
				
			||||||
 | 
						DtYieldAsOf    Date             `xml:"DTYIELDASOF,omitempty"` // Date YIELD is valid for
 | 
				
			||||||
 | 
						AssetClasses   []AssetPortion   `xml:"MFASSETCLASS>PORTION"`
 | 
				
			||||||
 | 
						FiAssetClasses []FiAssetPortion `xml:"FIMFASSETCLASS>FIPORTION"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (i MFInfo) SecurityType() string {
 | 
				
			||||||
 | 
						return "MFINFO"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type OptInfo struct {
 | 
				
			||||||
 | 
						XMLName      xml.Name   `xml:"OPTINFO"`
 | 
				
			||||||
 | 
						SecInfo      SecInfo    `xml:"SECINFO"`
 | 
				
			||||||
 | 
						OptType      String     `xml:"OPTTYPE"` // One of PUT, CALL
 | 
				
			||||||
 | 
						StrikePrice  Amount     `xml:"STRIKEPRICE"`
 | 
				
			||||||
 | 
						DtExpire     Date       `xml"DTEXPIRE"`                // Expiration date
 | 
				
			||||||
 | 
						ShPerCtrct   Int        `xml:"SHPERCTRCT"`             // Shares per contract
 | 
				
			||||||
 | 
						SecId        SecurityId `xml:"SECID,omitempty"`        // Security ID of the underlying security
 | 
				
			||||||
 | 
						AssetClass   String     `xml:"ASSETCLASS,omitempty"`   // One of DOMESTICBOND, INTLBOND, LARGESTOCK, SMALLSTOCK, INTLSTOCK, MONEYMRKT, OTHER
 | 
				
			||||||
 | 
						FiAssetClass String     `xml:"FIASSETCLASS,omitempty"` // FI-defined asset class
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (i OptInfo) SecurityType() string {
 | 
				
			||||||
 | 
						return "OPTINFO"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type OtherInfo struct {
 | 
				
			||||||
 | 
						XMLName      xml.Name `xml:"OTHERINFO"`
 | 
				
			||||||
 | 
						SecInfo      SecInfo  `xml:"SECINFO"`
 | 
				
			||||||
 | 
						TypeDesc     String   `xml:"TYPEDESC,omitempty"`     // Description of security type
 | 
				
			||||||
 | 
						AssetClass   String   `xml:"ASSETCLASS,omitempty"`   // One of DOMESTICBOND, INTLBOND, LARGESTOCK, SMALLSTOCK, INTLSTOCK, MONEYMRKT, OTHER
 | 
				
			||||||
 | 
						FiAssetClass String   `xml:"FIASSETCLASS,omitempty"` // FI-defined asset class
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (i OtherInfo) SecurityType() string {
 | 
				
			||||||
 | 
						return "OTHERINFO"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type StockInfo struct {
 | 
				
			||||||
 | 
						XMLName      xml.Name `xml:"STOCKINFO"`
 | 
				
			||||||
 | 
						SecInfo      SecInfo  `xml:"SECINFO"`
 | 
				
			||||||
 | 
						StockType    String   `xml:"STOCKTYPE,omitempty"`    // One of COMMON, PREFERRED, CONVERTIBLE, OTHER
 | 
				
			||||||
 | 
						Yield        Amount   `xml:"YIELD,omitempty"`        // Current yield reported as the dividend expressed as a portion of the current stock price
 | 
				
			||||||
 | 
						DtYieldAsOf  Date     `xml:"DTYIELDASOF,omitempty"`  // Date YIELD is valid for
 | 
				
			||||||
 | 
						AssetClass   String   `xml:"ASSETCLASS,omitempty"`   // One of DOMESTICBOND, INTLBOND, LARGESTOCK, SMALLSTOCK, INTLSTOCK, MONEYMRKT, OTHER
 | 
				
			||||||
 | 
						FiAssetClass String   `xml:"FIASSETCLASS,omitempty"` // FI-defined asset class
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (i StockInfo) SecurityType() string {
 | 
				
			||||||
 | 
						return "STOCKINFO"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SecurityList struct {
 | 
				
			||||||
 | 
						Securities []Security
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r SecurityList) Name() string {
 | 
				
			||||||
 | 
						return "SECLIST"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r SecurityList) Valid() (bool, error) {
 | 
				
			||||||
 | 
						// TODO implement
 | 
				
			||||||
 | 
						return true, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *SecurityList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							tok, err := nextNonWhitespaceToken(d)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							} else if end, ok := tok.(xml.EndElement); ok && end.Name.Local == start.Name.Local {
 | 
				
			||||||
 | 
								// If we found the end of our starting element, we're done parsing
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							} else if startElement, ok := tok.(xml.StartElement); ok {
 | 
				
			||||||
 | 
								switch startElement.Name.Local {
 | 
				
			||||||
 | 
								case "DEBTINFO":
 | 
				
			||||||
 | 
									var info DebtInfo
 | 
				
			||||||
 | 
									if err := d.DecodeElement(&info, &startElement); err != nil {
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									r.Securities = append(r.Securities, Security(info))
 | 
				
			||||||
 | 
								case "MFINFO":
 | 
				
			||||||
 | 
									var info MFInfo
 | 
				
			||||||
 | 
									if err := d.DecodeElement(&info, &startElement); err != nil {
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									r.Securities = append(r.Securities, Security(info))
 | 
				
			||||||
 | 
								case "OPTINFO":
 | 
				
			||||||
 | 
									var info OptInfo
 | 
				
			||||||
 | 
									if err := d.DecodeElement(&info, &startElement); err != nil {
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									r.Securities = append(r.Securities, Security(info))
 | 
				
			||||||
 | 
								case "OTHERINFO":
 | 
				
			||||||
 | 
									var info OtherInfo
 | 
				
			||||||
 | 
									if err := d.DecodeElement(&info, &startElement); err != nil {
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									r.Securities = append(r.Securities, Security(info))
 | 
				
			||||||
 | 
								case "STOCKINFO":
 | 
				
			||||||
 | 
									var info StockInfo
 | 
				
			||||||
 | 
									if err := d.DecodeElement(&info, &startElement); err != nil {
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									r.Securities = append(r.Securities, Security(info))
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									return errors.New("Invalid SECLIST child tag: " + startElement.Name.Local)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return errors.New("Didn't find an opening element")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DecodeSecuritiesMessageSet(d *xml.Decoder, start xml.StartElement) ([]Message, error) {
 | 
				
			||||||
 | 
						var msgs []Message
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							tok, err := nextNonWhitespaceToken(d)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							} else if end, ok := tok.(xml.EndElement); ok && end.Name.Local == start.Name.Local {
 | 
				
			||||||
 | 
								// If we found the end of our starting element, we're done parsing
 | 
				
			||||||
 | 
								return msgs, nil
 | 
				
			||||||
 | 
							} else if startElement, ok := tok.(xml.StartElement); ok {
 | 
				
			||||||
 | 
								switch startElement.Name.Local {
 | 
				
			||||||
 | 
								case "SECLISTTRNRS":
 | 
				
			||||||
 | 
									var info SecListResponse
 | 
				
			||||||
 | 
									if err := d.DecodeElement(&info, &startElement); err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									msgs = append(msgs, Message(info))
 | 
				
			||||||
 | 
								case "SECLIST":
 | 
				
			||||||
 | 
									var info SecurityList
 | 
				
			||||||
 | 
									if err := d.DecodeElement(&info, &startElement); err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									msgs = append(msgs, Message(info))
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									return nil, errors.New("Unsupported securities response tag: " + startElement.Name.Local)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return nil, errors.New("Didn't find an opening element")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user