package questrade import ( "fmt" "net/url" "strconv" ) // Account represents an account associated with the user on behalf // of which the API client is authorized. // // Ref: http://www.questrade.com/api/documentation/rest-operations/account-calls/accounts type Account struct { // Type of the account (e.g., "Cash", "Margin"). Type string `json:"type"` // Eight-digit account number (e.g., "26598145") // Stored as a string, it's used for making account-related API calls Number string `json:"number"` // Status of the account (e.g., Active). Status string `json:"status"` // Whether this is a primary account for the holder. IsPrimary bool `json:"isPrimary"` // Whether this account is one that gets billed for various expenses such as inactivity fees, market data, etc. IsBilling bool `json:"isBilling"` // Type of client holding the account (e.g., "Individual"). ClientAccountType string `json:"clientAccountType"` } // Balance belonging to an Account // // Ref: http://www.questrade.com/api/documentation/rest-operations/account-calls/accounts-id-balances type Balance struct { // Currency of the balance figure(e.g., "USD" or "CAD"). Currency string `json:"currency"` // Balance amount. Cash float32 `json:"cash"` // Market value of all securities in the account in a given currency. MarketValue float32 `json:"marketValue"` // Equity as a difference between cash and marketValue properties. TotalEquity float32 `json:"totalEquity"` // Buying power for that particular currency side of the account. BuyingPower float32 `json:"buyingPower"` // Maintenance excess for that particular side of the account. MaintenanceExcess float32 `json:"maintenanceExcess"` // Whether real-time data was used to calculate the above values. IsRealTime bool `json:"isRealTime"` } // AccountBalances represents per-currency and combined balances for a specified account. // // Ref: http://www.questrade.com/api/documentation/rest-operations/account-calls/accounts-id-balances type AccountBalances struct { PerCurrencyBalances []Balance `json:"perCurrencyBalances"` CombinedBalances []Balance `json:"combinedBalances"` SODPerCurrencyBalances []Balance `json:"sodPerCurrencyBalances"` SODCombinedBalances []Balance `json:"sodCombinedBalances"` } // GetAccounts returns the logged-in User ID, and a list of accounts // belonging to that user. func (c *client) GetAccounts() (int, []Account, error) { list := struct { UserID int `json:"userId"` Accounts []Account `json:"accounts"` }{} err := c.get("v1/accounts", &list, url.Values{}) if err != nil { return 0, []Account{}, err } return list.UserID, list.Accounts, nil } // GetBalances returns the balances for the account with the specified account number func (c *client) GetBalances(number string) (AccountBalances, error) { bal := AccountBalances{} err := c.get("v1/accounts/"+number+"/balances", &bal, url.Values{}) if err != nil { return AccountBalances{}, err } return bal, nil } func (c *client) GetQuestradeAccountBalance(accountID int) (int, error) { balances, err := c.GetBalances(strconv.Itoa(accountID)) if err != nil { return 0, fmt.Errorf("failed to get balances for account ID '%d': %v", accountID, err) } for _, balance := range balances.CombinedBalances { if balance.Currency != "CAD" { continue } return int(balance.TotalEquity) * 1000, nil } return 0, fmt.Errorf("could not find a CAD balance for this account in questade response") }