diff --git a/accounts-trading.go b/accounts-trading.go index 882cf31..cf27b7c 100644 --- a/accounts-trading.go +++ b/accounts-trading.go @@ -9,10 +9,6 @@ import ( "github.com/bytedance/sonic" ) -/* TODO: -[ ] http.NewRequest -> agent.client -*/ - var ( accountEndpoint string = "https://api.schwabapi.com/trader/v1" @@ -424,10 +420,10 @@ func marshalMultiLegOrder(order *MultiLegOrder) string { var legs string // UNTESTED for i, leg := range order.OrderLegCollection { - if i != order.OrderLegCollection.length-1 { - legs += fmt.Sprintf(LegTemplate, order.Instruction, order.Quantity, order.Instrument.Symbol, order.Instrument.AssetType) + if i != len(order.OrderLegCollection)-1 { + legs += fmt.Sprintf(LegTemplate, leg.Instruction, leg.Quantity, leg.Instrument.Symbol, leg.Instrument.AssetType) } else { - legs += fmt.Sprintf(LegTemplateLast, order.Instruction, order.Quantity, order.Instrument.Symbol, order.Instrument.AssetType) + legs += fmt.Sprintf(LegTemplateLast, leg.Instruction, leg.Quantity, leg.Instrument.Symbol, leg.Instrument.AssetType) } } return fmt.Sprintf(OrderTemplate) diff --git a/go.mod b/go.mod index f65d26f..4e3483e 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/fatih/color v1.17.0 // indirect - github.com/go-schwab/oauth2ns v0.0.0-20241015193425-e8abfd05a439 // indirect + github.com/go-schwab/oauth2ns v0.0.0-20241027015119-9e1292705f91 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect diff --git a/go.sum b/go.sum index c77375a..1fe720d 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,8 @@ github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/go-schwab/oauth2ns v0.0.0-20241015193425-e8abfd05a439 h1:y/AmrAYZNvqI7IaMLllCjKlqOBbtYTe/KKtE+gip2c8= github.com/go-schwab/oauth2ns v0.0.0-20241015193425-e8abfd05a439/go.mod h1:69d3XNxDSeVmN6g+8a0RT+a13ZxDc5LRKODEZB3d5go= +github.com/go-schwab/oauth2ns v0.0.0-20241027015119-9e1292705f91 h1:2p/Kayfg67+S8/Cip+i/dGcxpkF7q1cwUPyDaVwRZPQ= +github.com/go-schwab/oauth2ns v0.0.0-20241027015119-9e1292705f91/go.mod h1:69d3XNxDSeVmN6g+8a0RT+a13ZxDc5LRKODEZB3d5go= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= diff --git a/market-data.go b/market-data.go index 7480a86..f40aff7 100644 --- a/market-data.go +++ b/market-data.go @@ -9,10 +9,6 @@ import ( "github.com/bytedance/sonic" ) -/* TODO: -[ ] http.NewRequest -> agent.client -*/ - var ( endpoint string = "https://api.schwabapi.com/marketdata/v1" diff --git a/utils.go b/utils.go index 5a5c50b..bbd48a0 100644 --- a/utils.go +++ b/utils.go @@ -12,7 +12,6 @@ import ( "time" "github.com/bytedance/sonic" - "github.com/go-schwab/oauth2ns" o "github.com/go-schwab/oauth2ns" "github.com/joho/godotenv" "golang.org/x/oauth2" @@ -31,37 +30,24 @@ type DB struct { var Tokens DB func init() { - err := godotenv.Load("*.env") + err := godotenv.Load() isErrNil(err) } -// Read in tokens from ~/.trade/bar.json -func readDB() *oauth2ns.AuthorizedClient { - body, err := os.ReadFile(fmt.Sprintf("%s/.trade/bar.json", homeDir())) - isErrNil(err) - var ctx context.Context - err = sonic.Unmarshal(body, &Tokens) - isErrNil(err) - token := new(oauth2.Token) - token.AccessToken = Tokens.AccessToken - token.RefreshToken = Tokens.RefreshToken - token.TokenType = Tokens.TokenType - token.Expiry = Tokens.Expiry - token.ExpiresIn = Tokens.ExpiresIn - c := &oauth2.Config{ - ClientID: os.Getenv("APPKEY"), - ClientSecret: os.Getenv("SECRET"), - Endpoint: oauth2.Endpoint{ - AuthURL: "https://api.schwabapi.com/v1/oauth/authorize", - TokenURL: "https://api.schwabapi.com/v1/oauth/token", - }, - } - return &o.AuthorizedClient{ - c.Client(ctx, token), - token, +// is the err nil? +func isErrNil(err error) { + if err != nil { + log.Fatalf("[err] %s", err.Error()) } } +// wrapper for os.UserHomeDir() +func homeDir() string { + dir, err := os.UserHomeDir() + isErrNil(err) + return dir +} + // Credit: https://go.dev/play/p/C2sZRYC15XN func getStringInBetween(str string, start string, end string) (result string) { s := strings.Index(str, start) @@ -76,13 +62,6 @@ func getStringInBetween(str string, start string, end string) (result string) { return str[s : s+e] } -// is the err nil? -func isErrNil(err error) { - if err != nil { - log.Fatalf("[ERR] %s", err.Error()) - } -} - // trim one FIRST character in the string func trimOneFirst(s string) string { if len(s) < 1 { @@ -131,19 +110,44 @@ func trimOneFirstThreeLast(s string) string { return s[1 : len(s)-3] } -// wrapper for os.UserHomeDir() -func homeDir() string { - dir, err := os.UserHomeDir() +// Read in tokens from ~/.trade/bar.json +func readDB() *o.AuthorizedClient { + body, err := os.ReadFile(fmt.Sprintf("%s/.trade/bar.json", homeDir())) isErrNil(err) - return dir + var ctx context.Context + err = sonic.Unmarshal(body, &Tokens) + isErrNil(err) + token := new(oauth2.Token) + token.AccessToken = Tokens.AccessToken + token.RefreshToken = Tokens.RefreshToken + token.TokenType = Tokens.TokenType + token.Expiry = Tokens.Expiry + token.ExpiresIn = Tokens.ExpiresIn + c := &oauth2.Config{ + ClientID: os.Getenv("APPKEY"), + ClientSecret: os.Getenv("SECRET"), + Endpoint: oauth2.Endpoint{ + AuthURL: "https://api.schwabapi.com/v1/oauth/authorize", + TokenURL: "https://api.schwabapi.com/v1/oauth/token", + }, + } + return &o.AuthorizedClient{ + c.Client(ctx, token), + token, + } } func Initiate() *Agent { var agent Agent - if _, err := os.Stat(fmt.Sprintf("%s/.trade", homeDir())); errors.Is(err, os.ErrNotExist) { + // TODO: test this block, this is to attempt to resolve the error described in #67 + if _, err := os.Stat(fmt.Sprintf("%s/.trade/bar.json", homeDir())); errors.Is(err, os.ErrNotExist) { + if _, err := os.Stat(fmt.Sprintf("%s/.trade", homeDir())); !errors.Is(err, os.ErrNotExist) { + err = os.RemoveAll(fmt.Sprintf("%s/.trade", homeDir())) + isErrNil(err) + } err = os.Mkdir(fmt.Sprintf("%s/.trade", homeDir()), os.ModePerm) isErrNil(err) - agent.client, err = o.Run() + agent.client, err = o.Initiate(os.Getenv("APPKEY"), os.Getenv("SECRET"), os.Getenv("CBURL")) isErrNil(err) Tokens.AccessToken = agent.client.Token.AccessToken Tokens.RefreshToken = agent.client.Token.RefreshToken @@ -175,7 +179,9 @@ func (agent *Agent) Handler(req *http.Request) (*http.Response, error) { log.Fatalf("[err] no access token found, please reinitiate with 'Initiate'") } if ((&Agent{}) == agent) || ((&o.AuthorizedClient{}) == agent.client) { - agent.client, err = o.Run() + // TODO: this theoretically works but results in an error for the oauth implrementation + // going to do some testing now, but pushing as it is in what is a theoretically working state + agent.client, err = o.Initiate(os.Getenv("APPKEY"), os.Getenv("SECRET"), os.Getenv("CBURL")) isErrNil(err) Tokens.AccessToken = agent.client.Token.AccessToken Tokens.RefreshToken = agent.client.Token.RefreshToken @@ -183,9 +189,7 @@ func (agent *Agent) Handler(req *http.Request) (*http.Response, error) { Tokens.Expiry = agent.client.Token.Expiry Tokens.ExpiresIn = agent.client.Token.ExpiresIn } - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", agent.client.Token.AccessToken)) - client := http.Client{} - resp, err := client.Do(req) + resp, err := agent.client.Do(req) if err != nil { return resp, err }