ofxgo

package module
v0.1.1-0...-d1cb82f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 26, 2019 License: GPL-2.0 Imports: 17 Imported by: 1

README

OFXGo

Go Report Card Build Status Coverage Status GoDoc

OFXGo is a library for querying OFX servers and/or parsing the responses. It also provides an example command-line client to demonstrate the use of the library.

Goals

The main purpose of this project is to provide a library to make it easier to query financial information with OFX from the comfort of Golang, without having to marshal/unmarshal to SGML or XML. The library does not intend to abstract away all of the details of the OFX specification, which would be difficult to do well. Instead, it exposes the OFX SGML/XML hierarchy as structs which mostly resemble it. Its primary goal is to enable the creation of other personal finance software in Go (as it was created to allow me to fetch OFX transactions for my own project, MoneyGo).

Because the OFX specification is rather... 'comprehensive,' it can be difficult for those unfamiliar with it to figure out where to start. To that end, I have created a sample command-line client which uses the library to do simple tasks (currently it does little more than list accounts and query for balances and transactions). My hope is that by studying its code, new users will be able to figure out how to use the library much faster than staring at the OFX specification (or this library's API documentation). The command-line client also serves as an easy way for me to test/debug the library with actual financial institutions, which frequently have 'quirks' in their implementations. The command-line client can be found in the cmd/ofx directory of this repository.

Library documentation

Documentation can be found with the go doc tool, or at https://godoc.org/github.com/aclindsa/ofxgo

Example Usage

The following code snippet demonstrates how to use OFXGo to query and parse OFX code from a checking account, printing the balance and returned transactions:

client := ofxgo.BasicClient{} // Accept the default Client settings

// These values are specific to your bank
var query ofxgo.Request
query.URL = "https://secu.example.com/ofx"
query.Signon.Org = ofxgo.String("SECU")
query.Signon.Fid = ofxgo.String("1234")

// Set your username/password
query.Signon.UserID = ofxgo.String("username")
query.Signon.UserPass = ofxgo.String("hunter2")

uid, _ := ofxgo.RandomUID() // Handle error in real code
query.Bank = append(query.Bank, &ofxgo.StatementRequest{
	TrnUID: *uid,
	BankAcctFrom: ofxgo.BankAcct{
		BankID:   ofxgo.String("123456789"),   // Possibly your routing number
		AcctID:   ofxgo.String("00011122233"), // Possibly your account number
		AcctType: ofxgo.AcctTypeChecking,
	},
	Include: true, // Include transactions (instead of only balance information)
})

response, _ := client.Request(&query) // Handle error in real code

// Was there an OFX error while processing our request?
if response.Signon.Status.Code != 0 {
	meaning, _ := response.Signon.Status.CodeMeaning()
	fmt.Printf("Nonzero signon status (%d: %s) with message: %s\n", response.Signon.Status.Code, meaning, response.Signon.Status.Message)
	os.Exit(1)
}

if len(response.Bank) < 1 {
	fmt.Println("No banking messages received")
	os.Exit(1)
}

if stmt, ok := response.Bank[0].(*ofxgo.StatementResponse); ok {
	fmt.Printf("Balance: %s %s (as of %s)\n", stmt.BalAmt, stmt.CurDef, stmt.DtAsOf)
	fmt.Println("Transactions:")
	for _, tran := range stmt.BankTranList.Transactions {
		currency := stmt.CurDef
		if ok, _ := tran.Currency.Valid(); ok {
			currency = tran.Currency.CurSym
		}
		fmt.Printf("%s %-15s %-11s %s%s%s\n", tran.DtPosted, tran.TrnAmt.String()+" "+currency.String(), tran.TrnType, tran.Name, tran.Payee.Name, tran.Memo)
	}
}

Requirements

OFXGo requires go >= 1.9

Using the command-line client

To install the command-line client and test it out, you may do the following:

$ go get -v github.com/aclindsa/ofxgo/cmd/ofx && go install -v github.com/aclindsa/ofxgo/cmd/ofx

Once installed (at ~/go/bin/ofx by default, if you haven't set $GOPATH), the command's usage should help you to use it (./ofx --help for a listing of the available subcommands and their purposes, ./ofx subcommand --help for individual subcommand usage).

Documentation

Overview

Package ofxgo seeks to provide a library to make it easier to query and/or parse financial information with OFX from the comfort of Golang, without having to deal with marshalling/unmarshalling the SGML or XML. The library does *not* intend to abstract away all of the details of the OFX specification, which would be difficult to do well. Instead, it exposes the OFX SGML/XML hierarchy as structs which mostly resemble it. For more information on OFX and to read the specification, see http://ofx.net.

There are three main top-level objects defined in ofxgo. These are Client, Request, and Response. The Request and Response objects represent OFX requests and responses as Golang structs. Client contains settings which control how requests and responses are marshalled and unmarshalled (the OFX version used, client id and version, whether to indent SGML/XML tags, etc.), and provides helper methods for making requests and optionally parsing the response using those settings.

Every Request object contains a SignonRequest element, called Signon. This element contains the username, password (or key), and the ORG and FID fields particular to the financial institution being queried, and an optional ClientUID field (required by some FIs). Likewise, each Response contains a SignonResponse object which contains, among other things, the Status of the request. Any status with a nonzero Code should be inspected for a possible error (using the Severity and Message fields populated by the server, or the CodeMeaning() and CodeConditions() functions which return information about a particular code as specified by the OFX specification).

Each top-level Request or Response object may contain zero or more messages, sorted into named slices by message set, just as the OFX specification groups them. Here are the supported types of Request/Response objects (along with the name of the slice of Messages they belong to in parentheses):

Requests:

var r AcctInfoRequest     // (Signup) Request a list of the valid accounts
                          //   for this user
var r CCStatementRequest  // (CreditCard) Request the balance (and optionally
                          //   list of transactions) for a credit card
var r StatementRequest    // (Bank) Request the balance (and optionally list
                          //   of transactions) for a bank account
var r InvStatementRequest // (InvStmt) Request balance, transactions,
                          //   existing positions, and/or open orders for an
                          //   investment account
var r SecListRequest      // (SecList) Request securities details and prices
var r ProfileRequest      // (Prof) Request the server's capabilities (which
                          //   messages sets it supports, along with features)

Responses:

var r AcctInfoResponse     // (Signup) List of the valid accounts for this
                           //   user
var r CCStatementResponse  // (CreditCard) The balance (and optionally list of
                           //   transactions) for a credit card
var r StatementResponse    // (Bank) The balance (and optionally list of
                           //   transactions) for a bank account
var r InvStatementResponse // (InvStmt) The balance, transactions, existing
                           //   positions, and/or open orders for an
                           //   investment account
var r SecListResponse      // (SecList) Returned as a result of
                           //   SecListRequest, but only contains request
                           //   status
var r SecurityList         // (SecList) The actual list of securities, prices,
                           //   etc. (sent as a result of SecListRequest or
                           //   InvStatementRequest)
var r ProfileResponse      // (Prof) Describes the server's capabilities

When constructing a Request, simply append the desired message to the message set it belongs to. For Responses, it is the user's responsibility to make type assertions on objects found inside one of these message sets before using them.

For example, the following code would request a bank statement for a checking account and print the balance:

import (
  "fmt"
  "github.com/jwaggs/ofxgo"
  "os"
)

var client ofxgo.Client // By not initializing them, we accept all default
                        // client values
var request ofxgo.Request

// These are all specific to you and your financial institution
request.URL = "https://ofx.example.com"
request.Signon.UserID = ofxgo.String("john")
request.Signon.UserPass = ofxgo.String("hunter2")
request.Signon.Org = ofxgo.String("MyBank")
request.Signon.Fid = ofxgo.String("0001")

uid, err := ofxgo.RandomUID()
if err != nil {
  fmt.Println("Error creating uid for transaction:", err)
  os.Exit(1)
}

statementRequest := ofxgo.StatementRequest{
  TrnUID: *uid,
  BankAcctFrom: ofxgo.BankAcct{
    BankID:   ofxgo.String("123456789"),
    AcctID:   ofxgo.String("11111111111"),
    AcctType: ofxgo.AcctTypeChecking,
  },
}

request.Bank = append(request.Bank, &statementRequest)

response, err := client.Request(request)
if err != nil {
  fmt.Println("Error requesting account statement:", err)
  os.Exit(1)
}

if response.Signon.Status.Code != 0 {
  meaning, _ := response.Signon.Status.CodeMeaning()
  fmt.Printf("Nonzero signon status (%d: %s) with message: %s\n", response.Signon.Status.Code, meaning, response.Signon.Status.Message)
  os.Exit(1)
}

if len(response.Bank) < 1 {
  fmt.Println("No banking messages received")
} else if stmt, ok := response.Bank[0].(*ofxgo.StatementResponse); ok {
  fmt.Printf("Balance: %s %s (as of %s)\n", stmt.BalAmt, stmt.CurDef, stmt.DtAsOf)
}

More usage examples may be found in the example command-line client provided with this library, in the cmd/ofx directory of the source.

Index

Constants

View Source
const (
	// Requests
	SignonRq messageType = iota
	SignupRq
	BankRq
	CreditCardRq
	LoanRq
	InvStmtRq
	InterXferRq
	WireXferRq
	BillpayRq
	EmailRq
	SecListRq
	PresDirRq
	PresDlvRq
	ProfRq
	ImageRq

	// Responses
	SignonRs
	SignupRs
	BankRs
	CreditCardRs
	LoanRs
	InvStmtRs
	InterXferRs
	WireXferRs
	BillpayRs
	EmailRs
	SecListRs
	PresDirRs
	PresDlvRs
	ProfRs
	ImageRs
)

These constants are returned by Messages' Type() functions to determine which message set they belong to

View Source
const (
	OfxVersion102 ofxVersion = 1 + iota
	OfxVersion103
	OfxVersion151
	OfxVersion160
	OfxVersion200
	OfxVersion201
	OfxVersion202
	OfxVersion203
	OfxVersion210
	OfxVersion211
	OfxVersion220
)

OfxVersion* constants represent the OFX specification version in use

View Source
const (
	AcctTypeChecking acctType = 1 + iota
	AcctTypeSavings
	AcctTypeMoneyMrkt
	AcctTypeCreditLine
	AcctTypeCD
)

AcctType* constants represent types of bank accounts

View Source
const (
	TrnTypeCredit trnType = 1 + iota
	TrnTypeDebit
	TrnTypeInt
	TrnTypeDiv
	TrnTypeFee
	TrnTypeSrvChg
	TrnTypeDep
	TrnTypeATM
	TrnTypePOS
	TrnTypeXfer
	TrnTypeCheck
	TrnTypePayment
	TrnTypeCash
	TrnTypeDirectDep
	TrnTypeDirectDebit
	TrnTypeRepeatPmt
	TrnTypeHold
	TrnTypeOther
)

TrnType* constants represent types of transactions. INT, ATM, and POS depend on the signage of the account.

View Source
const (
	ImageTypeStatement imageType = 1 + iota
	ImageTypeTransaction
	ImageTypeTax
)

ImageType* constants represent what this image contains

View Source
const (
	ImageRefTypeOpaque imageRefType = 1 + iota
	ImageRefTypeURL
	ImageRefTypeFormURL
)

ImageRefType* constants represent the type of reference to the image

View Source
const (
	CheckSupFrontOnly checkSup = 1 + iota
	CheckSupBackOnly
	CheckSupFrontAndBack
)

CheckSup* constants represent what portions of the check this image contains

View Source
const (
	CorrectActionDelete correctAction = 1 + iota
	CorrectActionReplace
)

CorrectAction* constants represent whether this transaction correction replaces or deletes the transaction matching its CORRECTFITID

View Source
const (
	BalTypeDollar balType = 1 + iota
	BalTypePercent
	BalTypeNumber
)

BalType* constants represent how this BAL's VALUE field should be interpreted

View Source
const (
	Inv401kSourcePreTax inv401kSource = 1 + iota
	Inv401kSourceAfterTax
	Inv401kSourceMatch
	Inv401kSourceProfitSharing
	Inv401kSourceRollover
	Inv401kSourceOtherVest
	Inv401kSourceOtherNonVest
)

Inv401kSource* constants represent the source of money used for this security in a 401(k) account. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST.

View Source
const (
	SubAcctTypeCash subAcctType = 1 + iota
	SubAcctTypeMargin
	SubAcctTypeShort
	SubAcctTypeOther
)

SubAcctType* constants represent the sub-account type for a source and/or destination of a transaction. Used in fields named SubAcctFrom, SubAcctTo, SubAcctSec, SubAcctFund, HeldInAcct.

View Source
const (
	BuyTypeBuy buyType = 1 + iota
	BuyTypeBuyToCover
)

BuyType* constants represent types of purchases

View Source
const (
	OptActionExercise optAction = 1 + iota
	OptActionAssign
	OptActionExpire
)

OptAction* constants represent types of actions for options

View Source
const (
	TferActionIn tferAction = 1 + iota
	TferActionOut
)

TferAction* constants represent whether the transfer is into or out of this account

View Source
const (
	PosTypeLong posType = 1 + iota
	PosTypeShort
)

PosType* constants represent position type

View Source
const (
	SecuredNaked secured = 1 + iota
	SecuredCovered
)

Secured* constants represent how an option is secured

View Source
const (
	DurationDay duration = 1 + iota
	DurationGoodTilCancel
	DurationImmediate
)

Duration* constants represent how long the investment order is good for

View Source
const (
	RestrictionAllOrNone restriction = 1 + iota
	RestrictionMinUnits
	RestrictionNone
)

Restriction* constants represent a special restriction on an investment order

View Source
const (
	UnitTypeShares unitType = 1 + iota
	UnitTypeCurrency
)

UnitType* constants represent type of the UNITS value

View Source
const (
	OptBuyTypeBuyToOpen optBuyType = 1 + iota
	OptBuyTypeBuyToClose
)

OptBuyType* constants represent types of purchases for options

View Source
const (
	SellTypeSell sellType = 1 + iota
	SellTypeSellShort
)

SellType* constants represent types of sales

View Source
const (
	LoanPmtFreqWeekly loanPmtFreq = 1 + iota
	LoanPmtFreqBiweekly
	LoanPmtFreqTwiceMonthly
	LoanPmtFreqMonthly
	LoanPmtFreqFourWeeks
	LoanPmtFreqBiMonthly
	LoanPmtFreqQuarterly
	LoanPmtFreqSemiannually
	LoanPmtFreqAnnually
	LoanPmtFreqOther
)

LoanPmtFreq* constants represent the frequency of loan payments

View Source
const (
	IncomeTypeCGLong incomeType = 1 + iota
	IncomeTypeCGShort
	IncomeTypeDiv
	IncomeTypeInterest
	IncomeTypeMisc
)

IncomeType* constants represent types of investment income

View Source
const (
	SellReasonCall sellReason = 1 + iota
	SellReasonSell
	SellReasonMaturity
)

SellReason* constants represent the reason the sell of a debt security was generated: CALL (the debt was called), SELL (the debt was sold), MATURITY (the debt reached maturity)

View Source
const (
	OptSellTypeSellToClose optSellType = 1 + iota
	OptSellTypeSellToOpen
)

OptSellType* constants represent types of sales for options

View Source
const (
	RelTypeSpread relType = 1 + iota
	RelTypeStraddle
	RelTypeNone
	RelTypeOther
)

RelType* constants represent related option transaction types

View Source
const (
	CharTypeAlphaOnly charType = 1 + iota
	CharTypeNumericOnly
	CharTypeAlphaOrNumeric
	CharTypeAlphaAndNumeric
)

CharType* constants represent types of characters allowed in password

View Source
const (
	SyncModeFull syncMode = 1 + iota
	SyncModeLite
)

SyncMode* constants represent data synchronization mode supported (see OFX spec for more details)

View Source
const (
	OfxSecNone ofxSec = 1 + iota
	OfxSecType1
)

OfxSec* constants represent the type of application-level security required for the message set

View Source
const (
	DebtTypeCoupon debtType = 1 + iota
	DebtTypeZero
)

DebtType* constants represent debt type

View Source
const (
	DebtClassTreasury debtClass = 1 + iota
	DebtClassMunicipal
	DebtClassCorporate
	DebtClassOther
)

DebtClass* constants represent the class of debt

View Source
const (
	CouponFreqMonthly couponFreq = 1 + iota
	CouponFreqQuarterly
	CouponFreqSemiannual
	CouponFreqAnnual
	CouponFreqOther
)

CouponFreq* constants represent when debt coupons mature

View Source
const (
	CallTypeCall callType = 1 + iota
	CallTypePut
	CallTypePrefund
	CallTypeMaturity
)

CallType* constants represent type of next call (for a debt)

View Source
const (
	AssetClassDomesticBond assetClass = 1 + iota
	AssetClassIntlBond
	AssetClassLargeStock
	AssetClassSmallStock
	AssetClassIntlStock
	AssetClassMoneyMrkt
	AssetClassOther
)

AssetClass* constants represent type of asset classes

View Source
const (
	MfTypeOpenEnd mfType = 1 + iota
	MfTypeCloseEnd
	MfTypeOther
)

MfType* constants represent types of mutual funds

View Source
const (
	OptTypePut optType = 1 + iota
	OptTypeCall
)

OptType* constants represent whether the option is a PUT or a CALL

View Source
const (
	StockTypeCommon stockType = 1 + iota
	StockTypePreferred
	StockTypeConvertible
	StockTypeOther
)

StockType* constants represent types of stock

View Source
const (
	HolderTypeIndividual holderType = 1 + iota
	HolderTypeJoint
	HolderTypeCustodial
	HolderTypeTrust
	HolderTypeOther
)

HolderType* constants represent how the account is held

View Source
const (
	AcctClassificationPersonal acctClassification = 1 + iota
	AcctClassificationBusiness
	AcctClassificationCorporate
	AcctClassificationOther
)

AcctClassification* constants represent the type of an account

View Source
const (
	SvcStatusAvail svcStatus = 1 + iota
	SvcStatusPend
	SvcStatusActive
)

SvcStatus* constants represent the status of the account: AVAIL = Available, but not yet requested, PEND = Requested, but not yet available, ACTIVE = In use

View Source
const (
	UsProductType401K usProductType = 1 + iota
	UsProductType403B
	UsProductTypeIRA
	UsProductTypeKEOGH
	UsProductTypeOther
	UsProductTypeSARSEP
	UsProductTypeSimple
	UsProductTypeNormal
	UsProductTypeTDA
	UsProductTypeTrust
	UsProductTypeUGMA
)

UsProductType* constants represent type of investment account (in the US)

Variables

This section is empty.

Functions

func NewAcctClassification

func NewAcctClassification(s string) (acctClassification, error)

NewAcctClassification returns returns an 'enum' value of type acctClassification given its string representation

func NewAcctType

func NewAcctType(s string) (acctType, error)

NewAcctType returns returns an 'enum' value of type acctType given its string representation

func NewAssetClass

func NewAssetClass(s string) (assetClass, error)

NewAssetClass returns returns an 'enum' value of type assetClass given its string representation

func NewBalType

func NewBalType(s string) (balType, error)

NewBalType returns returns an 'enum' value of type balType given its string representation

func NewBuyType

func NewBuyType(s string) (buyType, error)

NewBuyType returns returns an 'enum' value of type buyType given its string representation

func NewCallType

func NewCallType(s string) (callType, error)

NewCallType returns returns an 'enum' value of type callType given its string representation

func NewCharType

func NewCharType(s string) (charType, error)

NewCharType returns returns an 'enum' value of type charType given its string representation

func NewCheckSup

func NewCheckSup(s string) (checkSup, error)

NewCheckSup returns returns an 'enum' value of type checkSup given its string representation

func NewCorrectAction

func NewCorrectAction(s string) (correctAction, error)

NewCorrectAction returns returns an 'enum' value of type correctAction given its string representation

func NewCouponFreq

func NewCouponFreq(s string) (couponFreq, error)

NewCouponFreq returns returns an 'enum' value of type couponFreq given its string representation

func NewDebtClass

func NewDebtClass(s string) (debtClass, error)

NewDebtClass returns returns an 'enum' value of type debtClass given its string representation

func NewDebtType

func NewDebtType(s string) (debtType, error)

NewDebtType returns returns an 'enum' value of type debtType given its string representation

func NewDuration

func NewDuration(s string) (duration, error)

NewDuration returns returns an 'enum' value of type duration given its string representation

func NewHolderType

func NewHolderType(s string) (holderType, error)

NewHolderType returns returns an 'enum' value of type holderType given its string representation

func NewImageRefType

func NewImageRefType(s string) (imageRefType, error)

NewImageRefType returns returns an 'enum' value of type imageRefType given its string representation

func NewImageType

func NewImageType(s string) (imageType, error)

NewImageType returns returns an 'enum' value of type imageType given its string representation

func NewIncomeType

func NewIncomeType(s string) (incomeType, error)

NewIncomeType returns returns an 'enum' value of type incomeType given its string representation

func NewInv401kSource

func NewInv401kSource(s string) (inv401kSource, error)

NewInv401kSource returns returns an 'enum' value of type inv401kSource given its string representation

func NewLoanPmtFreq

func NewLoanPmtFreq(s string) (loanPmtFreq, error)

NewLoanPmtFreq returns returns an 'enum' value of type loanPmtFreq given its string representation

func NewMfType

func NewMfType(s string) (mfType, error)

NewMfType returns returns an 'enum' value of type mfType given its string representation

func NewOfxSec

func NewOfxSec(s string) (ofxSec, error)

NewOfxSec returns returns an 'enum' value of type ofxSec given its string representation

func NewOfxVersion

func NewOfxVersion(s string) (ofxVersion, error)

NewOfxVersion returns returns an 'enum' value of type ofxVersion given its string representation

func NewOptAction

func NewOptAction(s string) (optAction, error)

NewOptAction returns returns an 'enum' value of type optAction given its string representation

func NewOptBuyType

func NewOptBuyType(s string) (optBuyType, error)

NewOptBuyType returns returns an 'enum' value of type optBuyType given its string representation

func NewOptSellType

func NewOptSellType(s string) (optSellType, error)

NewOptSellType returns returns an 'enum' value of type optSellType given its string representation

func NewOptType

func NewOptType(s string) (optType, error)

NewOptType returns returns an 'enum' value of type optType given its string representation

func NewPosType

func NewPosType(s string) (posType, error)

NewPosType returns returns an 'enum' value of type posType given its string representation

func NewRelType

func NewRelType(s string) (relType, error)

NewRelType returns returns an 'enum' value of type relType given its string representation

func NewRestriction

func NewRestriction(s string) (restriction, error)

NewRestriction returns returns an 'enum' value of type restriction given its string representation

func NewSecured

func NewSecured(s string) (secured, error)

NewSecured returns returns an 'enum' value of type secured given its string representation

func NewSellReason

func NewSellReason(s string) (sellReason, error)

NewSellReason returns returns an 'enum' value of type sellReason given its string representation

func NewSellType

func NewSellType(s string) (sellType, error)

NewSellType returns returns an 'enum' value of type sellType given its string representation

func NewStockType

func NewStockType(s string) (stockType, error)

NewStockType returns returns an 'enum' value of type stockType given its string representation

func NewSubAcctType

func NewSubAcctType(s string) (subAcctType, error)

NewSubAcctType returns returns an 'enum' value of type subAcctType given its string representation

func NewSvcStatus

func NewSvcStatus(s string) (svcStatus, error)

NewSvcStatus returns returns an 'enum' value of type svcStatus given its string representation

func NewSyncMode

func NewSyncMode(s string) (syncMode, error)

NewSyncMode returns returns an 'enum' value of type syncMode given its string representation

func NewTferAction

func NewTferAction(s string) (tferAction, error)

NewTferAction returns returns an 'enum' value of type tferAction given its string representation

func NewTrnType

func NewTrnType(s string) (trnType, error)

NewTrnType returns returns an 'enum' value of type trnType given its string representation

func NewUnitType

func NewUnitType(s string) (unitType, error)

NewUnitType returns returns an 'enum' value of type unitType given its string representation

func NewUsProductType

func NewUsProductType(s string) (usProductType, error)

NewUsProductType returns returns an 'enum' value of type usProductType given its string representation

Types

type AcctInfo

type AcctInfo struct {
	XMLName         xml.Name   `xml:"ACCTINFO"`
	Name            String     `xml:"NAME,omitempty"`
	Desc            String     `xml:"DESC,omitempty"`
	Phone           String     `xml:"PHONE,omitempty"`
	PrimaryHolder   HolderInfo `xml:"HOLDERINFO>PRIMARYHOLDER,omitempty"`
	SecondaryHolder HolderInfo `xml:"HOLDERINFO>SECONDARYHOLDER,omitempty"`

	// Only one of the rest of the fields will be valid for any given AcctInfo
	BankAcctInfo *BankAcctInfo `xml:"BANKACCTINFO,omitempty"`
	CCAcctInfo   *CCAcctInfo   `xml:"CCACCTINFO,omitempty"`
	InvAcctInfo  *InvAcctInfo  `xml:"INVACCTINFO,omitempty"`
}

AcctInfo represents generic account information. It should contain one (and only one) *AcctInfo element corresponding to the tyep of account it represents.

type AcctInfoRequest

type AcctInfoRequest struct {
	XMLName   xml.Name `xml:"ACCTINFOTRNRQ"`
	TrnUID    UID      `xml:"TRNUID"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	TAN       String   `xml:"TAN,omitempty"` // Transaction authorization number
	// TODO `xml:"OFXEXTENSION,omitempty"`
	DtAcctUp Date `xml:"ACCTINFORQ>DTACCTUP"`
}

AcctInfoRequest represents a request for the server to provide information for all of the user's available accounts at this FI

func (*AcctInfoRequest) Name

func (r *AcctInfoRequest) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*AcctInfoRequest) Type

func (r *AcctInfoRequest) Type() messageType

Type returns which message set this message belongs to (which Request element of type []Message it should appended to)

func (*AcctInfoRequest) Valid

func (r *AcctInfoRequest) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct would be valid OFX if marshalled into XML/SGML

type AcctInfoResponse

type AcctInfoResponse struct {
	XMLName   xml.Name `xml:"ACCTINFOTRNRS"`
	TrnUID    UID      `xml:"TRNUID"`
	Status    Status   `xml:"STATUS"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	// TODO `xml:"OFXEXTENSION,omitempty"`
	DtAcctUp Date       `xml:"ACCTINFORS>DTACCTUP"`
	AcctInfo []AcctInfo `xml:"ACCTINFORS>ACCTINFO,omitempty"`
}

AcctInfoResponse contains the information about all a user's accounts accessible from this FI

func (*AcctInfoResponse) Name

func (air *AcctInfoResponse) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*AcctInfoResponse) Type

func (air *AcctInfoResponse) Type() messageType

Type returns which message set this message belongs to (which Response element of type []Message it belongs to)

func (*AcctInfoResponse) Valid

func (air *AcctInfoResponse) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct was valid OFX when unmarshalled

type Amount

type Amount struct {
	big.Rat
}

Amount represents non-integer values (or at least values for fields that may not necessarily be integers)

func (Amount) Equal

func (a Amount) Equal(o Amount) bool

Equal returns true if two Amounts are equal in value

func (*Amount) MarshalXML

func (a *Amount) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML marshals an Amount to SGML/XML

func (Amount) String

func (a Amount) String() string

String prints a string representation of an Amount

func (*Amount) UnmarshalXML

func (a *Amount) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling an Amount from an SGML/XML string. Leading and trailing whitespace is ignored.

type AssetPortion

type AssetPortion struct {
	XMLName    xml.Name   `xml:"PORTION"`
	AssetClass assetClass `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
}

AssetPortion represents the percentage of a mutual fund with the given asset classification

type Balance

type Balance struct {
	XMLName xml.Name `xml:"BAL"`
	Name    String   `xml:"NAME"`
	Desc    String   `xml:"DESC"`

	// Balance type:
	// DOLLAR = dollar (value formatted DDDD.cc)
	// PERCENT = percentage (value formatted XXXX.YYYY)
	// NUMBER = number (value formatted as is)
	BalType balType `xml:"BALTYPE"`

	Value    Amount    `xml:"VALUE"`
	DtAsOf   *Date     `xml:"DTASOF,omitempty"`
	Currency *Currency `xml:"CURRENCY,omitempty"` // if BALTYPE is DOLLAR
}

Balance represents a generic (free-form) balance defined by an FI.

func (Balance) Valid

func (b Balance) Valid() (bool, error)

Valid returns (true, nil) if this struct is valid OFX

type BankAcct

type BankAcct struct {
	XMLName  xml.Name // BANKACCTTO or BANKACCTFROM
	BankID   String   `xml:"BANKID"`
	BranchID String   `xml:"BRANCHID,omitempty"` // Unused in USA
	AcctID   String   `xml:"ACCTID"`
	AcctType acctType `xml:"ACCTTYPE"`          // One of CHECKING, SAVINGS, MONEYMRKT, CREDITLINE, CD
	AcctKey  String   `xml:"ACCTKEY,omitempty"` // Unused in USA
}

BankAcct represents the identifying information for one bank account

func (BankAcct) Valid

func (b BankAcct) Valid() (bool, error)

Valid returns whether the BankAcct is valid according to the OFX spec

type BankAcctInfo

type BankAcctInfo struct {
	XMLName            xml.Name           `xml:"BANKACCTINFO"`
	BankAcctFrom       BankAcct           `xml:"BANKACCTFROM"`
	SupTxDl            Boolean            `xml:"SUPTXDL"`                      // Supports downloading transactions (as opposed to balance only)
	XferSrc            Boolean            `xml:"XFERSRC"`                      // Enabled as source for intra/interbank transfer
	XferDest           Boolean            `xml:"XFERDEST"`                     // Enabled as destination for intra/interbank transfer
	MaturityDate       Date               `xml:"MATURITYDATE,omitempty"`       // Maturity date for CD, if CD
	MaturityAmt        Amount             `xml:"MATURITYAMOUNT,omitempty"`     // Maturity amount for CD, if CD
	MinBalReq          Amount             `xml:"MINBALREQ,omitempty"`          // Minimum balance required to avoid service fees
	AcctClassification acctClassification `xml:"ACCTCLASSIFICATION,omitempty"` // One of PERSONAL, BUSINESS, CORPORATE, OTHER
	OverdraftLimit     Amount             `xml:"OVERDRAFTLIMIT,omitempty"`
	SvcStatus          svcStatus          `xml:"SVCSTATUS"` // One of AVAIL (available, but not yet requested), PEND (requested, but not yet available), ACTIVE
}

BankAcctInfo contains information about a bank account, including how to access it (BankAcct), and whether it supports downloading transactions (SupTxDl).

func (*BankAcctInfo) String

func (bai *BankAcctInfo) String() string

String makes pointers to BankAcctInfo structs print nicely

type BasicClient

type BasicClient struct {
	// Request fields to overwrite with the client's values. If nonempty,
	// defaults are used
	SpecVersion ofxVersion // VERSION in header
	AppID       string     // SONRQ>APPID
	AppVer      string     // SONRQ>APPVER

	// Don't insert newlines or indentation when marshalling to SGML/XML
	NoIndent bool
	// Use carriage returns on new lines
	CarriageReturn bool
}

BasicClient provides a standard Client implementation suitable for most financial institutions. BasicClient uses default, non-zero settings, even if its fields are not initialized.

func (*BasicClient) CarriageReturnNewLines

func (c *BasicClient) CarriageReturnNewLines() bool

CarriageReturnNewLines returns true if carriage returns should be used on new lines, false otherwise

func (*BasicClient) ID

func (c *BasicClient) ID() String

ID returns this BasicClient's OFX AppID field, defaulting to "OFXGO" if unspecified.

func (*BasicClient) IndentRequests

func (c *BasicClient) IndentRequests() bool

IndentRequests returns true if the marshaled XML should be indented (and contain newlines, since the two are linked in the current implementation)

func (*BasicClient) OfxVersion

func (c *BasicClient) OfxVersion() ofxVersion

OfxVersion returns the OFX specification version this BasicClient will marshal Requests as. Defaults to "203" if the client's SpecVersion field is empty.

func (*BasicClient) RawRequest

func (c *BasicClient) RawRequest(URL string, r io.Reader) (*http.Response, error)

func (*BasicClient) Request

func (c *BasicClient) Request(r *Request) (*Response, error)

func (*BasicClient) RequestNoParse

func (c *BasicClient) RequestNoParse(r *Request) (*http.Response, error)

func (*BasicClient) Version

func (c *BasicClient) Version() String

Version returns this BasicClient's version number as a string, defaulting to "0001" if unspecified.

type Boolean

type Boolean bool

Boolean provides helper methods to unmarshal bool values from OFX SGML/XML

func (Boolean) Equal

func (ob Boolean) Equal(o Boolean) bool

Equal returns true if the two Booleans are the same

func (*Boolean) MarshalXML

func (ob *Boolean) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML marshals a Boolean to XML

func (*Boolean) String

func (ob *Boolean) String() string

String returns a string representation of a Boolean value

func (*Boolean) UnmarshalXML

func (ob *Boolean) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling a Boolean from an SGML/XML string. Leading and trailing whitespace is ignored.

type BuyDebt

type BuyDebt struct {
	XMLName  xml.Name `xml:"BUYDEBT"`
	InvBuy   InvBuy   `xml:"INVBUY"`
	AccrdInt Amount   `xml:"ACCRDINT,omitempty"` // Accrued interest. This amount is not reflected in the <TOTAL> field of a containing aggregate.
}

BuyDebt represents a transaction purchasing a debt security

func (BuyDebt) TransactionType

func (t BuyDebt) TransactionType() string

TransactionType returns a string representation of this transaction's type

type BuyMF

type BuyMF struct {
	XMLName  xml.Name `xml:"BUYMF"`
	InvBuy   InvBuy   `xml:"INVBUY"`
	BuyType  buyType  `xml:"BUYTYPE"`            // One of BUY, BUYTOCOVER (BUYTOCOVER used to close short sales.)
	RelFiTID String   `xml:"RELFITID,omitempty"` // used to relate transactions associated with mutual fund exchanges
}

BuyMF represents a transaction purchasing a mutual fund

func (BuyMF) TransactionType

func (t BuyMF) TransactionType() string

TransactionType returns a string representation of this transaction's type

type BuyOpt

type BuyOpt struct {
	XMLName    xml.Name   `xml:"BUYOPT"`
	InvBuy     InvBuy     `xml:"INVBUY"`
	OptBuyType optBuyType `xml:"OPTBUYTYPE"` // type of purchase: BUYTOOPEN, BUYTOCLOSE (The BUYTOOPEN buy type is like “ordinary” buying of option and works like stocks.)
	ShPerCtrct Int        `xml:"SHPERCTRCT"` // Shares per contract
}

BuyOpt represents a transaction purchasing an option

func (BuyOpt) TransactionType

func (t BuyOpt) TransactionType() string

TransactionType returns a string representation of this transaction's type

type BuyOther

type BuyOther struct {
	XMLName xml.Name `xml:"BUYOTHER"`
	InvBuy  InvBuy   `xml:"INVBUY"`
}

BuyOther represents a transaction purchasing a type of security not covered by the other Buy* structs

func (BuyOther) TransactionType

func (t BuyOther) TransactionType() string

TransactionType returns a string representation of this transaction's type

type BuyStock

type BuyStock struct {
	XMLName xml.Name `xml:"BUYSTOCK"`
	InvBuy  InvBuy   `xml:"INVBUY"`
	BuyType buyType  `xml:"BUYTYPE"` // One of BUY, BUYTOCOVER (BUYTOCOVER used to close short sales.)
}

BuyStock represents a transaction purchasing stock

func (BuyStock) TransactionType

func (t BuyStock) TransactionType() string

TransactionType returns a string representation of this transaction's type

type CCAcct

type CCAcct struct {
	XMLName xml.Name // CCACCTTO or CCACCTFROM
	AcctID  String   `xml:"ACCTID"`
	AcctKey String   `xml:"ACCTKEY,omitempty"` // Unused in USA
}

CCAcct represents the identifying information for one checking account

func (CCAcct) Valid

func (c CCAcct) Valid() (bool, error)

Valid returns whether the CCAcct is valid according to the OFX spec

type CCAcctInfo

type CCAcctInfo struct {
	XMLName            xml.Name           `xml:"CCACCTINFO"`
	CCAcctFrom         CCAcct             `xml:"CCACCTFROM"`
	SupTxDl            Boolean            `xml:"SUPTXDL"`                      // Supports downloading transactions (as opposed to balance only)
	XferSrc            Boolean            `xml:"XFERSRC"`                      // Enabled as source for intra/interbank transfer
	XferDest           Boolean            `xml:"XFERDEST"`                     // Enabled as destination for intra/interbank transfer
	AcctClassification acctClassification `xml:"ACCTCLASSIFICATION,omitempty"` // One of PERSONAL, BUSINESS, CORPORATE, OTHER
	SvcStatus          svcStatus          `xml:"SVCSTATUS"`                    // One of AVAIL (available, but not yet requested), PEND (requested, but not yet available), ACTIVE
}

CCAcctInfo contains information about a credit card account, including how to access it (CCAcct), and whether it supports downloading transactions (SupTxDl).

func (*CCAcctInfo) String

func (ci *CCAcctInfo) String() string

String makes pointers to CCAcctInfo structs print nicely

type CCStatementRequest

type CCStatementRequest struct {
	XMLName   xml.Name `xml:"CCSTMTTRNRQ"`
	TrnUID    UID      `xml:"TRNUID"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	TAN       String   `xml:"TAN,omitempty"`
	// TODO OFXEXTENSION
	CCAcctFrom     CCAcct  `xml:"CCSTMTRQ>CCACCTFROM"`
	DtStart        *Date   `xml:"CCSTMTRQ>INCTRAN>DTSTART,omitempty"`
	DtEnd          *Date   `xml:"CCSTMTRQ>INCTRAN>DTEND,omitempty"`
	Include        Boolean `xml:"CCSTMTRQ>INCTRAN>INCLUDE"`          // Include transactions (instead of just balance)
	IncludePending Boolean `xml:"CCSTMTRQ>INCLUDEPENDING,omitempty"` // Include pending transactions
	IncTranImg     Boolean `xml:"CCSTMTRQ>INCTRANIMG,omitempty"`     // Include transaction images
}

CCStatementRequest represents a request for a credit card statement. It is used to request balances and/or transactions. See StatementRequest for the analog for all other bank accounts.

func (*CCStatementRequest) Name

func (r *CCStatementRequest) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*CCStatementRequest) Type

func (r *CCStatementRequest) Type() messageType

Type returns which message set this message belongs to (which Request element of type []Message it should appended to)

func (*CCStatementRequest) Valid

func (r *CCStatementRequest) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct would be valid OFX if marshalled into XML/SGML

type CCStatementResponse

type CCStatementResponse struct {
	XMLName   xml.Name `xml:"CCSTMTTRNRS"`
	TrnUID    UID      `xml:"TRNUID"`
	Status    Status   `xml:"STATUS"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	// TODO `xml:"OFXEXTENSION,omitempty"`
	CurDef       CurrSymbol       `xml:"CCSTMTRS>CURDEF"`
	CCAcctFrom   CCAcct           `xml:"CCSTMTRS>CCACCTFROM"`
	BankTranList *TransactionList `xml:"CCSTMTRS>BANKTRANLIST,omitempty"`
	//BANKTRANLISTP
	BalAmt        Amount    `xml:"CCSTMTRS>LEDGERBAL>BALAMT"`
	DtAsOf        Date      `xml:"CCSTMTRS>LEDGERBAL>DTASOF"`
	AvailBalAmt   *Amount   `xml:"CCSTMTRS>AVAILBAL>BALAMT,omitempty"`
	AvailDtAsOf   *Date     `xml:"CCSTMTRS>AVAILBAL>DTASOF,omitempty"`
	CashAdvBalAmt Amount    `xml:"CCSTMTRS>CASHADVBALAMT,omitempty"`           // Only for CREDITLINE accounts, available balance for cash advances
	IntRatePurch  Amount    `xml:"CCSTMTRS>INTRATEPURCH,omitempty"`            // Current interest rate for purchases
	IntRateCash   Amount    `xml:"CCSTMTRS>INTRATECASH,omitempty"`             // Current interest rate for cash advances
	IntRateXfer   Amount    `xml:"CCSTMTRS>INTRATEXFER,omitempty"`             // Current interest rate for cash advances
	RewardName    String    `xml:"CCSTMTRS>REWARDINFO>NAME,omitempty"`         // Name of the reward program referred to by the next two elements
	RewardBal     Amount    `xml:"CCSTMTRS>REWARDINFO>REWARDBAL,omitempty"`    // Current balance of the reward program
	RewardEarned  Amount    `xml:"CCSTMTRS>REWARDINFO>REWARDEARNED,omitempty"` // Reward amount earned YTD
	BalList       []Balance `xml:"CCSTMTRS>BALLIST>BAL,omitempty"`
	MktgInfo      String    `xml:"CCSTMTRS>MKTGINFO,omitempty"` // Marketing information
}

CCStatementResponse represents a credit card statement, including its balances and possibly transactions. It is a response to CCStatementRequest, or sometimes provided as part of an OFX file downloaded manually from an FI.

func (*CCStatementResponse) Name

func (sr *CCStatementResponse) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*CCStatementResponse) Type

func (sr *CCStatementResponse) Type() messageType

Type returns which message set this message belongs to (which Response element of type []Message it belongs to)

func (*CCStatementResponse) Valid

func (sr *CCStatementResponse) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct was valid OFX when unmarshalled

type Client

type Client interface {
	// Used to fill out a Request object
	OfxVersion() ofxVersion
	ID() String
	Version() String
	IndentRequests() bool
	CarriageReturnNewLines() bool

	// Request marshals a Request object into XML, makes an HTTP request
	// against it's URL, and then unmarshals the response into a Response
	// object.
	//
	// Before being marshaled, some of the the Request object's values are
	// overwritten, namely those dictated by the BasicClient's configuration
	// (Version, AppID, AppVer fields), and the client's current time
	// (DtClient). These are updated in place in the supplied Request object so
	// they may later be inspected by the caller.
	Request(r *Request) (*Response, error)

	// RequestNoParse marshals a Request object into XML, makes an HTTP
	// request, and returns the raw HTTP response. Unlike RawRequest(), it
	// takes client settings into account. Unlike Request(), it doesn't parse
	// the response into  an ofxgo.Request object.
	//
	// Caveat: The caller is responsible for closing the http Response.Body
	// (see the http module's documentation for more information)
	RequestNoParse(r *Request) (*http.Response, error)

	// RawRequest is little more than a thin wrapper around http.Post
	//
	// In most cases, you should probably be using Request() instead, but
	// RawRequest can be useful if you need to read the raw unparsed http
	// response yourself (perhaps for downloading an OFX file for use by an
	// external program, or debugging server behavior), or have a handcrafted
	// request you'd like to try.
	//
	// Caveats: RawRequest does *not* take client settings into account as
	// Client.Request() does, so your particular server may or may not like
	// whatever we read from 'r'. The caller is responsible for closing the
	// http Response.Body (see the http module's documentation for more
	// information)
	RawRequest(URL string, r io.Reader) (*http.Response, error)
}

Client serves to aggregate OFX client settings that may be necessary to talk to a particular server due to quirks in that server's implementation. Client also provides the Request and RequestNoParse helper methods to aid in making and parsing requests.

func GetClient

func GetClient(URL string, bc *BasicClient) Client

GetClient returns a new Client for a given URL. It attempts to find a specialized client for this URL, but simply returns the passed-in BasicClient if no such match is found.

func NewDiscoverCardClient

func NewDiscoverCardClient(bc *BasicClient) Client

NewDiscoverCardClient returns a Client interface configured to handle Discover Card's brand of idiosyncracy

func NewVanguardClient

func NewVanguardClient(bc *BasicClient) Client

NewVanguardClient returns a Client interface configured to handle Vanguard's brand of idiosyncracy

type ClosureOpt

type ClosureOpt struct {
	XMLName    xml.Name    `xml:"CLOSUREOPT"`
	InvTran    InvTran     `xml:"INVTRAN"`
	SecID      SecurityID  `xml:"SECID"`
	OptAction  optAction   `xml:"OPTACTION"`          // One of EXERCISE, ASSIGN, EXPIRE. The EXERCISE action is used to close out an option that is exercised. The ASSIGN action is used when an option writer is assigned. The EXPIRE action is used when the option’s expired date is reached
	Units      Amount      `xml:"UNITS"`              // For stocks, MFs, other, number of shares held. Bonds = face value. Options = number of contracts
	ShPerCtrct Int         `xml:"SHPERCTRCT"`         // Shares per contract
	SubAcctSec subAcctType `xml:"SUBACCTSEC"`         // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
	RelFiTID   String      `xml:"RELFITID,omitempty"` // used to relate transactions associated with mutual fund exchanges
	Gain       Amount      `xml:"GAIN,omitempty"`     // Total gain
}

ClosureOpt represents a transaction closing a position for an option

func (ClosureOpt) TransactionType

func (t ClosureOpt) TransactionType() string

TransactionType returns a string representation of this transaction's type

type ContribSecurity

type ContribSecurity struct {
	XMLName                 xml.Name   `xml:"CONTRIBSECURITY"`
	SecID                   SecurityID `xml:"SECID"`
	PreTaxContribPct        Amount     `xml:"PRETAXCONTRIBPCT,omitempty"`        // Percentage of each new employee pretax contribution allocated to this security, rate.
	PreTaxContribAmt        Amount     `xml:"PRETAXCONTRIBAMT,omitempty"`        // Fixed amount of each new employee pretax contribution allocated to this security, amount
	AfterTaxContribPct      Amount     `xml:"AFTERTAXCONTRIBPCT,omitempty"`      // Percentage of each new employee after tax contribution allocated to this security, rate.
	AfterTaxContribAmt      Amount     `xml:"AFTERTAXCONTRIBAMT,omitempty"`      // Fixed amount of each new employee pretax contribution allocated to this security, amount.
	MatchContribPct         Amount     `xml:"MATCHCONTRIBPCT,omitempty"`         // Percentage of each new employer match contribution allocated to this security, rate.
	MatchContribAmt         Amount     `xml:"MATCHCONTRIBAMT,omitempty"`         // Fixed amount of each new employer match contribution allocated to this security, amount.
	ProfitSharingContribPct Amount     `xml:"PROFITSHARINGCONTRIBPCT,omitempty"` // Percentage of each new employer profit sharing contribution allocated to this security, rate.
	ProfitSharingContribAmt Amount     `xml:"PROFITSHARINGCONTRIBAMT,omitempty"` // Fixed amount of each new employer profit sharing contribution allocated to this security, amount.
	RolloverContribPct      Amount     `xml:"ROLLOVERCONTRIBPCT,omitempty"`      // Percentage of new rollover contributions allocated to this security, rate.
	RolloverContribAmt      Amount     `xml:"ROLLOVERCONTRIBAMT,omitempty"`      // Fixed amount of new rollover contributions allocated to this security, amount.
	OtherVestPct            Amount     `xml:"OTHERVESTPCT,omitempty"`            // Percentage of each new other employer contribution allocated to this security, rate.
	OtherVestAmt            Amount     `xml:"OTHERVESTAMT,omitempty"`            // Fixed amount of each new other employer contribution allocated to this security, amount.
	OtherNonVestPct         Amount     `xml:"OTHERNONVESTPCT,omitempty"`         // Percentage of each new other employee contribution allocated to this security, rate.
	OtherNonVestAmt         Amount     `xml:"OTHERNONVESTAMT,omitempty"`         // Fixed amount of each new other employee contribution allocated to this security, amount
}

ContribSecurity identifies current contribution allocation for a security in a 401(k) account

type CurrSymbol

type CurrSymbol struct {
	currency.Unit
}

CurrSymbol represents an ISO-4217 currency

func NewCurrSymbol

func NewCurrSymbol(s string) (*CurrSymbol, error)

NewCurrSymbol returns a new CurrSymbol given a three-letter ISO-4217 currency symbol as a string

func (CurrSymbol) Equal

func (c CurrSymbol) Equal(o CurrSymbol) bool

Equal returns true if the two Currencies are the same

func (*CurrSymbol) MarshalXML

func (c *CurrSymbol) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML marshals a CurrSymbol to SGML/XML

func (*CurrSymbol) UnmarshalXML

func (c *CurrSymbol) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling a CurrSymbol from an SGML/XML string. Leading and trailing whitespace is ignored.

func (CurrSymbol) Valid

func (c CurrSymbol) Valid() (bool, error)

Valid returns true, nil if the CurrSymbol is valid.

type Currency

type Currency struct {
	XMLName xml.Name   // CURRENCY or ORIGCURRENCY
	CurRate Amount     `xml:"CURRATE"` // Ratio of statement's currency (CURDEF) to transaction currency (CURSYM)
	CurSym  CurrSymbol `xml:"CURSYM"`  // ISO-4217 3-character currency identifier
}

Currency represents one ISO-4217 currency. CURRENCY elements signify that the transaction containing this Currency struct is in this currency instead of being converted to the statement's default. ORIGCURRENCY elements signify that the transaction containing this Currency struct was converted to the statement's default from the specified currency.

func (Currency) Valid

func (c Currency) Valid() (bool, error)

Valid returns whether the Currency is valid according to the OFX spec

type Date

type Date struct {
	time.Time
}

Date represents OFX date/time values

func NewDate

func NewDate(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) *Date

NewDate returns a new Date object with the provided date, time, and timezone

func NewDateGMT

func NewDateGMT(year int, month time.Month, day, hour, min, sec, nsec int) *Date

NewDateGMT returns a new Date object with the provided date and time in the GMT timezone

func (Date) Equal

func (od Date) Equal(o Date) bool

Equal returns true if the two Dates represent the same time (time zones are accounted for when comparing, but are not required to match)

func (*Date) MarshalXML

func (od *Date) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML marshals a Date to XML

func (Date) String

func (od Date) String() string

String returns a string representation of the Date abiding by the OFX spec

func (*Date) UnmarshalXML

func (od *Date) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling a Date from an SGML/XML string. It attempts to unmarshal the valid date formats in order of decreasing length and defaults to GMT if a time zone is not provided, as per the OFX spec. Leading and trailing whitespace is ignored.

type DebtInfo

type DebtInfo struct {
	XMLName      xml.Name   `xml:"DEBTINFO"`
	SecInfo      SecInfo    `xml:"SECINFO"`
	ParValue     Amount     `xml:"PARVALUE"`
	DebtType     debtType   `xml:"DEBTTYPE"`               // One of COUPON, ZERO (zero coupon)
	DebtClass    debtClass  `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   couponFreq `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     callType   `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   assetClass `xml:"ASSETCLASS,omitempty"`   // One of DOMESTICBOND, INTLBOND, LARGESTOCK, SMALLSTOCK, INTLSTOCK, MONEYMRKT, OTHER
	FiAssetClass String     `xml:"FIASSETCLASS,omitempty"` // FI-defined asset class
}

DebtInfo provides information about a debt security

func (DebtInfo) SecurityType

func (i DebtInfo) SecurityType() string

SecurityType returns a string representation of this security's type

type DebtPosition

type DebtPosition struct {
	XMLName xml.Name    `xml:"POSDEBT"`
	InvPos  InvPosition `xml:"INVPOS"`
}

DebtPosition represents a position held in a debt security

func (DebtPosition) PositionType

func (p DebtPosition) PositionType() string

PositionType returns a string representation of this position's type

type DiscoverCardClient

type DiscoverCardClient struct {
	*BasicClient
}

DiscoverCardClient provides a Client implementation which handles DiscoverCard's broken HTTP header behavior. DiscoverCardClient uses default, non-zero settings, if its fields are not initialized.

func (*DiscoverCardClient) RawRequest

func (c *DiscoverCardClient) RawRequest(URL string, r io.Reader) (*http.Response, error)

func (*DiscoverCardClient) Request

func (c *DiscoverCardClient) Request(r *Request) (*Response, error)

func (*DiscoverCardClient) RequestNoParse

func (c *DiscoverCardClient) RequestNoParse(r *Request) (*http.Response, error)

type FiAssetPortion

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
}

FiAssetPortion represents the percentage of a mutual fund with the given FI-defined asset classification (AssetPortion should be used for all asset classifications defined by the assetClass enum)

type HolderInfo

type HolderInfo struct {
	XMLName    xml.Name
	FirstName  String     `xml:"FIRSTNAME"`
	MiddleName String     `xml:"MIDDLENAME,omitempty"`
	LastName   String     `xml:"LASTNAME"`
	Addr1      String     `xml:"ADDR1"`
	Addr2      String     `xml:"ADDR2,omitempty"`
	Addr3      String     `xml:"ADDR3,omitempty"`
	City       String     `xml:"CITY"`
	State      String     `xml:"STATE"`
	PostalCode String     `xml:"POSTALCODE"`
	Country    String     `xml:"COUNTRY,omitempty"`
	DayPhone   String     `xml:"DAYPHONE,omitempty"`
	EvePhone   String     `xml:"EVEPHONE,omitempty"`
	Email      String     `xml:"EMAIL,omitempty"`
	HolderType holderType `xml:"HOLDERTYPE,omitempty"` // One of INDIVIDUAL, JOINT, CUSTODIAL, TRUST, OTHER
}

HolderInfo contains the information a FI has about an account-holder

type ImageData

type ImageData struct {
	XMLName      xml.Name     `xml:"IMAGEDATA"`
	ImageType    imageType    `xml:"IMAGETYPE"`    // One of STATEMENT, TRANSACTION, TAX
	ImageRef     String       `xml:"IMAGEREF"`     // URL or identifier, depending on IMAGEREFTYPE
	ImageRefType imageRefType `xml:"IMAGEREFTYPE"` // One of OPAQUE, URL, FORMURL (see spec for more details on how to access images of each of these types)
	// Only one of the next two should be valid at any given time
	ImageDelay   Int      `xml:"IMAGEDELAY,omitempty"`   // Number of calendar days from DTSERVER (for statement images) or DTPOSTED (for transaction image) the image will become available
	DtImageAvail *Date    `xml:"DTIMAGEAVAIL,omitempty"` // Date image will become available
	ImageTTL     Int      `xml:"IMAGETTL,omitempty"`     // Number of days after image becomes available that it will remain available
	CheckSup     checkSup `xml:"CHECKSUP,omitempty"`     // What is contained in check images. One of FRONTONLY, BACKONLY, FRONTANDBACK
}

ImageData represents the metadata surrounding a check or other image file, including how to retrieve the image

type Income

type Income struct {
	XMLName       xml.Name      `xml:"INCOME"`
	InvTran       InvTran       `xml:"INVTRAN"`
	SecID         SecurityID    `xml:"SECID"`
	IncomeType    incomeType    `xml:"INCOMETYPE"` // Type of investment income: CGLONG (capital gains-long term), CGSHORT (capital gains-short term), DIV (dividend), INTEREST, MISC
	Total         Amount        `xml:"TOTAL"`
	SubAcctSec    subAcctType   `xml:"SUBACCTSEC"`              // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
	SubAcctFund   subAcctType   `xml:"SUBACCTFUND"`             // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
	TaxExempt     Boolean       `xml:"TAXEXEMPT,omitempty"`     // Tax-exempt transaction
	Witholding    Amount        `xml:"WITHHOLDING,omitempty"`   // Federal tax witholdings
	Currency      Currency      `xml:"CURRENCY,omitempty"`      // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
	OrigCurrency  Currency      `xml:"ORIGCURRENCY,omitempty"`  // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}

Income represents a transaction where investment income is being realized as cash into the investment account

func (Income) TransactionType

func (t Income) TransactionType() string

TransactionType returns a string representation of this transaction's type

type Int

type Int int64

Int provides helper methods to unmarshal int64 values from SGML/XML

func (Int) Equal

func (i Int) Equal(o Int) bool

Equal returns true if the two Ints are equal in value

func (*Int) UnmarshalXML

func (i *Int) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling an Int from an SGML/XML string. Leading and trailing whitespace is ignored.

type Inv401K

type Inv401K struct {
	XMLName             xml.Name `xml:"INV401K"`
	EmployerName        String   `xml:"EMPLOYERNAME"`
	PlanID              String   `xml:"PLANID,omitempty"`              // Plan number
	PlanJoinDate        *Date    `xml:"PLANJOINDATE,omitempty"`        // Date the employee joined the plan
	EmployerContactInfo String   `xml:"EMPLOYERCONTACTINFO,omitempty"` // Name of contact person at employer, plus any available contact information, such as phone number
	BrokerContactInfo   String   `xml:"BROKERCONTACTINFO,omitempty"`   // Name of contact person at broker, plus any available contact information, such as phone number
	DeferPctPreTax      Amount   `xml:"DEFERPCTPRETAX,omitempty"`      // Percent of employee salary deferred before tax
	DeferPctAfterTax    Amount   `xml:"DEFERPCTAFTERTAX,omitempty"`    // Percent of employee salary deferred after tax

	//<MATCHINFO> Aggregate containing employer match information. Absent if employer does not contribute matching funds.
	MatchPct            Amount                `xml:"MATCHINFO>MATCHPCT,omitempty"`          // Percent of employee contribution matched, e.g., 75% if contribution rate is $0.75/$1.00
	MaxMatchAmt         Amount                `xml:"MATCHINFO>MAXMATCHAMT,omitempty"`       // Maximum employer contribution amount in any year
	MaxMatchPct         Amount                `xml:"MATCHINFO>MAXMATCHPCT,omitempty"`       // Current maximum employer contribution percentage. Maximum match in a year is MAXMATCHPCT up to the MAXMATCHAMT, if provided
	StartOfYear         *Date                 `xml:"MATCHINFO>STARTOFYEAR,omitempty"`       // Specifies when the employer contribution max is reset. Some plans have a maximum based on the company fiscal year rather than calendar year. Assume calendar year if omitted. Only the month and day (MMDD) are used; year (YYYY) and time are ignored
	BaseMatchAmt        Amount                `xml:"MATCHINFO>BASEMATCHAMT"`                // Specifies a fixed dollar amount contributed by the employer if the employee participates in the plan at all. This may be present in addition to the <MATCHPCT>. $0 if omitted
	BaseMatchPct        Amount                `xml:"MATCHINFO>BASEMATCHPCT"`                // Specifies a fixed percent of employee salary matched if the employee participates in the plan at all. This may be present in addition to the MATCHPCT>. 0% if omitted. Base match in a year is BASEMATCHPCT up to the BASEMATCHAMT,if provided
	ContribInfo         []ContribSecurity     `xml:"CONTRIBINTO>CONTRIBSECURITY"`           // Aggregate to describe how new contributions are distributed among the available securities.
	CurrentVestPct      Amount                `xml:"CURRENTVESTPCT,omitempty"`              // Estimated percentage of employer contributions vested as of the current date. If omitted, assume 100%
	VestInfo            []VestInfo            `xml:"VESTINFO,omitempty"`                    // Vest change dates. Provides the vesting percentage as of any particular past, current, or future date. 0 or more.
	LoanInfo            []LoanInfo            `xml:"LOANINFO,omitempty"`                    // List of any loans outstanding against this account
	YearToDateSummary   Inv401KSummaryPeriod  `xml:"INV401KSUMMARY>YEARTODATE"`             // Contributions to date for this calendar year.
	InceptToDateSummary *Inv401KSummaryPeriod `xml:"INV401KSUMMARY>INCEPTODATE,omitempty"`  // Total contributions to date (since inception)
	PeriodToDate        *Inv401KSummaryPeriod `xml:"INV401KSUMMARY>PERIODTODATE,omitempty"` // Total contributions this contribution period
}

Inv401K is included in InvStatementResponse for 401(k) accounts and provides a summary of the 401(k) specific information about the user's account.

type Inv401KBal

type Inv401KBal struct {
	XMLName       xml.Name  `xml:"INV401KBAL"`
	CashBal       Amount    `xml:"CASHBAL,omitempty"`       // Available cash balance
	PreTax        Amount    `xml:"PRETAX,omitempty"`        // Current value of all securities purchased with Before Tax Employee contributions
	AfterTax      Amount    `xml:"AFTERTAX,omitempty"`      // Current value of all securities purchased with After Tax Employee contributions
	Match         Amount    `xml:"MATCH,omitempty"`         // Current value of all securities purchased with Employer Match contributions
	ProfitSharing Amount    `xml:"PROFITSHARING,omitempty"` // Current value of all securities purchased with Employer Profit Sharing contributions
	Rollover      Amount    `xml:"ROLLOVER,omitempty"`      // Current value of all securities purchased with Rollover contributions
	OtherVest     Amount    `xml:"OTHERVEST,omitempty"`     // Current value of all securities purchased with Other (vesting) Employer contributions
	OtherNonVest  Amount    `xml:"OTHERNONVEST,omitempty"`  // Current value of all securities purchased with Other (non-vesting) Employer contributions
	Total         Amount    `xml:"TOTAL"`                   // Current value of all securities purchased with all contributions
	BalList       []Balance `xml:"BALLIST>BAL,omitempty"`
}

Inv401KBal provides the balances for different 401(k) subaccount types, as well as the total cash value of the securities held

type Inv401KSummaryAggregate

type Inv401KSummaryAggregate struct {
	XMLName       xml.Name // One of CONTRIBUTIONS, WITHDRAWALS, EARNINGS
	PreTax        Amount   `xml:"PRETAX,omitempty"`        // Pretax contributions, withdrawals, or earlings.
	AfterTax      Amount   `xml:"AFTERTAX,omitempty"`      // After tax contributions, withdrawals, or earlings.
	Match         Amount   `xml:"MATCH,omitempty"`         // Employer matching contributions, withdrawals, or earlings.
	ProfitSharing Amount   `xml:"PROFITSHARING,omitempty"` // Profit sharing contributions, withdrawals, or earlings.
	Rollover      Amount   `xml:"ROLLOVER,omitempty"`      // Rollover contributions, withdrawals, or earlings.
	OtherVest     Amount   `xml:"OTHERVEST,omitempty"`     // Other vesting contributions, withdrawals, or earlings.
	OtherNonVest  Amount   `xml:"OTHERNONVEST,omitempty"`  // Other non-vesting contributions, withdrawals, or earlings.
	Total         Amount   `xml:"TOTAL"`                   // Sum of contributions, withdrawals, or earlings from all fund sources.
}

Inv401KSummaryAggregate represents the total of either contributions, withdrawals, or earnings made in each contribution type in a given period (dates specified in a containing Inv401KSummaryPeriod)

type Inv401KSummaryPeriod

type Inv401KSummaryPeriod struct {
	XMLName       xml.Name                 // One of YEARTODATE, INCEPTODATE, or PERIODTODATE
	DtStart       Date                     `xml:"DTSTART"`
	DtEnd         Date                     `xml:"DTEND"`
	Contributions *Inv401KSummaryAggregate `xml:"CONTRIBUTIONS,omitempty"` // 401(k) contribution aggregate. Note: this includes loan payments.
	Withdrawls    *Inv401KSummaryAggregate `xml:"WITHDRAWLS,omitempty"`    // 401(k) withdrawals aggregate. Note: this includes loan withdrawals.
	Earnings      *Inv401KSummaryAggregate `xml:"EARNINGS,omitempty"`      // 401(k) earnings aggregate. This is the market value change. It includes dividends/interest, and capital gains - realized and unrealized.
}

Inv401KSummaryPeriod contains the total contributions, withdrawals, and earnings made in the given date range

type InvAcct

type InvAcct struct {
	XMLName  xml.Name // INVACCTTO or INVACCTFROM
	BrokerID String   `xml:"BROKERID"`
	AcctID   String   `xml:"ACCTID"`
}

InvAcct represents the identifying information for one investment account

type InvAcctInfo

type InvAcctInfo struct {
	XMLName       xml.Name      `xml:"INVACCTINFO"`
	InvAcctFrom   InvAcct       `xml:"INVACCTFROM"`
	UsProductType usProductType `xml:"USPRODUCTTYPE"`         // One of 401K, 403B, IRA, KEOGH, OTHER, SARSEP, SIMPLE, NORMAL, TDA, TRUST, UGMA
	Checking      Boolean       `xml:"CHECKING"`              // Has check-writing privileges
	SvcStatus     svcStatus     `xml:"SVCSTATUS"`             // One of AVAIL (available, but not yet requested), PEND (requested, but not yet available), ACTIVE
	InvAcctType   holderType    `xml:"INVACCTTYPE,omitempty"` // One of INDIVIDUAL, JOINT, TRUST, CORPORATE
	OptionLevel   String        `xml:"OPTIONLEVEL,omitempty"` // Text desribing option trading privileges
}

InvAcctInfo contains information about an investment account, including how to access it (InvAcct), and whether it supports downloading transactions (SupTxDl).

func (*InvAcctInfo) String

func (iai *InvAcctInfo) String() string

String makes pointers to InvAcctInfo structs print nicely

type InvBalance

type InvBalance struct {
	XMLName       xml.Name  `xml:"INVBAL"`
	AvailCash     Amount    `xml:"AVAILCASH"`     // Available cash across all sub-accounts, including sweep funds
	MarginBalance Amount    `xml:"MARGINBALANCE"` // Negative means customer has borrowed funds
	ShortBalance  Amount    `xml:"SHORTBALANCE"`  // Always positive, market value of all short positions
	BuyPower      Amount    `xml:"BUYPOWER, omitempty"`
	BalList       []Balance `xml:"BALLIST>BAL,omitempty"`
}

InvBalance contains three (or optionally four) specified balances as well as a free-form list of generic balance information which may be provided by an FI.

type InvBankTransaction

type InvBankTransaction struct {
	XMLName      xml.Name      `xml:"INVBANKTRAN"`
	Transactions []Transaction `xml:"STMTTRN,omitempty"`
	SubAcctFund  subAcctType   `xml:"SUBACCTFUND"` // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
}

InvBankTransaction is a banking transaction performed in an investment account. This represents all transactions not related to securities - for instance, funding the account using cash from another bank.

type InvBuy

type InvBuy struct {
	XMLName      xml.Name    `xml:"INVBUY"`
	InvTran      InvTran     `xml:"INVTRAN"`
	SecID        SecurityID  `xml:"SECID"`
	Units        Amount      `xml:"UNITS"`            // For stocks, MFs, other, number of shares held. Bonds = face value. Options = number of contracts
	UnitPrice    Amount      `xml:"UNITPRICE"`        // For stocks, MFs, other, price per share. Bonds = percentage of par. Option = premium per share of underlying security
	Markup       Amount      `xml:"MARKUP,omitempty"` // Portion of UNITPRICE that is attributed to the dealer markup
	Commission   Amount      `xml:"COMMISSION,omitempty"`
	Taxes        Amount      `xml:"TAXES,omitempty"`
	Fees         Amount      `xml:"FEES,omitempty"`
	Load         Amount      `xml:"LOAD,omitempty"`
	Total        Amount      `xml:"TOTAL"`                  // Transaction total. Buys, sells, etc.:((quan. * (price +/- markup/markdown)) +/-(commission + fees + load + taxes + penalty + withholding + statewithholding)). Distributions, interest, margin interest, misc. expense, etc.: amount. Return of cap: cost basis
	Currency     Currency    `xml:"CURRENCY,omitempty"`     // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
	OrigCurrency Currency    `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
	SubAcctSec   subAcctType `xml:"SUBACCTSEC"`             // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
	SubAcctFund  subAcctType `xml:"SUBACCTFUND"`            // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER

	// The next three elements must either all be provided, or none of them
	LoanID        String `xml:"LOANID,omitempty"`        // For 401(k) accounts only. Indicates that the transaction was due to a loan or a loan repayment, and which loan it was
	LoanPrincipal Amount `xml:"LOANPRINCIPAL,omitempty"` // For 401(k) accounts only. Indicates how much of the loan repayment was principal
	LoanInterest  Amount `xml:"LOANINTEREST,omitempty"`  // For 401(k) accounts only. Indicates how much of the loan repayment was interest

	Inv401kSource    inv401kSource `xml:"INV401KSOURCE,omitempty"`    // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
	DtPayroll        *Date         `xml:"DTPAYROLL,omitempty"`        // For 401(k)accounts, date the funds for this transaction was obtained via payroll deduction
	PriorYearContrib Boolean       `xml:"PRIORYEARCONTRIB,omitempty"` // For 401(k) accounts, indicates that this Buy was made with a prior year contribution
}

InvBuy represents generic investment purchase transaction. It is included in many of the more specific transaction Buy* aggregates below.

type InvExpense

type InvExpense struct {
	XMLName       xml.Name      `xml:"INVEXPENSE"`
	InvTran       InvTran       `xml:"INVTRAN"`
	SecID         SecurityID    `xml:"SECID"`
	Total         Amount        `xml:"TOTAL"`
	SubAcctSec    subAcctType   `xml:"SUBACCTSEC"`              // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
	SubAcctFund   subAcctType   `xml:"SUBACCTFUND"`             // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
	Currency      Currency      `xml:"CURRENCY,omitempty"`      // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
	OrigCurrency  Currency      `xml:"ORIGCURRENCY,omitempty"`  // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}

InvExpense represents a transaction realizing an expense associated with an investment

func (InvExpense) TransactionType

func (t InvExpense) TransactionType() string

TransactionType returns a string representation of this transaction's type

type InvPosition

type InvPosition struct {
	XMLName       xml.Name      `xml:"INVPOS"`
	SecID         SecurityID    `xml:"SECID"`
	HeldInAcct    subAcctType   `xml:"HELDINACCT"`             // Sub-account type, one of CASH, MARGIN, SHORT, OTHER
	PosType       posType       `xml:"POSTYPE"`                // SHORT = Writer for options, Short for all others; LONG = Holder for options, Long for all others.
	Units         Amount        `xml:"UNITS"`                  // For stocks, MFs, other, number of shares held. Bonds = face value. Options = number of contracts
	UnitPrice     Amount        `xml:"UNITPRICE"`              // For stocks, MFs, other, price per share. Bonds = percentage of par. Option = premium per share of underlying security
	MktVal        Amount        `xml:"MKTVAL"`                 // Market value of this position
	AvgCostBasis  Amount        `xml:"AVGCOSTBASIS,omitempty"` //
	DtPriceAsOf   Date          `xml:"DTPRICEASOF"`            // Date and time of unit price and market value, and cost basis. If this date is unknown, use 19900101 as the placeholder; do not use 0,
	Currency      *Currency     `xml:"CURRENCY,omitempty"`     // Overriding currency for UNITPRICE
	Memo          String        `xml:"MEMO,omitempty"`
	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}

InvPosition contains generic position information included in each of the other *Position types

type InvSell

type InvSell struct {
	XMLName      xml.Name    `xml:"INVSELL"`
	InvTran      InvTran     `xml:"INVTRAN"`
	SecID        SecurityID  `xml:"SECID"`
	Units        Amount      `xml:"UNITS"`              // For stocks, MFs, other, number of shares held. Bonds = face value. Options = number of contracts
	UnitPrice    Amount      `xml:"UNITPRICE"`          // For stocks, MFs, other, price per share. Bonds = percentage of par. Option = premium per share of underlying security
	Markdown     Amount      `xml:"MARKDOWN,omitempty"` // Portion of UNITPRICE that is attributed to the dealer markdown
	Commission   Amount      `xml:"COMMISSION,omitempty"`
	Taxes        Amount      `xml:"TAXES,omitempty"`
	Fees         Amount      `xml:"FEES,omitempty"`
	Load         Amount      `xml:"LOAD,omitempty"`
	Witholding   Amount      `xml:"WITHHOLDING,omitempty"`  // Federal tax witholdings
	TaxExempt    Boolean     `xml:"TAXEXEMPT,omitempty"`    // Tax-exempt transaction
	Total        Amount      `xml:"TOTAL"`                  // Transaction total. Buys, sells, etc.:((quan. * (price +/- markup/markdown)) +/-(commission + fees + load + taxes + penalty + withholding + statewithholding)). Distributions, interest, margin interest, misc. expense, etc.: amount. Return of cap: cost basis
	Gain         Amount      `xml:"GAIN,omitempty"`         // Total gain
	Currency     Currency    `xml:"CURRENCY,omitempty"`     // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
	OrigCurrency Currency    `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
	SubAcctSec   subAcctType `xml:"SUBACCTSEC"`             // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
	SubAcctFund  subAcctType `xml:"SUBACCTFUND"`            // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER

	LoanID          String `xml:"LOANID,omitempty"`           // For 401(k) accounts only. Indicates that the transaction was due to a loan or a loan repayment, and which loan it was
	StateWitholding Amount `xml:"STATEWITHHOLDING,omitempty"` // State tax witholdings
	Penalty         Amount `xml:"PENALTY,omitempty"`          // Amount withheld due to penalty

	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}

InvSell represents generic investment sale transaction. It is included in many of the more specific transaction Sell* aggregates below.

type InvStatementRequest

type InvStatementRequest struct {
	XMLName   xml.Name `xml:"INVSTMTTRNRQ"`
	TrnUID    UID      `xml:"TRNUID"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	TAN       String   `xml:"TAN,omitempty"` // Transaction authorization number
	// TODO `xml:"OFXEXTENSION,omitempty"`
	InvAcctFrom      InvAcct `xml:"INVSTMTRQ>INVACCTFROM"`
	DtStart          *Date   `xml:"INVSTMTRQ>INCTRAN>DTSTART,omitempty"`
	DtEnd            *Date   `xml:"INVSTMTRQ>INCTRAN>DTEND,omitempty"`
	Include          Boolean `xml:"INVSTMTRQ>INCTRAN>INCLUDE"`         // Include transactions (instead of just balance)
	IncludeOO        Boolean `xml:"INVSTMTRQ>INCOO"`                   // Include open orders
	PosDtAsOf        *Date   `xml:"INVSTMTRQ>INCPOS>DTASOF,omitempty"` // Date that positions should be sent down for, if present
	IncludePos       Boolean `xml:"INVSTMTRQ>INCPOS>INCLUDE"`          // Include position data in response
	IncludeBalance   Boolean `xml:"INVSTMTRQ>INCBAL"`                  // Include investment balance in response
	Include401K      Boolean `xml:"INVSTMTRQ>INC401K,omitempty"`       // Include 401k information
	Include401KBal   Boolean `xml:"INVSTMTRQ>INC401KBAL,omitempty"`    // Include 401k balance information
	IncludeTranImage Boolean `xml:"INVSTMTRQ>INCTRANIMAGE,omitempty"`  // Include transaction images
}

InvStatementRequest allows a customer to request transactions, positions, open orders, and balances. It specifies what types of information to include in hte InvStatementResponse and which account to include it for.

func (*InvStatementRequest) Name

func (r *InvStatementRequest) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*InvStatementRequest) Type

func (r *InvStatementRequest) Type() messageType

Type returns which message set this message belongs to (which Request element of type []Message it should appended to)

func (*InvStatementRequest) Valid

func (r *InvStatementRequest) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct would be valid OFX if marshalled into XML/SGML

type InvStatementResponse

type InvStatementResponse struct {
	XMLName   xml.Name `xml:"INVSTMTTRNRS"`
	TrnUID    UID      `xml:"TRNUID"`
	Status    Status   `xml:"STATUS"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	// TODO `xml:"OFXEXTENSION,omitempty"`
	DtAsOf      Date         `xml:"INVSTMTRS>DTASOF"`
	CurDef      CurrSymbol   `xml:"INVSTMTRS>CURDEF"`
	InvAcctFrom InvAcct      `xml:"INVSTMTRS>INVACCTFROM"`
	InvTranList *InvTranList `xml:"INVSTMTRS>INVTRANLIST,omitempty"`
	InvPosList  PositionList `xml:"INVSTMTRS>INVPOSLIST,omitempty"`
	InvBal      *InvBalance  `xml:"INVSTMTRS>INVBAL,omitempty"`
	InvOOList   OOList       `xml:"INVSTMTRS>INVOOLIST,omitempty"`
	MktgInfo    String       `xml:"INVSTMTRS>MKTGINFO,omitempty"` // Marketing information
	Inv401K     *Inv401K     `xml:"INVSTMTRS>INV401K,omitempty"`
	Inv401KBal  *Inv401KBal  `xml:"INVSTMTRS>INV401KBAL,omitempty"`
}

InvStatementResponse includes requested transaction, position, open order, and balance information for an investment account. It is in response to an InvStatementRequest or sometimes provided as part of an OFX file downloaded manually from an FI.

func (*InvStatementResponse) Name

func (sr *InvStatementResponse) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*InvStatementResponse) Type

func (sr *InvStatementResponse) Type() messageType

Type returns which message set this message belongs to (which Response element of type []Message it belongs to)

func (*InvStatementResponse) Valid

func (sr *InvStatementResponse) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct was valid OFX when unmarshalled

type InvTran

type InvTran struct {
	XMLName       xml.Name `xml:"INVTRAN"`
	FiTID         String   `xml:"FITID"`                   // Unique FI-assigned transaction ID. This ID is used to detect duplicate downloads
	SrvrTID       String   `xml:"SRVRTID,omitempty"`       // Server assigned transaction ID
	DtTrade       Date     `xml:"DTTRADE"`                 // trade date; for stock splits, day of record
	DtSettle      *Date    `xml:"DTSETTLE,omitempty"`      // settlement date; for stock splits, execution date
	ReversalFiTID String   `xml:"REVERSALFITID,omitempty"` // For a reversal transaction, the FITID of the transaction that is being reversed.
	Memo          String   `xml:"MEMO,omitempty"`
}

InvTran represents generic investment transaction. It is included in both InvBuy and InvSell as well as many of the more specific transaction aggregates.

type InvTranList

type InvTranList struct {
	XMLName          xml.Name `xml:"INVTRANLIST"`
	DtStart          Date
	DtEnd            Date // This is the value that should be sent as <DTSTART> in the next InvStatementRequest to ensure that no transactions are missed
	InvTransactions  []InvTransaction
	BankTransactions []InvBankTransaction
}

InvTranList represents a list of investment account transactions. It includes the date range its transactions cover, as well as the bank- and security-related transactions themselves. It must be unmarshalled manually due to the structure (don't know what kind of InvTransaction is coming next)

func (*InvTranList) MarshalXML

func (l *InvTranList) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML handles marshalling an InvTranList element to an SGML/XML string

func (*InvTranList) UnmarshalXML

func (l *InvTranList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling an InvTranList element from an SGML/XML string

type InvTransaction

type InvTransaction interface {
	TransactionType() string
}

InvTransaction is a generic interface met by all investment transactions (Buy*, Sell*, & co.)

type JrnlFund

type JrnlFund struct {
	XMLName     xml.Name    `xml:"JRNLFUND"`
	InvTran     InvTran     `xml:"INVTRAN"`
	Total       Amount      `xml:"TOTAL"`
	SubAcctFrom subAcctType `xml:"SUBACCTFROM"` // Sub-account cash is being transferred from: CASH, MARGIN, SHORT, OTHER
	SubAcctTo   subAcctType `xml:"SUBACCTTO"`   // Sub-account cash is being transferred to: CASH, MARGIN, SHORT, OTHER
}

JrnlFund represents a transaction journaling cash holdings between sub-accounts within the same investment account

func (JrnlFund) TransactionType

func (t JrnlFund) TransactionType() string

TransactionType returns a string representation of this transaction's type

type JrnlSec

type JrnlSec struct {
	XMLName     xml.Name    `xml:"JRNLSEC"`
	InvTran     InvTran     `xml:"INVTRAN"`
	SecID       SecurityID  `xml:"SECID"`
	SubAcctFrom subAcctType `xml:"SUBACCTFROM"` // Sub-account cash is being transferred from: CASH, MARGIN, SHORT, OTHER
	SubAcctTo   subAcctType `xml:"SUBACCTTO"`   // Sub-account cash is being transferred to: CASH, MARGIN, SHORT, OTHER
	Units       Amount      `xml:"UNITS"`       // For stocks, MFs, other, number of shares held. Bonds = face value. Options = number of contracts
}

JrnlSec represents a transaction journaling security holdings between sub-accounts within the same investment account

func (JrnlSec) TransactionType

func (t JrnlSec) TransactionType() string

TransactionType returns a string representation of this transaction's type

type LoanInfo

type LoanInfo struct {
	XMLName               xml.Name    `xml:"VESTINFO"`
	LoanID                String      `xml:"LOANID"`                          // Identifier of this loan
	LoanDesc              String      `xml:"LOANDESC,omitempty"`              // Loan description
	InitialLoanBal        Amount      `xml:"INITIALLOANBAL,omitempty"`        // Initial loan balance
	LoanStartDate         *Date       `xml:"LOANSTARTDATE,omitempty"`         // Start date of loan
	CurrentLoanBal        Amount      `xml:"CURRENTLOANBAL"`                  // Current loan principal balance
	DtAsOf                *Date       `xml:"DTASOF"`                          // Date and time of the current loan balance
	LoanRate              Amount      `xml:"LOANRATE,omitempty"`              // Loan annual interest rate
	LoanPmtAmt            Amount      `xml:"LOANPMTAMT,omitempty"`            // Loan payment amount
	LoanPmtFreq           loanPmtFreq `xml:"LOANPMTFREQ,omitempty"`           // Frequency of loan repayments: WEEKLY, BIWEEKLY, TWICEMONTHLY, MONTHLY, FOURWEEKS, BIMONTHLY, QUARTERLY, SEMIANNUALLY, ANNUALLY, OTHER. See section 10.2.1 for calculation rules.
	LoanPmtsInitial       Int         `xml:"LOANPMTSINITIAL,omitempty"`       // Initial number of loan payments.
	LoanPmtsRemaining     Int         `xml:"LOANPMTSREMAINING,omitempty"`     // Remaining number of loan payments
	LoanMaturityDate      *Date       `xml:"LOANMATURITYDATE,omitempty"`      // Expected loan end date
	LoanTotalProjInterest Amount      `xml:"LOANTOTALPROJINTEREST,omitempty"` // Total projected interest to be paid on this loan
	LoanInterestToDate    Amount      `xml:"LOANINTERESTTODATE,omitempty"`    // Total interested paid to date on this loan
	LoanExtPmtDate        *Date       `xml:"LOANNEXTPMTDATE,omitempty"`       // Next payment due date
}

LoanInfo represents a loan outstanding against this 401(k) account

type MFInfo

type MFInfo struct {
	XMLName        xml.Name         `xml:"MFINFO"`
	SecInfo        SecInfo          `xml:"SECINFO"`
	MfType         mfType           `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"`
}

MFInfo provides information about a mutual fund

func (MFInfo) SecurityType

func (i MFInfo) SecurityType() string

SecurityType returns a string representation of this security's type

type MFPosition

type MFPosition struct {
	XMLName     xml.Name    `xml:"POSMF"`
	InvPos      InvPosition `xml:"INVPOS"`
	UnitsStreet Amount      `xml:"UNITSSTREET,omitempty"` // Units in the FI’s street name
	UnitsUser   Amount      `xml:"UNITSUSER,omitempty"`   // Units in the user's name directly
	ReinvDiv    Boolean     `xml:"REINVDIV,omitempty"`    // Reinvest dividends
	ReinvCG     Boolean     `xml:"REINVCG,omitempty"`     // Reinvest capital gains
}

MFPosition represents a position held in a mutual fund

func (MFPosition) PositionType

func (p MFPosition) PositionType() string

PositionType returns a string representation of this position's type

type MarginInterest

type MarginInterest struct {
	XMLName      xml.Name    `xml:"MARGININTEREST"`
	InvTran      InvTran     `xml:"INVTRAN"`
	Total        Amount      `xml:"TOTAL"`
	SubAcctFund  subAcctType `xml:"SUBACCTFUND"`            // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
	Currency     Currency    `xml:"CURRENCY,omitempty"`     // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
	OrigCurrency Currency    `xml:"ORIGCURRENCY,omitempty"` // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
}

MarginInterest represents a transaction realizing a margin interest expense

func (MarginInterest) TransactionType

func (t MarginInterest) TransactionType() string

TransactionType returns a string representation of this transaction's type

type Message

type Message interface {
	Name() string                           // The name of the OFX transaction wrapper element this represents
	Valid(version ofxVersion) (bool, error) // Called before a Message is marshaled and after it's unmarshaled to ensure the request or response is valid
	Type() messageType                      // The message set this message belongs to
}

Message represents an OFX message in a message set. it is used to ease marshalling and unmarshalling.

type MessageSet

type MessageSet struct {
	XMLName     xml.Name // <xxxMSGSETVn>
	Name        string   // <xxxMSGSETVn> (copy of XMLName.Local)
	Ver         Int      `xml:"MSGSETCORE>VER"`                   // Message set version - should always match 'n' in <xxxMSGSETVn> of Name
	URL         String   `xml:"MSGSETCORE>URL"`                   // URL where messages in this set are to be set
	OfxSec      ofxSec   `xml:"MSGSETCORE>OFXSEC"`                // NONE or 'TYPE 1'
	TranspSec   Boolean  `xml:"MSGSETCORE>TRANSPSEC"`             // Transport-level security must be used
	SignonRealm String   `xml:"MSGSETCORE>SIGNONREALM"`           // Used to identify which SignonInfo to use for to this MessageSet
	Language    []String `xml:"MSGSETCORE>LANGUAGE"`              // List of supported languages
	SyncMode    syncMode `xml:"MSGSETCORE>SYNCMODE"`              // One of FULL, LITE
	RefreshSupt Boolean  `xml:"MSGSETCORE>REFRESHSUPT,omitempty"` // Y if server supports <REFRESH>Y within synchronizations. This option is irrelevant for full synchronization servers. Clients must ignore <REFRESHSUPT> (or its absence) if the profile also specifies <SYNCMODE>FULL. For lite synchronization, the default is N. Without <REFRESHSUPT>Y, lite synchronization servers are not required to support <REFRESH>Y requests
	RespFileER  Boolean  `xml:"MSGSETCORE>RESPFILEER"`            // server supports file-based error recovery
	SpName      String   `xml:"MSGSETCORE>SPNAME"`                // Name of service provider

}

MessageSet represents one message set supported by an FI and its capabilities

type MessageSetList

type MessageSetList []MessageSet

MessageSetList is a list of MessageSets (necessary because they must be manually parsed)

func (*MessageSetList) MarshalXML

func (msl *MessageSetList) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML handles marshalling a MessageSetList element to an XML string

func (*MessageSetList) UnmarshalXML

func (msl *MessageSetList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling a MessageSetList element from an XML string

type OO

type OO struct {
	XMLName       xml.Name      `xml:"OO"`
	FiTID         String        `xml:"FITID"`
	SrvrTID       String        `xml:"SRVRTID,omitempty"`
	SecID         SecurityID    `xml:"SECID"`
	DtPlaced      Date          `xml:"DTPLACED"`           // Date the order was placed
	Units         Amount        `xml:"UNITS"`              // Quantity of the security the open order is for
	SubAcct       subAcctType   `xml:"SUBACCT"`            // One of CASH, MARGIN, SHORT, OTHER
	Duration      duration      `xml:"DURATION"`           // How long the order is good for. One of DAY, GOODTILCANCEL, IMMEDIATE
	Restriction   restriction   `xml:"RESTRICTION"`        // Special restriction on the order: One of ALLORNONE, MINUNITS, NONE
	MinUnits      Amount        `xml:"MINUNITS,omitempty"` // Minimum number of units that must be filled for the order
	LimitPrice    Amount        `xml:"LIMITPRICE,omitempty"`
	StopPrice     Amount        `xml:"STOPPRICE,omitempty"`
	Memo          String        `xml:"MEMO,omitempty"`
	Currency      *Currency     `xml:"CURRENCY,omitempty"`      // Overriding currency for UNITPRICE
	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}

OO represents a generic open investment order. It is included in the other OO* elements.

type OOBuyDebt

type OOBuyDebt struct {
	XMLName   xml.Name `xml:"OOBUYDEBT"`
	OO        OO       `xml:"OO"`
	Auction   Boolean  `xml:"AUCTION"` // whether the debt should be purchased at the auction
	DtAuction *Date    `xml:"DTAUCTION,omitempty"`
}

OOBuyDebt represents an open order to purchase a debt security

func (OOBuyDebt) OrderType

func (o OOBuyDebt) OrderType() string

OrderType returns a string representation of this order's type

type OOBuyMF

type OOBuyMF struct {
	XMLName  xml.Name `xml:"OOBUYMF"`
	OO       OO       `xml:"OO"`
	BuyType  buyType  `xml:"BUYTYPE"`  // One of BUY, BUYTOCOVER
	UnitType unitType `xml:"UNITTYPE"` // What the units represent: one of SHARES, CURRENCY
}

OOBuyMF represents an open order to purchase a mutual fund

func (OOBuyMF) OrderType

func (o OOBuyMF) OrderType() string

OrderType returns a string representation of this order's type

type OOBuyOpt

type OOBuyOpt struct {
	XMLName    xml.Name   `xml:"OOBUYOPT"`
	OO         OO         `xml:"OO"`
	OptBuyType optBuyType `xml:"OPTBUYTYPE"` // One of BUYTOOPEN, BUYTOCLOSE
}

OOBuyOpt represents an open order to purchase an option

func (OOBuyOpt) OrderType

func (o OOBuyOpt) OrderType() string

OrderType returns a string representation of this order's type

type OOBuyOther

type OOBuyOther struct {
	XMLName  xml.Name `xml:"OOBUYOTHER"`
	OO       OO       `xml:"OO"`
	UnitType unitType `xml:"UNITTYPE"` // What the units represent: one of SHARES, CURRENCY
}

OOBuyOther represents an open order to purchase a security type not covered by the other OOBuy* elements

func (OOBuyOther) OrderType

func (o OOBuyOther) OrderType() string

OrderType returns a string representation of this order's type

type OOBuyStock

type OOBuyStock struct {
	XMLName xml.Name `xml:"OOBUYSTOCK"`
	OO      OO       `xml:"OO"`
	BuyType buyType  `xml:"BUYTYPE"` // One of BUY, BUYTOCOVER
}

OOBuyStock represents an open order to purchase stock

func (OOBuyStock) OrderType

func (o OOBuyStock) OrderType() string

OrderType returns a string representation of this order's type

type OOList

type OOList []OpenOrder

OOList represents a list of open orders (OO* elements)

func (*OOList) MarshalXML

func (o *OOList) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML handles marshalling an OOList to an XML string

func (*OOList) UnmarshalXML

func (o *OOList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling an OOList element from an XML string

type OOSellDebt

type OOSellDebt struct {
	XMLName xml.Name `xml:"OOSELLDEBT"`
	OO      OO       `xml:"OO"`
}

OOSellDebt represents an open order to sell a debt security

func (OOSellDebt) OrderType

func (o OOSellDebt) OrderType() string

OrderType returns a string representation of this order's type

type OOSellMF

type OOSellMF struct {
	XMLName  xml.Name `xml:"OOSELLMF"`
	OO       OO       `xml:"OO"`
	SellType sellType `xml:"SELLTYPE"` // One of SELL, SELLSHORT
	UnitType unitType `xml:"UNITTYPE"` // What the units represent: one of SHARES, CURRENCY
	SellAll  Boolean  `xml:"SELLALL"`  // Sell entire holding
}

OOSellMF represents an open order to sell a mutual fund

func (OOSellMF) OrderType

func (o OOSellMF) OrderType() string

OrderType returns a string representation of this order's type

type OOSellOpt

type OOSellOpt struct {
	XMLName     xml.Name    `xml:"OOSELLOPT"`
	OO          OO          `xml:"OO"`
	OptSellType optSellType `xml:"OPTSELLTYPE"` // One of SELLTOOPEN, SELLTOCLOSE
}

OOSellOpt represents an open order to sell an option

func (OOSellOpt) OrderType

func (o OOSellOpt) OrderType() string

OrderType returns a string representation of this order's type

type OOSellOther

type OOSellOther struct {
	XMLName  xml.Name `xml:"OOSELLOTHER"`
	OO       OO       `xml:"OO"`
	UnitType unitType `xml:"UNITTYPE"` // What the units represent: one of SHARES, CURRENCY
}

OOSellOther represents an open order to sell a security type not covered by the other OOSell* elements

func (OOSellOther) OrderType

func (o OOSellOther) OrderType() string

OrderType returns a string representation of this order's type

type OOSellStock

type OOSellStock struct {
	XMLName  xml.Name `xml:"OOSELLSTOCK"`
	OO       OO       `xml:"OO"`
	SellType sellType `xml:"SELLTYPE"` // One of SELL, SELLSHORT
}

OOSellStock represents an open order to sell stock

func (OOSellStock) OrderType

func (o OOSellStock) OrderType() string

OrderType returns a string representation of this order's type

type OOSwitchMF

type OOSwitchMF struct {
	XMLName   xml.Name   `xml:"SWITCHMF"`
	OO        OO         `xml:"OO"`
	SecID     SecurityID `xml:"SECID"`     // Security ID of the fund to switch to or purchase
	UnitType  unitType   `xml:"UNITTYPE"`  // What the units represent: one of SHARES, CURRENCY
	SwitchAll Boolean    `xml:"SWITCHALL"` // Switch entire holding
}

OOSwitchMF represents an open order to switch to or purchase a different mutual fund

func (OOSwitchMF) OrderType

func (o OOSwitchMF) OrderType() string

OrderType returns a string representation of this order's type

type OpenOrder

type OpenOrder interface {
	OrderType() string
}

OpenOrder is an interface satisfied by all the OO* elements.

type OptInfo

type OptInfo struct {
	XMLName      xml.Name    `xml:"OPTINFO"`
	SecInfo      SecInfo     `xml:"SECINFO"`
	OptType      optType     `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   assetClass  `xml:"ASSETCLASS,omitempty"`   // One of DOMESTICBOND, INTLBOND, LARGESTOCK, SMALLSTOCK, INTLSTOCK, MONEYMRKT, OTHER
	FiAssetClass String      `xml:"FIASSETCLASS,omitempty"` // FI-defined asset class
}

OptInfo provides information about an option

func (OptInfo) SecurityType

func (i OptInfo) SecurityType() string

SecurityType returns a string representation of this security's type

type OptPosition

type OptPosition struct {
	XMLName xml.Name    `xml:"POSOPT"`
	InvPos  InvPosition `xml:"INVPOS"`
	Secured secured     `xml:"SECURED,omitempty"` // One of NAKED, COVERED
}

OptPosition represents a position held in an option

func (OptPosition) PositionType

func (p OptPosition) PositionType() string

PositionType returns a string representation of this position's type

type OtherInfo

type OtherInfo struct {
	XMLName      xml.Name   `xml:"OTHERINFO"`
	SecInfo      SecInfo    `xml:"SECINFO"`
	TypeDesc     String     `xml:"TYPEDESC,omitempty"`     // Description of security type
	AssetClass   assetClass `xml:"ASSETCLASS,omitempty"`   // One of DOMESTICBOND, INTLBOND, LARGESTOCK, SMALLSTOCK, INTLSTOCK, MONEYMRKT, OTHER
	FiAssetClass String     `xml:"FIASSETCLASS,omitempty"` // FI-defined asset class
}

OtherInfo provides information about a security type not covered by the other *Info elements

func (OtherInfo) SecurityType

func (i OtherInfo) SecurityType() string

SecurityType returns a string representation of this security's type

type OtherPosition

type OtherPosition struct {
	XMLName xml.Name    `xml:"POSOTHER"`
	InvPos  InvPosition `xml:"INVPOS"`
}

OtherPosition represents a position held in a security type not covered by the other *Position elements

func (OtherPosition) PositionType

func (p OtherPosition) PositionType() string

PositionType returns a string representation of this position's type

type Payee

type Payee struct {
	XMLName    xml.Name `xml:"PAYEE"`
	Name       String   `xml:"NAME"`
	Addr1      String   `xml:"ADDR1"`
	Addr2      String   `xml:"ADDR2,omitempty"`
	Addr3      String   `xml:"ADDR3,omitempty"`
	City       String   `xml:"CITY"`
	State      String   `xml:"STATE"`
	PostalCode String   `xml:"POSTALCODE"`
	Country    String   `xml:"COUNTRY,omitempty"`
	Phone      String   `xml:"PHONE"`
}

Payee specifies a complete billing address for a payee

func (Payee) Valid

func (p Payee) Valid() (bool, error)

Valid returns (true, nil) if this struct is valid OFX

type PendingTransaction

type PendingTransaction struct {
	XMLName   xml.Name    `xml:"STMTTRNP"`
	TrnType   trnType     `xml:"TRNTYPE"` // One of CREDIT, DEBIT, INT (interest earned or paid. Note: Depends on signage of amount), DIV, FEE, SRVCHG (service charge), DEP (deposit), ATM (Note: Depends on signage of amount), POS (Note: Depends on signage of amount), XFER, CHECK, PAYMENT, CASH, DIRECTDEP, DIRECTDEBIT, REPEATPMT, HOLD, OTHER
	DtTran    Date        `xml:"DTTRAN"`
	DtExpire  *Date       `xml:"DTEXPIRE,omitempty"` // only valid for TrnType==HOLD, the date the hold will expire
	TrnAmt    Amount      `xml:"TRNAMT"`
	RefNum    String      `xml:"REFNUM,omitempty"`
	Name      String      `xml:"NAME,omitempty"`
	ExtdName  String      `xml:"EXTDNAME,omitempty"` // Extended name of payee or transaction description
	Memo      String      `xml:"MEMO,omitempty"`     // Extra information (not in NAME)
	ImageData []ImageData `xml:"IMAGEDATA,omitempty"`

	// Only one of Currency and OrigCurrency can ever be Valid() for the same transaction
	Currency     Currency `xml:"CURRENCY,omitempty"`     // Represents the currency of TrnAmt (instead of CURDEF in STMTRS) if Valid
	OrigCurrency Currency `xml:"ORIGCURRENCY,omitempty"` // Represents the currency TrnAmt was converted to STMTRS' CURDEF from if Valid
}

PendingTransaction represents a single pending transaction. It is similar to Transaction, but is not finalized (and may never be). For instance, it lacks FiTID and DtPosted fields.

func (PendingTransaction) Valid

func (t PendingTransaction) Valid() (bool, error)

Valid returns (true, nil) if this struct is valid OFX

type PendingTransactionList

type PendingTransactionList struct {
	XMLName      xml.Name             `xml:"BANKTRANLISTP"`
	DtAsOf       Date                 `xml:"DTASOF"` // Date and time this set of pending transactions was generated
	Transactions []PendingTransaction `xml:"STMTTRNP,omitempty"`
}

PendingTransactionList represents a list of pending transactions, along with the date they were generated

func (PendingTransactionList) Valid

func (l PendingTransactionList) Valid() (bool, error)

Valid returns (true, nil) if this struct is valid OFX

type Position

type Position interface {
	PositionType() string
}

Position is an interface satisfied by all the other *Position types

type PositionList

type PositionList []Position

PositionList represents a list of positions held in securities in an investment account

func (*PositionList) MarshalXML

func (p *PositionList) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML handles marshalling a PositionList to an XML string

func (*PositionList) UnmarshalXML

func (p *PositionList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling a PositionList from an XML string

type ProfileRequest

type ProfileRequest struct {
	XMLName   xml.Name `xml:"PROFTRNRQ"`
	TrnUID    UID      `xml:"TRNUID"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	TAN       String   `xml:"TAN,omitempty"` // Transaction authorization number
	// TODO `xml:"OFXEXTENSION,omitempty"`
	ClientRouting String `xml:"PROFRQ>CLIENTROUTING"` // Forced to NONE
	DtProfUp      Date   `xml:"PROFRQ>DTPROFUP"`      // Date and time client last received a profile update
}

ProfileRequest represents a request for a server to provide a profile of its capabilities (which message sets and versions it supports, how to access them, which languages and which types of synchronization they support, etc.)

func (*ProfileRequest) Name

func (r *ProfileRequest) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*ProfileRequest) Type

func (r *ProfileRequest) Type() messageType

Type returns which message set this message belongs to (which Request element of type []Message it should appended to)

func (*ProfileRequest) Valid

func (r *ProfileRequest) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct would be valid OFX if marshalled into XML/SGML

type ProfileResponse

type ProfileResponse struct {
	XMLName   xml.Name `xml:"PROFTRNRS"`
	TrnUID    UID      `xml:"TRNUID"`
	Status    Status   `xml:"STATUS"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	// TODO `xml:"OFXEXTENSION,omitempty"`
	MessageSetList MessageSetList `xml:"PROFRS>MSGSETLIST"`
	SignonInfoList []SignonInfo   `xml:"PROFRS>SIGNONINFOLIST>SIGNONINFO"`
	DtProfUp       Date           `xml:"PROFRS>DTPROFUP"`
	FiName         String         `xml:"PROFRS>FINAME"`
	Addr1          String         `xml:"PROFRS>ADDR1"`
	Addr2          String         `xml:"PROFRS>ADDR2,omitempty"`
	Addr3          String         `xml:"PROFRS>ADDR3,omitempty"`
	City           String         `xml:"PROFRS>CITY"`
	State          String         `xml:"PROFRS>STATE"`
	PostalCode     String         `xml:"PROFRS>POSTALCODE"`
	Country        String         `xml:"PROFRS>COUNTRY"`
	CsPhone        String         `xml:"PROFRS>CSPHONE,omitempty"`
	TsPhone        String         `xml:"PROFRS>TSPHONE,omitempty"`
	FaxPhone       String         `xml:"PROFRS>FAXPHONE,omitempty"`
	URL            String         `xml:"PROFRS>URL,omitempty"`
	Email          String         `xml:"PROFRS>EMAIL,omitempty"`
}

ProfileResponse contains a requested profile of the server's capabilities (which message sets and versions it supports, how to access them, which languages and which types of synchronization they support, etc.). Note that if the server does not support ClientRouting=NONE (as we always send with ProfileRequest), this may be an error)

func (*ProfileResponse) Name

func (pr *ProfileResponse) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*ProfileResponse) Type

func (pr *ProfileResponse) Type() messageType

Type returns which message set this message belongs to (which Response element of type []Message it belongs to)

func (*ProfileResponse) Valid

func (pr *ProfileResponse) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct was valid OFX when unmarshalled

type Reinvest

type Reinvest struct {
	XMLName       xml.Name      `xml:"REINVEST"`
	InvTran       InvTran       `xml:"INVTRAN"`
	SecID         SecurityID    `xml:"SECID"`
	IncomeType    incomeType    `xml:"INCOMETYPE"` // Type of investment income: CGLONG (capital gains-long term), CGSHORT (capital gains-short term), DIV (dividend), INTEREST, MISC
	Total         Amount        `xml:"TOTAL"`      // Transaction total. Buys, sells, etc.:((quan. * (price +/- markup/markdown)) +/-(commission + fees + load + taxes + penalty + withholding + statewithholding)). Distributions, interest, margin interest, misc. expense, etc.: amount. Return of cap: cost basis
	SubAcctSec    subAcctType   `xml:"SUBACCTSEC"` // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
	Units         Amount        `xml:"UNITS"`      // For stocks, MFs, other, number of shares held. Bonds = face value. Options = number of contracts
	UnitPrice     Amount        `xml:"UNITPRICE"`  // For stocks, MFs, other, price per share. Bonds = percentage of par. Option = premium per share of underlying security
	Commission    Amount        `xml:"COMMISSION,omitempty"`
	Taxes         Amount        `xml:"TAXES,omitempty"`
	Fees          Amount        `xml:"FEES,omitempty"`
	Load          Amount        `xml:"LOAD,omitempty"`
	TaxExempt     Boolean       `xml:"TAXEXEMPT,omitempty"`     // Tax-exempt transaction
	Currency      Currency      `xml:"CURRENCY,omitempty"`      // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
	OrigCurrency  Currency      `xml:"ORIGCURRENCY,omitempty"`  // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}

Reinvest is a single transaction that contains both income and an investment transaction. If servers can’t track this as a single transaction they should return an Income transaction and an InvTran.

func (Reinvest) TransactionType

func (t Reinvest) TransactionType() string

TransactionType returns a string representation of this transaction's type

type Request

type Request struct {
	URL        string
	Version    ofxVersion    // OFX version, overwritten in Client.Request()
	Signon     SignonRequest //<SIGNONMSGSETV1>
	Signup     []Message     //<SIGNUPMSGSETV1>
	Bank       []Message     //<BANKMSGSETV1>
	CreditCard []Message     //<CREDITCARDMSGSETV1>
	Loan       []Message     //<LOANMSGSETV1>
	InvStmt    []Message     //<INVSTMTMSGSETV1>
	InterXfer  []Message     //<INTERXFERMSGSETV1>
	WireXfer   []Message     //<WIREXFERMSGSETV1>
	Billpay    []Message     //<BILLPAYMSGSETV1>
	Email      []Message     //<EMAILMSGSETV1>
	SecList    []Message     //<SECLISTMSGSETV1>
	PresDir    []Message     //<PRESDIRMSGSETV1>
	PresDlv    []Message     //<PRESDLVMSGSETV1>
	Prof       []Message     //<PROFMSGSETV1>
	Image      []Message     //<IMAGEMSGSETV1>
	// contains filtered or unexported fields
}

Request is the top-level object marshalled and sent to OFX servers. It is constructed by appending one or more request objects to the message set they correspond to (i.e. appending StatementRequest to Request.Bank to get a bank statemement). If a *Request object is appended to the wrong message set, an error will be returned when Marshal() is called on this Request.

func (*Request) Marshal

func (oq *Request) Marshal() (*bytes.Buffer, error)

Marshal this Request into its SGML/XML representation held in a bytes.Buffer

If error is non-nil, this bytes.Buffer is ready to be sent to an OFX server

func (*Request) SetClientFields

func (oq *Request) SetClientFields(c Client)

SetClientFields overwrites the fields in this Request object controlled by the Client

type Response

type Response struct {
	Version    ofxVersion     // OFX header version
	Signon     SignonResponse //<SIGNONMSGSETV1>
	Signup     []Message      //<SIGNUPMSGSETV1>
	Bank       []Message      //<BANKMSGSETV1>
	CreditCard []Message      //<CREDITCARDMSGSETV1>
	Loan       []Message      //<LOANMSGSETV1>
	InvStmt    []Message      //<INVSTMTMSGSETV1>
	InterXfer  []Message      //<INTERXFERMSGSETV1>
	WireXfer   []Message      //<WIREXFERMSGSETV1>
	Billpay    []Message      //<BILLPAYMSGSETV1>
	Email      []Message      //<EMAILMSGSETV1>
	SecList    []Message      //<SECLISTMSGSETV1>
	PresDir    []Message      //<PRESDIRMSGSETV1>
	PresDlv    []Message      //<PRESDLVMSGSETV1>
	Prof       []Message      //<PROFMSGSETV1>
	Image      []Message      //<IMAGEMSGSETV1>
}

Response is the top-level object returned from a parsed OFX response file. It can be inspected by using type assertions or switches on the message set you're interested in.

func ParseResponse

func ParseResponse(reader io.Reader) (*Response, error)

ParseResponse parses an OFX response in SGML or XML into a Response object from the given io.Reader

It is commonly used as part of Client.Request(), but may be used on its own to parse already-downloaded OFX files (such as those from 'Web Connect'). It performs version autodetection if it can and attempts to be as forgiving as possible about the input format.

func (*Response) Marshal

func (or *Response) Marshal() (*bytes.Buffer, error)

Marshal this Response into its SGML/XML representation held in a bytes.Buffer

If error is non-nil, this bytes.Buffer is ready to be sent to an OFX client

type RetOfCap

type RetOfCap struct {
	XMLName       xml.Name      `xml:"RETOFCAP"`
	InvTran       InvTran       `xml:"INVTRAN"`
	SecID         SecurityID    `xml:"SECID"`
	Total         Amount        `xml:"TOTAL"`
	SubAcctSec    subAcctType   `xml:"SUBACCTSEC"`              // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
	SubAcctFund   subAcctType   `xml:"SUBACCTFUND"`             // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
	Currency      Currency      `xml:"CURRENCY,omitempty"`      // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
	OrigCurrency  Currency      `xml:"ORIGCURRENCY,omitempty"`  // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}

RetOfCap represents a transaction where capital is being returned to the account holder

func (RetOfCap) TransactionType

func (t RetOfCap) TransactionType() string

TransactionType returns a string representation of this transaction's type

type SecInfo

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"`
}

SecInfo represents the generic information about a security. It is included in most other *Info elements.

type SecListRequest

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
	// TODO `xml:"OFXEXTENSION,omitempty"`
	Securities []SecurityRequest `xml:"SECLISTRQ>SECRQ,omitempty"`
}

SecListRequest represents a request for information (namely price) about one or more securities

func (*SecListRequest) Name

func (r *SecListRequest) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*SecListRequest) Type

func (r *SecListRequest) Type() messageType

Type returns which message set this message belongs to (which Request element of type []Message it should appended to)

func (*SecListRequest) Valid

func (r *SecListRequest) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct would be valid OFX if marshalled into XML/SGML

type SecListResponse

type SecListResponse struct {
	XMLName   xml.Name `xml:"SECLISTTRNRS"`
	TrnUID    UID      `xml:"TRNUID"`
	Status    Status   `xml:"STATUS"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
}

SecListResponse is always empty (except for the transaction UID, status, and optional client cookie). Its presence signifies that the SecurityList (a different element from this one) immediately after this element in Response.SecList was been generated in response to the same SecListRequest this is a response to.

func (*SecListResponse) Name

func (r *SecListResponse) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*SecListResponse) Type

func (r *SecListResponse) Type() messageType

Type returns which message set this message belongs to (which Response element of type []Message it belongs to)

func (*SecListResponse) Valid

func (r *SecListResponse) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct was valid OFX when unmarshalled

type Security

type Security interface {
	SecurityType() string
}

Security is satisfied by all *Info elements providing information about securities for SecurityList

type SecurityID

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
}

SecurityID identifies a security by its CUSIP (for US-based FI's, others may use UniqueID types other than CUSIP)

type SecurityList

type SecurityList struct {
	XMLName    xml.Name `xml:"SECLIST"`
	Securities []Security
}

SecurityList is a container for Security objects containaing information about securities

func (*SecurityList) MarshalXML

func (r *SecurityList) MarshalXML(e *xml.Encoder, start xml.StartElement) error

MarshalXML handles marshalling a SecurityList to an SGML/XML string

func (*SecurityList) Name

func (r *SecurityList) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*SecurityList) Type

func (r *SecurityList) Type() messageType

Type returns which message set this message belongs to (which Response element of type []Message it belongs to)

func (*SecurityList) UnmarshalXML

func (r *SecurityList) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling a SecurityList from an SGML/XML string

func (*SecurityList) Valid

func (r *SecurityList) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct was valid OFX when unmarshalled

type SecurityRequest

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"`
}

SecurityRequest represents a request for one security. It is specified with a SECID aggregate, a ticker symbol, or an FI assigned identifier (but no more than one of them at a time)

type SellDebt

type SellDebt struct {
	XMLName    xml.Name   `xml:"SELLDEBT"`
	InvSell    InvSell    `xml:"INVSELL"`
	SellReason sellReason `xml:"SELLREASON"`         // CALL (the debt was called), SELL (the debt was sold), MATURITY (the debt reached maturity)
	AccrdInt   Amount     `xml:"ACCRDINT,omitempty"` // Accrued interest
}

SellDebt represents the sale of a debt security. Used when debt is sold, called, or reaches maturity.

func (SellDebt) TransactionType

func (t SellDebt) TransactionType() string

TransactionType returns a string representation of this transaction's type

type SellMF

type SellMF struct {
	XMLName      xml.Name `xml:"SELLMF"`
	InvSell      InvSell  `xml:"INVSELL"`
	SellType     sellType `xml:"SELLTYPE"` // Type of sell. SELL, SELLSHORT
	AvgCostBasis Amount   `xml:"AVGCOSTBASIS"`
	RelFiTID     String   `xml:"RELFITID,omitempty"` // used to relate transactions associated with mutual fund exchanges
}

SellMF represents a transaction selling a mutual fund

func (SellMF) TransactionType

func (t SellMF) TransactionType() string

TransactionType returns a string representation of this transaction's type

type SellOpt

type SellOpt struct {
	XMLName     xml.Name    `xml:"SELLOPT"`
	InvSell     InvSell     `xml:"INVSELL"`
	OptSellType optSellType `xml:"OPTSELLTYPE"`        // For options, type of sell: SELLTOCLOSE, SELLTOOPEN. The SELLTOCLOSE action is selling a previously bought option. The SELLTOOPEN action is writing an option
	ShPerCtrct  Int         `xml:"SHPERCTRCT"`         // Shares per contract
	RelFiTID    String      `xml:"RELFITID,omitempty"` // used to relate transactions associated with mutual fund exchanges
	RelType     relType     `xml:"RELTYPE,omitempty"`  // Related option transaction type: SPREAD, STRADDLE, NONE, OTHER
	Secured     secured     `xml:"SECURED,omitempty"`  // NAKED, COVERED
}

SellOpt represents a transaction selling an option. Depending on the value of OptSellType, can be used to sell a previously bought option or write a new option.

func (SellOpt) TransactionType

func (t SellOpt) TransactionType() string

TransactionType returns a string representation of this transaction's type

type SellOther

type SellOther struct {
	XMLName xml.Name `xml:"SELLOTHER"`
	InvSell InvSell  `xml:"INVSELL"`
}

SellOther represents a transaction selling a security type not covered by the other Sell* structs

func (SellOther) TransactionType

func (t SellOther) TransactionType() string

TransactionType returns a string representation of this transaction's type

type SellStock

type SellStock struct {
	XMLName  xml.Name `xml:"SELLSTOCK"`
	InvSell  InvSell  `xml:"INVSELL"`
	SellType sellType `xml:"SELLTYPE"` // Type of sell. SELL, SELLSHORT
}

SellStock represents a transaction selling stock

func (SellStock) TransactionType

func (t SellStock) TransactionType() string

TransactionType returns a string representation of this transaction's type

type SignonInfo

type SignonInfo struct {
	XMLName           xml.Name `xml:"SIGNONINFO"`
	SignonRealm       String   `xml:"SIGNONREALM"`              // The SignonRealm for which this SignonInfo provides information. This SignonInfo is valid for all MessageSets with SignonRealm fields matching this one
	Min               Int      `xml:"MIN"`                      // Minimum number of password characters
	Max               Int      `xml:"MAX"`                      // Maximum number of password characters
	CharType          charType `xml:"CHARTYPE"`                 // One of ALPHAONLY, NUMERICONLY, ALPHAORNUMERIC, ALPHAANDNUMERIC
	CaseSen           Boolean  `xml:"CASESEN"`                  // Password is case-sensitive?
	Special           Boolean  `xml:"SPECIAL"`                  // Special characters allowed?
	Spaces            Boolean  `xml:"SPACES"`                   // Spaces allowed?
	PinCh             Boolean  `xml:"PINCH"`                    // Pin change <PINCHRQ> requests allowed
	ChgPinFirst       Boolean  `xml:"CHGPINFIRST"`              // Server requires user to change password at first signon
	UserCred1Label    String   `xml:"USERCRED1LABEL,omitempty"` // Prompt for USERCRED1 (if this field is present, USERCRED1 is required)
	UserCred2Label    String   `xml:"USERCRED2LABEL,omitempty"` // Prompt for USERCRED2 (if this field is present, USERCRED2 is required)
	ClientUIDReq      Boolean  `xml:"CLIENTUIDREQ,omitempty"`   // CLIENTUID required?
	AuthTokenFirst    Boolean  `xml:"AUTHTOKENFIRST,omitempty"` // Server requires AUTHTOKEN as part of first signon
	AuthTokenLabel    String   `xml:"AUTHTOKENLABEL,omitempty"`
	AuthTokenInfoURL  String   `xml:"AUTHTOKENINFOURL,omitempty"`
	MFAChallengeSupt  Boolean  `xml:"MFACHALLENGESUPT,omitempty"`  // Server supports MFACHALLENGE
	MFAChallengeFIRST Boolean  `xml:"MFACHALLENGEFIRST,omitempty"` // Server requires MFACHALLENGE to be sent with first signon
	AccessTokenReq    Boolean  `xml:"ACCESSTOKENREQ,omitempty"`    // Server requires ACCESSTOKEN to be sent with all requests except profile
}

SignonInfo provides the requirements to login to a single signon realm. A signon realm consists of all MessageSets which can be accessed using one set of login credentials. Most FI's only use one signon realm to make it easier and less confusing for the user.

type SignonRequest

type SignonRequest struct {
	XMLName   xml.Name `xml:"SONRQ"`
	DtClient  Date     `xml:"DTCLIENT"` // Current time on client, overwritten in Client.Request()
	UserID    String   `xml:"USERID"`
	UserPass  String   `xml:"USERPASS,omitempty"`
	UserKey   String   `xml:"USERKEY,omitempty"`
	Language  String   `xml:"LANGUAGE"` // Defaults to ENG
	Org       String   `xml:"FI>ORG"`
	Fid       String   `xml:"FI>FID"`
	AppID     String   `xml:"APPID"`  // Overwritten in Client.Request()
	AppVer    String   `xml:"APPVER"` // Overwritten in Client.Request()
	ClientUID UID      `xml:"CLIENTUID,omitempty"`
}

SignonRequest identifies and authenticates a user to their FI and is provided with every Request

func (*SignonRequest) Name

func (r *SignonRequest) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*SignonRequest) Valid

func (r *SignonRequest) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct would be valid OFX if marshalled into XML/SGML

type SignonResponse

type SignonResponse struct {
	XMLName     xml.Name `xml:"SONRS"`
	Status      Status   `xml:"STATUS"`
	DtServer    Date     `xml:"DTSERVER"`
	UserKey     String   `xml:"USERKEY,omitempty"`
	TsKeyExpire *Date    `xml:"TSKEYEXPIRE,omitempty"`
	Language    String   `xml:"LANGUAGE"`
	DtProfUp    *Date    `xml:"DTPROFUP,omitempty"`
	DtAcctUp    *Date    `xml:"DTACCTUP,omitempty"`
	Org         String   `xml:"FI>ORG"`
	Fid         String   `xml:"FI>FID"`
	SessCookie  String   `xml:"SESSCOOKIE,omitempty"`
	AccessKey   String   `xml:"ACCESSKEY,omitempty"`
}

SignonResponse is provided with every Response and indicates the success or failure of the SignonRequest in the corresponding Request

func (*SignonResponse) Name

func (r *SignonResponse) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*SignonResponse) Valid

func (r *SignonResponse) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct was valid OFX when unmarshalled

type Split

type Split struct {
	XMLName       xml.Name      `xml:"SPLIT"`
	InvTran       InvTran       `xml:"INVTRAN"`
	SecID         SecurityID    `xml:"SECID"`
	SubAcctSec    subAcctType   `xml:"SUBACCTSEC"`              // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
	OldUnits      Amount        `xml:"OLDUNITS"`                // number of shares before the split
	NewUnits      Amount        `xml:"NEWUNITS"`                // number of shares after the split
	Numerator     Int           `xml:"NUMERATOR"`               // split ratio numerator
	Denominator   Int           `xml:"DENOMINATOR"`             // split ratio denominator
	Currency      Currency      `xml:"CURRENCY,omitempty"`      // Represents the currency this transaction is in (instead of CURDEF in INVSTMTRS) if Valid()
	OrigCurrency  Currency      `xml:"ORIGCURRENCY,omitempty"`  // Represents the currency this transaction was converted to INVSTMTRS' CURDEF from if Valid
	FracCash      Amount        `xml:"FRACCASH,omitempty"`      // cash for fractional units
	SubAcctFund   subAcctType   `xml:"SUBACCTFUND,omitempty"`   // Where did the money for the transaction come from or go to? CASH, MARGIN, SHORT, OTHER
	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}

Split represents a stock or mutual fund split

func (Split) TransactionType

func (t Split) TransactionType() string

TransactionType returns a string representation of this transaction's type

type StatementRequest

type StatementRequest struct {
	XMLName   xml.Name `xml:"STMTTRNRQ"`
	TrnUID    UID      `xml:"TRNUID"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	TAN       String   `xml:"TAN,omitempty"` // Transaction authorization number
	// TODO `xml:"OFXEXTENSION,omitempty"`
	BankAcctFrom   BankAcct `xml:"STMTRQ>BANKACCTFROM"`
	DtStart        *Date    `xml:"STMTRQ>INCTRAN>DTSTART,omitempty"`
	DtEnd          *Date    `xml:"STMTRQ>INCTRAN>DTEND,omitempty"`
	Include        Boolean  `xml:"STMTRQ>INCTRAN>INCLUDE"`          // Include transactions (instead of just balance)
	IncludePending Boolean  `xml:"STMTRQ>INCLUDEPENDING,omitempty"` // Include pending transactions
	IncTranImg     Boolean  `xml:"STMTRQ>INCTRANIMG,omitempty"`     // Include transaction images
}

StatementRequest represents a request for a bank statement. It is used to request balances and/or transactions for checking, savings, money market, and line of credit accounts. See CCStatementRequest for the analog for credit card accounts.

func (*StatementRequest) Name

func (r *StatementRequest) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*StatementRequest) Type

func (r *StatementRequest) Type() messageType

Type returns which message set this message belongs to (which Request element of type []Message it should appended to)

func (*StatementRequest) Valid

func (r *StatementRequest) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct would be valid OFX if marshalled into XML/SGML

type StatementResponse

type StatementResponse struct {
	XMLName   xml.Name `xml:"STMTTRNRS"`
	TrnUID    UID      `xml:"TRNUID"`
	Status    Status   `xml:"STATUS"`
	CltCookie String   `xml:"CLTCOOKIE,omitempty"`
	// TODO `xml:"OFXEXTENSION,omitempty"`
	CurDef        CurrSymbol              `xml:"STMTRS>CURDEF"`
	BankAcctFrom  BankAcct                `xml:"STMTRS>BANKACCTFROM"`
	BankTranList  *TransactionList        `xml:"STMTRS>BANKTRANLIST,omitempty"`
	BankTranListP *PendingTransactionList `xml:"STMTRS>BANKTRANLISTP,omitempty"`
	BalAmt        Amount                  `xml:"STMTRS>LEDGERBAL>BALAMT"`
	DtAsOf        Date                    `xml:"STMTRS>LEDGERBAL>DTASOF"`
	AvailBalAmt   *Amount                 `xml:"STMTRS>AVAILBAL>BALAMT,omitempty"`
	AvailDtAsOf   *Date                   `xml:"STMTRS>AVAILBAL>DTASOF,omitempty"`
	CashAdvBalAmt *Amount                 `xml:"STMTRS>CASHADVBALAMT,omitempty"` // Only for CREDITLINE accounts, available balance for cash advances
	IntRate       *Amount                 `xml:"STMTRS>INTRATE,omitempty"`       // Current interest rate
	BalList       []Balance               `xml:"STMTRS>BALLIST>BAL,omitempty"`
	MktgInfo      String                  `xml:"STMTRS>MKTGINFO,omitempty"` // Marketing information
}

StatementResponse represents a bank account statement, including its balances and possibly transactions. It is a response to StatementRequest, or sometimes provided as part of an OFX file downloaded manually from an FI.

func (*StatementResponse) Name

func (sr *StatementResponse) Name() string

Name returns the name of the top-level transaction XML/SGML element

func (*StatementResponse) Type

func (sr *StatementResponse) Type() messageType

Type returns which message set this message belongs to (which Response element of type []Message it belongs to)

func (*StatementResponse) Valid

func (sr *StatementResponse) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct was valid OFX when unmarshalled

type Status

type Status struct {
	XMLName  xml.Name `xml:"STATUS"`
	Code     Int      `xml:"CODE"`
	Severity String   `xml:"SEVERITY"`
	Message  String   `xml:"MESSAGE,omitempty"`
}

Status represents the status of a Response (both top-level Request objects, and *Response objects)

func (*Status) CodeConditions

func (s *Status) CodeConditions() (string, error)

CodeConditions returns the conditions under which an OFX server is expected to return the current status Code

func (*Status) CodeMeaning

func (s *Status) CodeMeaning() (string, error)

CodeMeaning returns the meaning of the current status Code

func (*Status) Valid

func (s *Status) Valid() (bool, error)

Valid returns whether the Status is valid according to the OFX spec

type StockInfo

type StockInfo struct {
	XMLName      xml.Name   `xml:"STOCKINFO"`
	SecInfo      SecInfo    `xml:"SECINFO"`
	StockType    stockType  `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   assetClass `xml:"ASSETCLASS,omitempty"`   // One of DOMESTICBOND, INTLBOND, LARGESTOCK, SMALLSTOCK, INTLSTOCK, MONEYMRKT, OTHER
	FiAssetClass String     `xml:"FIASSETCLASS,omitempty"` // FI-defined asset class
}

StockInfo provides information about a security type

func (StockInfo) SecurityType

func (i StockInfo) SecurityType() string

SecurityType returns a string representation of this security's type

type StockPosition

type StockPosition struct {
	XMLName     xml.Name    `xml:"POSSTOCK"`
	InvPos      InvPosition `xml:"INVPOS"`
	UnitsStreet Amount      `xml:"UNITSSTREET,omitempty"` // Units in the FI’s street name
	UnitsUser   Amount      `xml:"UNITSUSER,omitempty"`   // Units in the user's name directly
	ReinvDiv    Boolean     `xml:"REINVDIV,omitempty"`    // Reinvest dividends
}

StockPosition represents a position held in a stock

func (StockPosition) PositionType

func (p StockPosition) PositionType() string

PositionType returns a string representation of this position's type

type String

type String string

String provides helper methods to unmarshal OFX string values from SGML/XML

func (String) Equal

func (os String) Equal(o String) bool

Equal returns true if the two Strings are equal in value

func (*String) String

func (os *String) String() string

String returns the string

func (*String) UnmarshalXML

func (os *String) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling a String from an SGML/XML string. Leading and trailing whitespace is ignored.

type Transaction

type Transaction struct {
	XMLName       xml.Name      `xml:"STMTTRN"`
	TrnType       trnType       `xml:"TRNTYPE"` // One of CREDIT, DEBIT, INT (interest earned or paid. Note: Depends on signage of amount), DIV, FEE, SRVCHG (service charge), DEP (deposit), ATM (Note: Depends on signage of amount), POS (Note: Depends on signage of amount), XFER, CHECK, PAYMENT, CASH, DIRECTDEP, DIRECTDEBIT, REPEATPMT, OTHER
	DtPosted      Date          `xml:"DTPOSTED"`
	DtUser        *Date         `xml:"DTUSER,omitempty"`
	DtAvail       *Date         `xml:"DTAVAIL,omitempty"`
	TrnAmt        Amount        `xml:"TRNAMT"`
	FiTID         String        `xml:"FITID"`                   // Client uses FITID to detect whether it has previously downloaded the transaction
	CorrectFiTID  String        `xml:"CORRECTFITID,omitempty"`  // Transaction ID that this transaction corrects, if present
	CorrectAction correctAction `xml:"CORRECTACTION,omitempty"` // One of DELETE, REPLACE
	SrvrTID       String        `xml:"SRVRTID,omitempty"`
	CheckNum      String        `xml:"CHECKNUM,omitempty"`
	RefNum        String        `xml:"REFNUM,omitempty"`
	SIC           Int           `xml:"SIC,omitempty"` // Standard Industrial Code
	PayeeID       String        `xml:"PAYEEID,omitempty"`
	// Note: Servers should provide NAME or PAYEE, but not both
	Name       String      `xml:"NAME,omitempty"`
	Payee      *Payee      `xml:"PAYEE,omitempty"`
	ExtdName   String      `xml:"EXTDNAME,omitempty"`   // Extended name of payee or transaction description
	BankAcctTo *BankAcct   `xml:"BANKACCTTO,omitempty"` // If the transfer was to a bank account we have the account information for
	CCAcctTo   *CCAcct     `xml:"CCACCTTO,omitempty"`   // If the transfer was to a credit card account we have the account information for
	Memo       String      `xml:"MEMO,omitempty"`       // Extra information (not in NAME)
	ImageData  []ImageData `xml:"IMAGEDATA,omitempty"`

	// Only one of Currency and OrigCurrency can ever be Valid() for the same transaction
	Currency      *Currency     `xml:"CURRENCY,omitempty"`      // Represents the currency of TrnAmt (instead of CURDEF in STMTRS) if Valid
	OrigCurrency  *Currency     `xml:"ORIGCURRENCY,omitempty"`  // Represents the currency TrnAmt was converted to STMTRS' CURDEF from if Valid
	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST (Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST.)
}

Transaction represents a single banking transaction. At a minimum, it identifies the type of transaction (TrnType) and the date it was posted (DtPosted). Ideally it also provides metadata to help the user recognize this transaction (i.e. CheckNum, Name or Payee, Memo, etc.)

func (Transaction) Valid

func (t Transaction) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct is valid OFX

type TransactionList

type TransactionList struct {
	XMLName      xml.Name      `xml:"BANKTRANLIST"`
	DtStart      Date          `xml:"DTSTART"` // Start date for transaction data
	DtEnd        Date          `xml:"DTEND"`   // Value that client should send in next <DTSTART> request to ensure that it does not miss any transactions
	Transactions []Transaction `xml:"STMTTRN,omitempty"`
}

TransactionList represents a list of bank transactions, and also includes the date range its transactions cover.

func (TransactionList) Valid

func (l TransactionList) Valid(version ofxVersion) (bool, error)

Valid returns (true, nil) if this struct is valid OFX

type Transfer

type Transfer struct {
	XMLName       xml.Name      `xml:"TRANSFER"`
	InvTran       InvTran       `xml:"INVTRAN"`
	SecID         SecurityID    `xml:"SECID"`
	SubAcctSec    subAcctType   `xml:"SUBACCTSEC"` // Sub-account type for this security. One of CASH, MARGIN, SHORT, OTHER
	Units         Amount        `xml:"UNITS"`      // For stocks, MFs, other, number of shares held. Bonds = face value. Options = number of contracts
	TferAction    tferAction    `xml:"TFERACTION"` // One of IN, OUT
	PosType       posType       `xml:"POSTYPE"`    // Position type. One of LONG, SHORT
	InvAcctFrom   InvAcct       `xml:"INVACCTFROM,omitempty"`
	AvgCostBasis  Amount        `xml:"AVGCOSTBASIS,omitempty"`
	UnitPrice     Amount        `xml:"UNITPRICE,omitempty"` // For stocks, MFs, other, price per share. Bonds = percentage of par. Option = premium per share of underlying security
	DtPurchase    *Date         `xml:"DTPURCHASE,omitempty"`
	Inv401kSource inv401kSource `xml:"INV401KSOURCE,omitempty"` // Source of money for this transaction. One of PRETAX, AFTERTAX, MATCH, PROFITSHARING, ROLLOVER, OTHERVEST, OTHERNONVEST for 401(k) accounts. Default if not present is OTHERNONVEST. The following cash source types are subject to vesting: MATCH, PROFITSHARING, and OTHERVEST
}

Transfer represents the transfer of securities into or out of an account

func (Transfer) TransactionType

func (t Transfer) TransactionType() string

TransactionType returns a string representation of this transaction's type

type UID

type UID string

UID represents an UID according to the OFX spec

func RandomUID

func RandomUID() (*UID, error)

RandomUID creates a new randomly-generated UID

func (UID) Equal

func (ou UID) Equal(o UID) bool

Equal returns true if the two UIDs are the same

func (UID) RecommendedFormat

func (ou UID) RecommendedFormat() (bool, error)

RecommendedFormat returns true iff this UID meets the OFX specification's recommendation that UIDs follow the standard UUID 36-character format

func (*UID) UnmarshalXML

func (ou *UID) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error

UnmarshalXML handles unmarshalling an UID from an SGML/XML string. Leading and trailing whitespace is ignored.

func (UID) Valid

func (ou UID) Valid() (bool, error)

Valid returns true, nil if the UID is valid. This is less strict than RecommendedFormat, and will always return true, nil if it does.

type VanguardClient

type VanguardClient struct {
	*BasicClient
}

VanguardClient provides a Client implementation which handles Vanguard's cookie-passing requirements. VanguardClient uses default, non-zero settings, if its fields are not initialized.

func (*VanguardClient) Request

func (c *VanguardClient) Request(r *Request) (*Response, error)

func (*VanguardClient) RequestNoParse

func (c *VanguardClient) RequestNoParse(r *Request) (*http.Response, error)

type VestInfo

type VestInfo struct {
	XMLName  xml.Name `xml:"VESTINFO"`
	VestDate *Date    `xml:"VESTDATE,omitempty"` // Date at which vesting percentage changes. Default (if empty) is that the vesting percentage below applies to the current date
	VestPct  Amount   `xml:"VESTPCT"`
}

VestInfo provides the vesting percentage of a 401(k) account as of a particular date (past, present, or future)

Directories

Path Synopsis
cmd
ofx

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL