Coder Social home page Coder Social logo

go-tdameritrade's Introduction

go-tdameritrade's People

Contributors

aakkas avatar joncooperworks avatar lifeoverip avatar lyonplus avatar phamdt avatar seanlaff avatar zricethezav avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-tdameritrade's Issues

SSL issues trying to run the webauth example

Thanks for the fantastic library! I'm thinking about using it to add a TD integration to ticker. I'm trying to get the webauth example working locally but keep running into this SSL issue:

image

I'm running the example with:

TDAMERITRADE_CLIENT_ID=<my_client_id> go run webauth.go

Are you doing SSL termination in front of your webauth? I tried switching the callback URL from https to http but it looks like the TD API forces it to https irrespective of your callback URL settings.

Everything works great if I toss in an ngrok secure tunnel (and adjust the callback URL accordingly), but would like to avoid making users set up ngrok if possible.

replace anonymous struct for Candles

I'm integrating your library into my application and discovered that I can't access an individual candle from the PriceHistory API. I can only access the list of Candles which references an anonymous struct. In my code it would be convenient if I could pass around the individual candle. I can make the PR if this is acceptable to you.

PriceHistory call errors with Bad Request because of empty time.Time values

The call to PriceHistory fails with a 400 Bad Request because StartDate and EndDate options contain empty time.Time which the API rejects.

Fixed by: #23

Example call.

                ph, resp, err := client.PriceHistory.PriceHistory(ctx, symbol, &tdameritrade.PriceHistoryOptions{
                        PeriodType:    "year",
                        Period:        20,
                        FrequencyType: "daily",
                        Frequency:     1,
                })

Fix:

type PriceHistoryOptions struct {
            ...
            EndDate               time.Time `url:"endDate, omitempty"`     <-- Include omitempty
            StartDate             time.Time `url:"startDate, omitempty"`     <--
            ...
}

Question

Hello I was wondering how you normally go about testing your applications seeing as there does not seem to be a Paper Trading option for TD's api. Thanks

Error placing Options order

I'm wrote some code to place an options order, using the Single Option example here. The example they give is this:

{
  "complexOrderStrategyType": "NONE",
  "orderType": "LIMIT",
  "session": "NORMAL",
  "price": "6.45",
  "duration": "DAY",
  "orderStrategyType": "SINGLE",
  "orderLegCollection": [
    {
      "instruction": "BUY_TO_OPEN",
      "quantity": 10,
      "instrument": {
        "symbol": "XYZ_032015C49",
        "assetType": "OPTION"
    	}
    }
  ]
}

It seem like the library's Instrument struct only has Symbol and Data, not AssetType. Has TDA changed their interface and this library is old? TIA!

Refresh Token

Is there a way to get a refresh token through the code? I tried several times with their API and couldn't get a refresh token, kept getting a 400 error.

TIA!

Multiple child orders in OCO format

Thanks very much for your work on this.

It's unclear to me how to format a trigger order with two child orders that are bound by OCO.
(Shown as the second-to-last example in https://developer.tdameritrade.com/content/place-order-samples)

In the example, they compose the OCO as two children of an order with a single attribute orderStrategyType.

However, if I submit an instance of *tdameritrade.Order with only the attribute OrderStrategyType: "OCO" and two child orders, the api complains that I am missing attributes on the order.

I tested the example by marshaling a map to json and it did in fact work as expected. I think the fix should just be a matter of using the right type to wrap the two OCO child orders?

Unable to authenticate with TD

Hi,

I've used the code from the examples, this is what I get when trying to go to http://localhost:8080/authenticate:

package main

import (
	"context"
	"encoding/json"
	"log"
	"net/http"
	"os"

	"github.com/zricethezav/go-tdameritrade"
	"golang.org/x/oauth2"
)

type HTTPHeaderStore struct{}

func (s *HTTPHeaderStore) StoreToken(token *oauth2.Token, w http.ResponseWriter, req *http.Request) error {
	// DO NOT DO THIS IN A PRODUCTION ENVIRONMENT!
	// This is just an example.
	// Used signed cookies like those provided by https://github.com/gorilla/securecookie
	http.SetCookie(
		w,
		&http.Cookie{
			Name:    "refreshToken",
			Value:   token.RefreshToken,
			Expires: token.Expiry,
		},
	)
	http.SetCookie(
		w,
		&http.Cookie{
			Name:    "accessToken",
			Value:   token.AccessToken,
			Expires: token.Expiry,
		},
	)
	return nil
}

func (s HTTPHeaderStore) GetToken(req *http.Request) (*oauth2.Token, error) {
	// DO NOT DO THIS IN A PRODUCTION ENVIRONMENT!
	// This is just an example.
	// Used signed cookies like those provided by https://github.com/gorilla/securecookie
	refreshToken, err := req.Cookie("refreshToken")
	if err != nil {
		return nil, err
	}

	accessToken, err := req.Cookie("accessToken")
	if err != nil {
		return nil, err
	}

	return &oauth2.Token{
		AccessToken:  accessToken.Value,
		RefreshToken: refreshToken.Value,
		Expiry:       refreshToken.Expires,
	}, nil
}

func (s HTTPHeaderStore) StoreState(state string, w http.ResponseWriter, req *http.Request) error {
	// DO NOT DO THIS IN A PRODUCTION ENVIRONMENT!
	// This is just an example.
	// Used signed cookies like those provided by https://github.com/gorilla/securecookie
	http.SetCookie(
		w,
		&http.Cookie{
			Name:  "state",
			Value: state,
		},
	)
	return nil
}

func (s HTTPHeaderStore) GetState(req *http.Request) (string, error) {
	// DO NOT DO THIS IN A PRODUCTION ENVIRONMENT!
	// This is just an example.
	// Used signed cookies like those provided by https://github.com/gorilla/securecookie
	cookie, err := req.Cookie("state")
	if err != nil {
		return "", err
	}

	return cookie.Value, nil
}

type TDHandlers struct {
	authenticator *tdameritrade.Authenticator
}

func (h *TDHandlers) Authenticate(w http.ResponseWriter, req *http.Request) {
	redirectURL, err := h.authenticator.StartOAuth2Flow(w, req)
	if err != nil {
		w.Write([]byte(err.Error()))
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	http.Redirect(w, req, redirectURL, http.StatusTemporaryRedirect)
}

func (h *TDHandlers) Callback(w http.ResponseWriter, req *http.Request) {
	ctx := context.Background()
	_, err := h.authenticator.FinishOAuth2Flow(ctx, w, req)
	if err != nil {
		w.Write([]byte(err.Error()))
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	http.Redirect(w, req, "/quote?ticker=SPY", http.StatusTemporaryRedirect)
}

func (h *TDHandlers) Quote(w http.ResponseWriter, req *http.Request) {
	ctx := context.Background()
	client, err := h.authenticator.AuthenticatedClient(ctx, req)
	if err != nil {
		w.Write([]byte(err.Error()))
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	ticker, ok := req.URL.Query()["ticker"]
	if !ok || len(ticker) == 0 {
		w.Write([]byte("ticker is required"))
		w.WriteHeader(http.StatusBadRequest)
		return
	}

	quote, resp, err := client.Quotes.GetQuotes(ctx, ticker[0])
	if err != nil {
		w.Write([]byte(err.Error()))
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	body, err := json.Marshal(quote)
	if err != nil {
		w.Write([]byte(err.Error()))
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	w.Write(body)
	w.WriteHeader(resp.StatusCode)

}

func main() {
	clientID := os.Getenv("TDAMERITRADE_CLIENT_ID")
	if clientID == "" {
		log.Fatal("Unauthorized: No client ID present")
	}

	authenticator := tdameritrade.NewAuthenticator(
		&HTTPHeaderStore{},
		oauth2.Config{
			ClientID: clientID,
			Endpoint: oauth2.Endpoint{
				TokenURL: "https://api.tdameritrade.com/v1/oauth2/token",
				AuthURL:  "https://auth.tdameritrade.com/auth",
			},
			RedirectURL: "http://localhost:8080/callback",
		},
	)
	handlers := &TDHandlers{authenticator: authenticator}
	http.HandleFunc("/authenticate", handlers.Authenticate)
	http.HandleFunc("/callback", handlers.Callback)
	http.HandleFunc("/quote", handlers.Quote)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

image

I've configured my callback URL to be: http://localhost:8080/callback (http, not https)

Is there something I else I would need to configure?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.