From a653810b12ff1aaedb76da326ac6d48d58705056 Mon Sep 17 00:00:00 2001 From: shauryam Date: Mon, 5 Feb 2024 23:56:26 +0530 Subject: [PATCH 01/12] first --- client.go | 61 ++++++--- client_test.go | 2 +- examples/api/api.go | 52 ++++---- go.mod | 2 + go.sum | 25 ++++ gtt_orders.go | 42 ++++++ http_client.go | 24 +++- iceberg.go | 24 ++++ models.go | 298 +++++++++++++++++++++++++++++++++---------- orders.go | 8 +- orders_test.go | 4 +- requests.go | 108 ++++++++++++++-- tags.go | 42 ++++++ transactions.go | 2 +- transactions_test.go | 2 +- vortex-mocks | 2 +- 16 files changed, 563 insertions(+), 135 deletions(-) create mode 100644 gtt_orders.go create mode 100644 iceberg.go create mode 100644 tags.go diff --git a/client.go b/client.go index f981e04..6b41635 100644 --- a/client.go +++ b/client.go @@ -11,31 +11,54 @@ import ( // Constants for the package const ( name string = "govortex" - version string = "1.0.0" + version string = "2.0.0" requestTimeout time.Duration = 7000 * time.Millisecond - baseURI string = "https://vortex.restapi.asthatrade.com" - flowBaseURI string = "https://flow.asthatrade.com" + baseURI string = "https://vortex-api.rupeezy.in/v2" + flowBaseURI string = "https://flow.rupeezy.in" ) // Constants for the API endpoints const ( - URILogin string = "/user/login" - URIInstruments string = "/data/instruments" - URIPlaceOrder string = "/orders/%s" // "/orders/regular" - URIModifyOrder string = "/orders/%s/%s/%s" //"/orders/regular/{exchange}/{order_id}" - URIDeleterOrder string = "/orders/%s/%s/%s" //"/orders/regular/{exchange}/{order_id}" - URIOrderBook string = "/orders" //"/orders?limit={limit}&offset={offset}" - URIOrderHistory string = "/orders/%s" //"/orders/{order_id}" - URITrades string = "/trades" - - URIPositions string = "/portfolio/positions" - URIConvertposition string = "/portfolio/positions" - URIHoldings string = "/portfolio/holdings" - - URIFunds string = "/user/funds" + URILogin string = "/user/login" + URIInstruments string = "/data/instruments" + URIPlaceOrder string = "/trading/orders/%s" //"/trading/orders/regular" + URIModifyOrder string = "/trading/orders/%s/%s" //"/trading/orders/{{order_type}}/{order_id}" + URIModifyOrderTags string = "/trading/orders/%s/%s/tags" //"/trading/orders/{{order_type}}/{order_id}/tags" + URIDeleteOrder string = "/trading/orders/%s/%s" //"/orders/{{order_type}}/{order_id}" + URIDeleteMultipleOrder string = "/trading/orders/%s/multi_delete" //"/orders/{{order_type}}/{order_id}" + URIGttOrderBook string = "/trading/orders/gtt" //"/orders/gtt" + URIOrderBook string = "/trading/orders" //"/orders" + URIOrderHistory string = "/trading/orders/%s" //"/orders/{order_id}" + URITrades string = "/trading/trades" + + URIPositions string = "/trading/portfolio/positions" + URIConvertposition string = "/trading/portfolio/positions" + URIHoldings string = "/trading/portfolio/holdings" + + URIFunds string = "/trading/user/funds" + URIBanks string = "/trading/user/banks" + URIBrokerage string = "/trading/user/brokerage" + + URIWithdrawal string = "/user/funds/withdrawal" URIOrderMargin string = "/margins/order" + URIOrderBasket string = "/margins/basket" URIQuotes string = "/data/quote" URIHistory string = "/data/history" + + URIOptionChain string = "/strategies/option_chain" + + URIStrategies string = "/strategies" + URIBuildStrategies string = "/strategies/build" + URIPayoffStrategies string = "/strategies/payoff" + + URITradeReport string = "/reports/trades/%s?from_date=%s&to_date=%s" + URITurnoverSummaryReport string = "/reports/turnover/summary/%s?from_date=%s&to_date=%s" + URITurnoverDetailsReport string = "/reports/turnover/details/%s?from_date=%s&to_date=%s" + URIPnLReport string = "/reports/pnl/%s?from_date=%s&to_date=%s" + URIMTFInterestReport string = "/reports/mtf_interest/%s?from_date=%s&to_date=%s" + + URITags string = "/reports/tags" + URITag string = "/reports/tags/%d" ) // VortexApi is a struct representing the Vortex API client @@ -65,8 +88,8 @@ func (v *VortexApi) initialize(applicationId string, apiKey string) { } // SetLogging sets the HTTP client with logging enabled -func (v *VortexApi) SetLogging(h *http.Client) { - v.htt = NewHTTPClient(h, nil, v.enableLogging) +func (v *VortexApi) SetLogging(flag bool) { + v.htt = NewHTTPClient(v.htt.GetClient().client, nil, flag) } // SetHTTPClient sets the HTTP client for the Vortex API client diff --git a/client_test.go b/client_test.go index 7142bad..678fcc6 100644 --- a/client_test.go +++ b/client_test.go @@ -42,7 +42,7 @@ var MockResponders = [][]interface{}{ {http.MethodGet, URIHistory, url.Values{"exchange": []string{string(ExchangeTypesNSEEQUITY)}, "token": []string{"22"}, "from": []string{"1494505756"}, "to": []string{"1494505756"}, "resolution": []string{string(ResolutionsMin1)}}, "history.json"}, {http.MethodGet, fmt.Sprintf(URIOrderHistory, "test"), url.Values{}, "order_history.json"}, // DELETE REQUESTS - {http.MethodDelete, fmt.Sprintf(URIDeleterOrder, "regular", ExchangeTypesNSEEQUITY, "NXAAE00002K3"), url.Values{}, "order.json"}, + {http.MethodDelete, fmt.Sprintf(URIDeleteOrder, "regular", ExchangeTypesNSEEQUITY, "NXAAE00002K3"), url.Values{}, "order.json"}, // POST REQUESTS {http.MethodPost, fmt.Sprintf(URIPlaceOrder, "regular"), url.Values{}, "order.json"}, diff --git a/examples/api/api.go b/examples/api/api.go index 19f3561..c40d67f 100644 --- a/examples/api/api.go +++ b/examples/api/api.go @@ -2,40 +2,48 @@ package main import ( "context" + "encoding/json" + "fmt" govortex "github.com/AsthaTech/govortex" ) const ( - applicationId string = "testApplicationId" - apiKey string = "testApiKey" + applicationId string = "dev_hK7M2HWR" + apiKey string = "TYB7g0bdJFvvQOfIXsgquaDfupLieYZlOHNMRAeO" ) func main() { var client govortex.VortexApi govortex.InitializeVortexApi(applicationId, apiKey, &client) + client.SetLogging(true) ctx := context.Background() - client.Login(ctx, "clientCode", "password", "totp") + client.Login(ctx, "600S1871", "ApiTesting1$", "136000") + client.SetAccessToken("eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDcxODY2MDAsImlhdCI6MTcwNzEzMjQyMCwiaXNzIjoiQXN0aGFUcmFkZSIsInN1YiI6IjYwMFMxODcxIiwiZGV2aWNlSWQiOiJhcGktY2xpZW50IiwiYXBwbGljYXRpb25JZCI6ImRldl9oSzdNMkhXUiIsImlwIjoiMTMuMjMyLjY0LjE0MSIsInNjb3BlIjoicHJvZmlsZS5yZWFkLG9yZGVycy5yZWFkLG9yZGVycy53cml0ZSxob2xkaW5ncy5yZWFkLHBvc2l0aW9ucy5yZWFkLHBvc2l0aW9ucy53cml0ZSxmdW5kcy5yZWFkLHRyYWRlcy5yZWFkLG1hcmdpbnMucmVhZCxkYXRhLnJlYWQiLCJjbGllbnRfY29kZSI6IjYwMFMxODcxIiwic291cmNlIjoiYXBpX2F1dGgiLCJwb2EiOnRydWV9.w4Lzj3Gu1tyeVjrWBMODMuUz3sHBLHRtEogTPImoT5uF_C7og4pvolddaET3AkqrJ_Z6fSI9fy-czWyUxHRuzsi0OijLatbdJidWzX48HqMrropBj5ggAq7Uhkqpo7qcqympmDI9ej8p3f91bZCWIevgnEGFJI9zNIu_NnIIqTU94q0kM5xiks5HNwrE4abS6jlTJ_OpuKsXgRhIqCtdgSl_QTcSaniZ0HHsYoxwJFhO2Mr-lcD22lP8BArNGpp765r36lkN1FhDvYwt2j-tRLOjWkUe-RyoFPBWh-whQ-BiE1aN0f53FwMI_TL2nf3pgM5M_CvOdF3_SEi4CuNfgAbhStirTq-E2MTLzrxOD3p5dMhms9dOlWmwK8uLV7xA2puMETUPY0_gyKAjQv9LX-29vFO6rKJzbJDMVJsD_QXQYDfJ1j35G_dPoWKRTjObWxcWOOdCBPXtcxj1N-oYO-2-ZFyGtEm-7c-HMnQ89fS4Td0brWMD8qSLIlV7nAlZ") + // Access token is automatically set upon successful login call - client.Orders(ctx, 1, 20) //orders need an offset and limit - client.Positions(ctx) //positions need an offset and limit - - client.PlaceOrder(ctx, govortex.PlaceOrderRequest{ - Exchange: govortex.ExchangeTypesNSEEQUITY, - Token: 22, - TransactionType: govortex.TransactionTypesBUY, - Product: govortex.ProductTypesDelivery, - Variety: govortex.VarietyTypesRegularMarketOrder, - Quantity: 1, - Price: 1800, - TriggerPrice: 0, - DisclosedQuantity: 0, - Validity: govortex.ValidityTypesFullDay, - ValidityDays: 1, - IsAMO: false, - }) - - client.Funds(ctx) + // client.Orders(ctx) //orders need an offset and limit + // client.Positions(ctx) //positions need an offset and limit + + // client.PlaceOrder(ctx, govortex.PlaceOrderRequest{ + // Exchange: govortex.ExchangeTypesNSEEQUITY, + // Token: 22, + // TransactionType: govortex.TransactionTypesBUY, + // Product: govortex.ProductTypesDelivery, + // Variety: govortex.VarietyTypesRegularMarketOrder, + // Quantity: 1, + // Price: 1800, + // TriggerPrice: 0, + // DisclosedQuantity: 0, + // Validity: govortex.ValidityTypesFullDay, + // ValidityDays: 1, + // IsAMO: false, + // }) + // client.Funds(ctx) + + aa, _ := client.Tags(ctx) + bb, _ := json.Marshal(aa) + fmt.Println(string(bb)) } diff --git a/go.mod b/go.mod index ebd4661..69a7cfd 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/AsthaTech/govortex go 1.16 require ( + github.com/gofrs/uuid v4.4.0+incompatible github.com/jarcoal/httpmock v1.3.0 + github.com/lib/pq v1.10.9 nhooyr.io/websocket v1.8.7 ) diff --git a/go.sum b/go.sum index 28ff9ac..4dad81f 100644 --- a/go.sum +++ b/go.sum @@ -1,44 +1,69 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/jarcoal/httpmock v1.3.0 h1:2RJ8GP0IIaWwcC9Fp2BmVi8Kog3v2Hn7VXM3fTd+nuc= github.com/jarcoal/httpmock v1.3.0/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eTO0Q8= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/maxatome/go-testdeep v1.12.0 h1:Ql7Go8Tg0C1D/uMMX59LAoYK7LffeJQ6X2T04nTH68g= github.com/maxatome/go-testdeep v1.12.0/go.mod h1:lPZc/HAcJMP92l7yI6TRz1aZN5URwUBUAfUNvrclaNM= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= diff --git a/gtt_orders.go b/gtt_orders.go new file mode 100644 index 0000000..87bc353 --- /dev/null +++ b/gtt_orders.go @@ -0,0 +1,42 @@ +package govortex + +import ( + "context" + "fmt" +) + +func (v *VortexApi) PlaceGttOrder(ctx context.Context, request PlaceGttRequest) (*OrderResponse, error) { + var resp OrderResponse + _, err := v.doJson(ctx, "POST", fmt.Sprintf(URIPlaceOrder, "gtt"), request, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) ModifyGttOrder(ctx context.Context, gtt_order_id string, request ModifyGttRequest) (*OrderResponse, error) { + var resp OrderResponse + _, err := v.doJson(ctx, "PUT", fmt.Sprintf(URIModifyOrder, "gtt", gtt_order_id), request, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) CancelGttOrder(ctx context.Context, gtt_order_id string) (*OrderResponse, error) { + var resp OrderResponse + _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URIModifyOrder, "gtt", gtt_order_id), nil, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) GttOrders(ctx context.Context) (*GttOrderbookResponse, error) { + var resp GttOrderbookResponse + _, err := v.doJson(ctx, "GET", URIGttOrderBook, nil, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/http_client.go b/http_client.go index f55a5a0..edb6a72 100644 --- a/http_client.go +++ b/http_client.go @@ -86,7 +86,10 @@ func (h *httpClient) doRaw(ctx context.Context, method, rURL string, reqBody int req, err := http.NewRequestWithContext(ctx, method, rURL, postBody) if err != nil { - h.hLog.Printf("Request preparation failed: %v", err) + if h.debug { + h.hLog.Printf("Request preparation failed: %v", err) + } + return resp, NewError(NetworkError, "Request preparation failed.", nil) } @@ -108,7 +111,10 @@ func (h *httpClient) doRaw(ctx context.Context, method, rURL string, reqBody int r, err := h.client.Do(req) if err != nil { - h.hLog.Printf("Request failed: %v", err) + if h.debug { + h.hLog.Printf("Request failed: %v", err) + } + return resp, NewError(NetworkError, "Request failed.", nil) } @@ -116,7 +122,10 @@ func (h *httpClient) doRaw(ctx context.Context, method, rURL string, reqBody int body, err := ioutil.ReadAll(r.Body) if err != nil { - h.hLog.Printf("Unable to read response: %v", err) + if h.debug { + h.hLog.Printf("Unable to read response: %v", err) + } + return resp, NewError(DataError, "Error reading response.", nil) } @@ -145,10 +154,15 @@ func (h *httpClient) doJSON(ctx context.Context, method, rURL string, reqBody in // We now unmarshal the body. if err := json.Unmarshal(resp.Body, obj); err != nil { - h.hLog.Printf(string(resp.Body)) - h.hLog.Printf("Error parsing JSON response: %v | %s", err, resp.Body) + if h.debug { + h.hLog.Printf(string(resp.Body)) + h.hLog.Printf("Error parsing JSON response: %v | %s", err, resp.Body) + } return resp, NewError(DataError, "Error parsing response.", nil) } + if h.debug { + h.hLog.Printf(string(resp.Body)) + } return resp, nil } diff --git a/iceberg.go b/iceberg.go new file mode 100644 index 0000000..102a463 --- /dev/null +++ b/iceberg.go @@ -0,0 +1,24 @@ +package govortex + +import ( + "context" + "fmt" +) + +func (v *VortexApi) PlaceIcebergOrder(ctx context.Context, request PlaceIcebergOrderRequest) (*PlaceIcebergOrderResponse, error) { + var resp PlaceIcebergOrderResponse + _, err := v.doJson(ctx, "POST", fmt.Sprintf(URIPlaceOrder, "iceberg"), request, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) ModifyIcebergOrder(ctx context.Context, request ModifyIcebergOrderRequest) (*PlaceIcebergOrderResponse, error) { + var resp PlaceIcebergOrderResponse + _, err := v.doJson(ctx, "POST", fmt.Sprintf(URIPlaceOrder, "iceberg"), request, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/models.go b/models.go index b8e4b1a..bd82979 100644 --- a/models.go +++ b/models.go @@ -1,5 +1,12 @@ package govortex +import ( + "time" + + "github.com/gofrs/uuid" + "github.com/lib/pq" +) + type FullQuoteData struct { Exchange string `json:"exchange"` Token int `json:"token"` @@ -80,51 +87,55 @@ type FundDetails struct { NetAvailable float64 `json:"net_available"` } +type ExchangeDetails struct { + Token int `json:"token"` + Exchange string `json:"exchange"` + Symbol string `json:"symbol"` +} + +type ExchangeDetail struct { + Token int `json:"token"` + Exchange ExchangeTypes `json:"exchange"` + Symbol string `json:"symbol"` +} + type Holding struct { ISIN string `json:"isin"` - NSE ExchangeDetails `json:"nse"` - BSE ExchangeDetails `json:"bse"` + NSE *ExchangeDetail `json:"nse,omitempty"` + BSE *ExchangeDetail `json:"bse,omitempty"` TotalFree int `json:"total_free"` DPFree int `json:"dp_free"` PoolFree int `json:"pool_free"` T1Quantity int `json:"t1_quantity"` AveragePrice float64 `json:"average_price"` + LastPrice float64 `json:"last_price"` + Product string `json:"product"` CollateralQuantity int `json:"collateral_quantity"` CollateralValue float64 `json:"collateral_value"` } -type ExchangeDetails struct { - Token int `json:"token"` - Exchange string `json:"exchange"` - Symbol string `json:"symbol"` -} - type HoldingsResponse struct { - Status string `json:"status"` - Data []Holding `json:"data"` + Status string `json:"status"` + Message string `json:"message,omitempty"` + Data []Holding `json:"data"` } type PositionResponse struct { - Status string `json:"status"` - Data PositionData `json:"data"` -} - -type ConvertPositionResponse struct { - Status string `json:"status"` - Code string `json:"code"` - Message string `json:"message"` + Status string `json:"status"` + Data NetDayPositions `json:"data"` } -type PositionData struct { - Net []Position `json:"net"` - Day []Position `json:"day"` +type NetDayPositions struct { + Net []PositionItem `json:"net"` + Day []PositionItem `json:"day"` } -type Position struct { +type PositionItem struct { Exchange ExchangeTypes `json:"exchange"` Symbol string `json:"symbol"` ExpiryDate string `json:"expiry_date"` - OptionType string `json:"option_type"` + OptionType OptionType `json:"option_type"` + StrikePrice float64 `json:"strike_price"` Token int `json:"token"` Product ProductTypes `json:"product"` Quantity int `json:"quantity"` @@ -143,6 +154,12 @@ type Position struct { SellPrice float64 `json:"sell_price"` } +type ConvertPositionResponse struct { + Status string `json:"status"` + Code string `json:"code"` + Message string `json:"message"` +} + type TradeBookResponse struct { Status string `json:"status"` Trades []Trade `json:"trades"` @@ -228,49 +245,58 @@ const ( ValidityTypesAfterMarket ValidityTypes = "AMO" ) +type OrderBookResponse struct { + Status string `json:"status"` + Orders []Order `json:"orders"` + Metadata Metadata `json:"metadata"` +} + type Order struct { - OrderID string `json:"order_id"` - Exchange ExchangeTypes `json:"exchange"` - Token int `json:"token"` - OrderNumber string `json:"order_number"` - Status string `json:"status"` - ErrorReason string `json:"error_reason"` - TransactionType TransactionTypes `json:"transaction_type"` - Product ProductTypes `json:"product"` - Variety VarietyTypes `json:"variety"` - TotalQuantity int `json:"total_quantity"` - PendingQuantity int `json:"pending_quantity"` - TradedQuantity int `json:"traded_quantity"` - DisclosedQuantity int `json:"disclosed_quantity"` - DisclosedQuantityRemaining int `json:"disclosed_quantity_remaining"` - OrderPrice float64 `json:"order_price"` - TriggerPrice float64 `json:"trigger_price"` - TradedPrice float64 `json:"traded_price"` - Validity ValidityTypes `json:"validity"` - ValidityDays int `json:"validity_days"` - Symbol string `json:"symbol"` - Series string `json:"series"` - InstrumentName string `json:"instrument_name"` - ExpiryDate string `json:"expiry_date"` - StrikePrice float64 `json:"strike_price"` - OptionType string `json:"option_type"` - LotSize int `json:"lot_size"` - OrderCreatedAt string `json:"order_created_at"` - InitiatedBy string `json:"initiated_by"` - ModifiedBy string `json:"modified_by"` - IsAMO bool `json:"is_amo"` - OrderIdentifier string `json:"order_identifier"` + OrderID string `json:"order_id"` + Exchange ExchangeTypes `json:"exchange"` + Token int `json:"token"` + OrderNumber string `json:"order_number"` + Status string `json:"status"` + ErrorReason string `json:"error_reason"` + TransactionType TransactionTypes `json:"transaction_type"` + Product ProductTypes `json:"product"` + Variety VarietyTypes `json:"variety"` + TotalQuantity int `json:"total_quantity"` + PendingQuantity int `json:"pending_quantity"` + TradedQuantity int `json:"traded_quantity"` + DisclosedQuantity int `json:"disclosed_quantity"` + DisclosedQuantityRemaining int `json:"disclosed_quantity_remaining"` + OrderPrice float64 `json:"order_price"` + TriggerPrice float64 `json:"trigger_price"` + TradedPrice float64 `json:"traded_price,omitempty"` + Validity ValidityTypes `json:"validity"` + Symbol string `json:"symbol"` + Series string `json:"series"` + InstrumentName InstrumentName `json:"instrument_name"` + ExpiryDate string `json:"expiry_date"` + StrikePrice float64 `json:"strike_price"` + OptionType OptionType `json:"option_type"` + LotSize int `json:"lot_size"` + OrderCreatedAt string `json:"order_created_at"` + InitiatedBy string `json:"initiated_by"` + ModifiedBy string `json:"modified_by"` + IsAMO bool `json:"is_amo"` + OrderIdentifier string `json:"order_identifier"` + TagsIds pq.Int32Array `json:"tags_ids"` + MiddlewareOrderId uint `json:"middleware_order_id"` + Iceberg *OrderBookIcebergInfo `json:"iceberg,omitempty"` + Gtt *OrderBookGttInfo `json:"gtt,omitempty"` +} +type OrderBookIcebergInfo struct { + IcebergOrderId uuid.UUID `json:"iceberg_order_id"` + IcebergSequence int `json:"iceberg_sequence"` + Legs int `json:"legs"` } -type OrderBookResponse struct { - Status string `json:"status"` - Orders []Order `json:"orders"` - Metadata struct { - TotalRecords int `json:"total_records"` - AllRecords int `json:"all_records"` - CompletedRecords int `json:"completed_records"` - OpenRecords int `json:"open_records"` - } `json:"metadata"` +type OrderBookGttInfo struct { + TriggerType GttTriggerType `json:"trigger_type"` + SlTriggerPercent *float64 `json:"sl_trigger_percent,omitempty"` + ProfitTriggerPercent *float64 `json:"profit_trigger_percent,omitempty"` } type LoginResponse struct { @@ -299,7 +325,7 @@ type OrderResponse struct { Code string `json:"code"` Message string `json:"message"` Data struct { - OrderID string `json:"orderId"` + OrderID string `json:"order_id"` } `json:"data"` } @@ -319,7 +345,7 @@ type Trade struct { InstrumentName string `json:"instrument_name"` ExpiryDate string `json:"expiry_date"` StrikePrice float64 `json:"strike_price"` - OptionType string `json:"option_type"` + OptionType OptionType `json:"option_type"` TradedAt string `json:"traded_at"` InitiatedBy string `json:"initiated_by"` ModifiedBy string `json:"modified_by"` @@ -389,10 +415,10 @@ type OrderHistory struct { ValidityDays int `json:"validity_days"` Symbol string `json:"symbol"` Series string `json:"series"` - InstrumentName string `json:"instrument_name"` + InstrumentName InstrumentName `json:"instrument_name"` ExpiryDate string `json:"expiry_date"` StrikePrice float64 `json:"strike_price"` - OptionType string `json:"option_type"` + OptionType OptionType `json:"option_type"` OrderCreatedAt string `json:"order_created_at"` ExchangeOrderCreatedAt string `json:"exchange_order_created_at"` InitiatedBy string `json:"initiated_by"` @@ -404,3 +430,141 @@ type OrderHistory struct { type Metadata struct { TotalRecords int `json:"total_records"` } + +type InstrumentName string + +const ( + InstrumentNameEqIndex InstrumentName = "EQIDX" + InstrumentNameCom InstrumentName = "COM" + InstrumentNameEquities InstrumentName = "EQUITIES" + InstrumentNameCommodityFuture InstrumentName = "FUTCOM" + InstrumentNameCurrencyFuture InstrumentName = "FUTCUR" + InstrumentNameIndexFuture InstrumentName = "FUTIDX" + InstrumentNameInterestFuture InstrumentName = "FUTIRC" + InstrumentNameInterestFutureT InstrumentName = "FUTIRT" + InstrumentNameStockFuture InstrumentName = "FUTSTK" + InstrumentNameCurrencyOption InstrumentName = "OPTCUR" + InstrumentNameCommodityOption InstrumentName = "OPTFUT" + InstrumentNameIndexOption InstrumentName = "OPTIDX" + InstrumentNameInterestOption InstrumentName = "OPTIRC" + InstrumentNameStockOption InstrumentName = "OPTSTK" + InstrumentNameCurrentcyUnderlying InstrumentName = "UNDCUR" +) + +type OptionType string + +const ( + OptionTypeCall OptionType = "CE" + OptionTypePut OptionType = "PE" +) + +type GttOrderbookResponse struct { + Status string `json:"status"` + Data []*GttOrderResponse `json:"data"` +} + +type GttOrderResponse struct { + Id uuid.UUID `json:"id"` + Token int `json:"token" binding:"required"` + Exchange ExchangeTypes `json:"exchange" binding:"required"` + Symbol string `json:"symbol" binding:"required"` + Series string `json:"series" binding:"required"` + InstrumentName InstrumentName `json:"instrument_name" binding:"required"` + ExpiryDate string `json:"expiry_date" binding:"required"` + StrikePrice float64 `json:"strike_price" binding:"required"` + OptionType OptionType `json:"option_type" binding:"required"` + LotSize int `json:"lot_size" binding:"required"` + TriggerType GttTriggerType `json:"trigger_type" binding:"required"` + TransactionType TransactionTypes `json:"transaction_type" binding:"required"` + TagIds pq.Int32Array `json:"tag_ids"` + Orders []GttOrderResponseOrders `json:"orders" binding:"required"` +} + +type GttOrderResponseOrders struct { + Id uint `json:"id"` + ProductType ProductTypes `json:"product"` + Variety VarietyTypes `json:"variety"` + TransactionType TransactionTypes `json:"transaction_type"` + Price float64 `json:"price"` + TriggerPrice float64 `json:"trigger_price"` + Quantity int `json:"quantity"` + Status GttOrderStatus `json:"status"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + TrigerredAt time.Time `json:"trigerred_at"` +} + +type GttOrderStatus string + +const ( + GttOrderStatusTriggered GttOrderStatus = "triggered" + GttOrderStatusActive GttOrderStatus = "active" + GttOrderStatusCancelled GttOrderStatus = "cancelled" + GttOrderStatusExpired GttOrderStatus = "expired" + GttOrderStatusCompleted GttOrderStatus = "completed" +) + +type FundResponse struct { + Nse ExchangeFundResponse `json:"nse"` + Mcx ExchangeFundResponse `json:"mcx"` +} + +type ExchangeFundResponse struct { + Deposit float64 `json:"deposit"` + FundsTransferred float64 `json:"funds_transferred"` + Collateral float64 `json:"collateral"` + CreditForSale float64 `json:"credit_for_sale"` + OptionCreditForSale float64 `json:"option_credit_for_sale"` + LimitUtilization float64 `json:"limit_utilization"` + MtmAndBookedLoss float64 `json:"mtm_and_booked_loss"` + BookedProfit float64 `json:"booked_profit"` + TotalTradingPower float64 `json:"total_trading_power"` + TotalUtilization float64 `json:"total_utilization"` + NetAvailable float64 `json:"net_available"` + FundsWithdrawal float64 `json:"funds_withdrawal"` +} + +type FundWithdrawalListResponse struct { + Status string `json:"status"` + Message string `json:"message,omitempty"` + Data []FundWithdrawalItem `json:"data"` +} + +type FundWithdrawalItem struct { + TransactionId string `json:"transaction_id"` + Amount float64 `json:"amount"` + CreatedAt time.Time `json:"created_at"` + Status string `json:"status"` + Exchange ExchangeTypes `json:"exchange"` +} + +type TagResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Data TagInfo `json:"data"` +} + +type TagsResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Data []TagInfo `json:"data"` +} +type TagInfo struct { + Id int `json:"id"` + ClientCode string `json:"client_code"` + Name string `json:"name"` + Description string `json:"description"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +type PlaceIcebergOrderResponse struct { + Message string `json:"message"` + Code string `json:"code"` + Status string `json:"status"` + Data IcebergOrderData `json:"data"` +} +type IcebergOrderData struct { + IcebergOrderId string `json:"iceberg_order_id"` + FirstOrderId string `json:"first_order_id"` +} diff --git a/orders.go b/orders.go index 183facf..f14162d 100644 --- a/orders.go +++ b/orders.go @@ -56,9 +56,9 @@ func (v *VortexApi) ModifyOrder(ctx context.Context, request ModifyOrderRequest, // CancelOrder cancels an existing order with the Vortex API. // It takes a context, an ExchangeTypes value, and an order ID as input. // It returns an OrderResponse and an error. -func (v *VortexApi) CancelOrder(ctx context.Context, exchange ExchangeTypes, orderID string) (*OrderResponse, error) { +func (v *VortexApi) CancelOrder(ctx context.Context, orderID string) (*OrderResponse, error) { var resp OrderResponse - _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URIDeleterOrder, "regular", exchange, orderID), nil, nil, nil, &resp) + _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URIDeleteOrder, "regular", orderID), nil, nil, nil, &resp) if err != nil { return nil, err } @@ -69,11 +69,9 @@ func (v *VortexApi) CancelOrder(ctx context.Context, exchange ExchangeTypes, ord // Orders retrieves the order book information from the Vortex API. // It takes a context, an offset, and a limit as input. // It returns an OrderBookResponse and an error. -func (v *VortexApi) Orders(ctx context.Context, offset int, limit int) (*OrderBookResponse, error) { +func (v *VortexApi) Orders(ctx context.Context) (*OrderBookResponse, error) { var resp OrderBookResponse params := url.Values{} - params.Add("offset", fmt.Sprintf("%d", offset)) - params.Add("limit", fmt.Sprintf("%d", limit)) _, err := v.doJson(ctx, "GET", URIOrderBook, nil, params, nil, &resp) if err != nil { return nil, err diff --git a/orders_test.go b/orders_test.go index 04de283..becc1da 100644 --- a/orders_test.go +++ b/orders_test.go @@ -36,7 +36,7 @@ func (ts *TestSuite) TestModifyOrder(t *testing.T) { func (ts *TestSuite) TestCancelOrder(t *testing.T) { t.Parallel() ctx := context.Background() - resp, err := ts.VortexApiClient.CancelOrder(ctx, ExchangeTypesNSEEQUITY, "NXAAE00002K3") + resp, err := ts.VortexApiClient.CancelOrder(ctx, "NXAAE00002K3") if err != nil { t.Errorf("Error while cancelling order. %v", err) return @@ -49,7 +49,7 @@ func (ts *TestSuite) TestCancelOrder(t *testing.T) { func (ts *TestSuite) TestOrderBook(t *testing.T) { t.Parallel() ctx := context.Background() - resp, err := ts.VortexApiClient.Orders(ctx, 1, 20) + resp, err := ts.VortexApiClient.Orders(ctx) if err != nil { t.Errorf("Error while fetching order book. %v", err) return diff --git a/requests.go b/requests.go index 2c58500..4df4dd1 100644 --- a/requests.go +++ b/requests.go @@ -1,5 +1,7 @@ package govortex +import "github.com/lib/pq" + type PlaceOrderRequest struct { Exchange ExchangeTypes `json:"exchange"` Token int `json:"token"` @@ -9,21 +11,30 @@ type PlaceOrderRequest struct { Quantity int `json:"quantity"` Price float64 `json:"price"` TriggerPrice float64 `json:"trigger_price"` + OrderIdentifier string `json:"order_identifier"` DisclosedQuantity int `json:"disclosed_quantity"` Validity ValidityTypes `json:"validity"` ValidityDays int `json:"validity_days"` IsAMO bool `json:"is_amo"` + Gtt *GttLegs `json:"gtt"` + TagIds []int `json:"tag_ids"` +} + +type GttLegs struct { + SlTriggerPercent *float64 `json:"sl_trigger_percent"` + ProfitTriggerPercent *float64 `json:"profit_trigger_percent"` } type ModifyOrderRequest struct { - Variety VarietyTypes `json:"variety"` - Quantity int `json:"quantity"` - TradedQuantity int `json:"traded_quantity"` - Price float64 `json:"price"` + Variety VarietyTypes `json:"variety" ` + Quantity int `json:"quantity" ` + TradedQuantity *int `json:"traded_quantity" ` + Price float64 `json:"price" ` TriggerPrice float64 `json:"trigger_price"` DisclosedQuantity int `json:"disclosed_quantity"` - Validity ValidityTypes `json:"validity"` + Validity ValidityTypes `json:"validity" ` ValidityDays int `json:"validity_days"` + TagIds []int `json:"tag_ids"` } type OrderMarginRequest struct { @@ -39,10 +50,85 @@ type OrderMarginRequest struct { Mode MarginModes `json:"mode"` } -type ConvertPositionObject struct { - Exchange ExchangeTypes `json:"exchange"` - Token int `json:"token"` - TransactionType TransactionTypes `json:"transaction_type"` - OldProductType ProductTypes `json:"old_product_type"` - NewProductType ProductTypes `json:"new_product_type"` +type ConvertPositionRequest struct { + Exchange ExchangeTypes `json:"exchange" ` + Token int `json:"token" ` + TransactionType TransactionTypes `json:"transaction_type" ` + Quantity int `json:"quantity" ` + OldProductType ProductTypes `json:"old_product" ` + NewProductType ProductTypes `json:"new_product" ` +} + +type ModifyGttRequest struct { + Id uint `json:"id" ` + TriggerPrice *float64 `json:"trigger_price"` + Price *float64 `json:"price"` + Quantity *int `json:"quantity"` +} + +type PlaceGttRequest struct { + Exchange ExchangeTypes `json:"exchange"` + Token int `json:"token"` + TransactionType TransactionTypes `json:"transaction_type"` + Quantity *int `json:"quantity"` + TriggerPrice *float64 `json:"trigger_price"` + Price *float64 `json:"price"` + OrderIdentifier string `json:"order_identifier"` + GttTriggerType GttTriggerType `json:"gtt_trigger_type"` + Product ProductTypes `json:"product"` + Stoploss *PlaceGttLegRequest `json:"stoploss"` + Profit *PlaceGttLegRequest `json:"profit"` + TagIds []int `json:"tag_ids"` +} +type PlaceGttLegRequest struct { + Quantity int `json:"quantity"` + Price float64 `json:"price"` + TriggerPrice float64 `json:"trigger_price"` + ProductType ProductTypes `json:"product"` +} + +type GttTriggerType string + +const ( + GttTriggerTypeSingle GttTriggerType = "single" + GttTriggerTypeOCO GttTriggerType = "oco" +) + +type PlaceIcebergOrderRequest struct { + Exchange ExchangeTypes `json:"exchange" ` + Token int `json:"token" ` + TransactionType TransactionTypes `json:"transaction_type" ` + Product ProductTypes `json:"product" ` + Variety VarietyTypes `json:"variety" ` + Quantity int `json:"quantity" ` + Price *float64 `json:"price" ` + TriggerPrice float64 `json:"trigger_price"` + OrderIdentifier string `json:"order_identifier"` + Validity ValidityTypes `json:"validity" ` + Legs int `json:"legs" ` + TagIds pq.Int32Array `json:"tag_ids"` +} + +type FundWithdrawalRequest struct { + BankAccountNumber string `json:"bank_account_number"` + Ifsc string `json:"ifsc"` + Amount float64 `json:"amount"` + Exchange ExchangeTypes `json:"exchange"` +} + +type FundWithdrawalCancelRequest struct { + TransactionId string `json:"transaction_id"` + Exchange ExchangeTypes `json:"exchange"` + Amount float64 `json:"amount"` +} + +type TagRequest struct { + Name string `json:"name"` + Description string `json:"description"` +} + +type ModifyIcebergOrderRequest struct { + Price float64 `json:"price"` + TriggerPrice float64 `json:"trigger_price" ` + TradedQuantity int `json:"traded_quantity"` } diff --git a/tags.go b/tags.go new file mode 100644 index 0000000..9cff0f9 --- /dev/null +++ b/tags.go @@ -0,0 +1,42 @@ +package govortex + +import ( + "context" + "fmt" +) + +func (v *VortexApi) Tags(ctx context.Context) (*TagsResponse, error) { + var resp TagsResponse + _, err := v.doJson(ctx, "GET", URITags, nil, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) CreateTag(ctx context.Context, request TagRequest) (*TagResponse, error) { + var resp TagResponse + _, err := v.doJson(ctx, "POST", URITags, request, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) UpdateTag(ctx context.Context, tag_id int, request TagRequest) (*TagResponse, error) { + var resp TagResponse + _, err := v.doJson(ctx, "PUT", fmt.Sprintf(URITag, tag_id), request, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) DeleteTag(ctx context.Context, tag_id int) (*TagResponse, error) { + var resp TagResponse + _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URITag, tag_id), nil, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/transactions.go b/transactions.go index 0353a5d..5123804 100644 --- a/transactions.go +++ b/transactions.go @@ -17,7 +17,7 @@ func (v *VortexApi) Positions(ctx context.Context) (*PositionResponse, error) { return &resp, nil } -func (v *VortexApi) ConvertPosition(ctx context.Context, req ConvertPositionObject) (*ConvertPositionResponse, error) { +func (v *VortexApi) ConvertPosition(ctx context.Context, req ConvertPositionRequest) (*ConvertPositionResponse, error) { var resp ConvertPositionResponse _, err := v.doJson(ctx, "PUT", URIConvertposition, req, nil, nil, &resp) if err != nil { diff --git a/transactions_test.go b/transactions_test.go index de0366b..60c900d 100644 --- a/transactions_test.go +++ b/transactions_test.go @@ -20,7 +20,7 @@ func (ts *TestSuite) TestGetPositions(t *testing.T) { func (ts *TestSuite) TestConvertPosition(t *testing.T) { t.Parallel() ctx := context.Background() - _, err := ts.VortexApiClient.ConvertPosition(ctx, ConvertPositionObject{ + _, err := ts.VortexApiClient.ConvertPosition(ctx, ConvertPositionRequest{ Exchange: ExchangeTypesNSEEQUITY, Token: 22, TransactionType: TransactionTypesBUY, diff --git a/vortex-mocks b/vortex-mocks index 6019b4b..2e4a0dc 160000 --- a/vortex-mocks +++ b/vortex-mocks @@ -1 +1 @@ -Subproject commit 6019b4bcc98ff7ae9e352207313dc7f761c80177 +Subproject commit 2e4a0dca3e71df3efb0505d8e0ff7e4cacb7537a From bfaa32226c4d5383f7431d0aaeba701d86a776c7 Mon Sep 17 00:00:00 2001 From: shauryam Date: Tue, 6 Feb 2024 10:31:55 +0530 Subject: [PATCH 02/12] new methods --- client.go | 1 + client_test.go | 40 ++++++++---- go.mod | 1 - go.sum | 2 - gtt_orders.go | 14 +++- gtt_orders_test.go | 59 +++++++++++++++++ iceberg.go | 28 ++++++-- iceberg_test.go | 45 +++++++++++++ models.go | 158 +++++++++++++++++++++++++++++++++++++++++++-- orders.go | 6 +- requests.go | 48 +++++++++++++- strategies.go | 41 ++++++++++++ strategies_test.go | 59 +++++++++++++++++ tags.go | 12 ++++ tags_test.go | 59 +++++++++++++++++ vortex-mocks | 2 +- 16 files changed, 541 insertions(+), 34 deletions(-) create mode 100644 gtt_orders_test.go create mode 100644 iceberg_test.go create mode 100644 strategies.go create mode 100644 strategies_test.go create mode 100644 tags_test.go diff --git a/client.go b/client.go index 6b41635..48c2cd6 100644 --- a/client.go +++ b/client.go @@ -115,5 +115,6 @@ func (v *VortexApi) doJson(ctx context.Context, method, uri string, body interfa if v.AccessToken != "" { headers.Add("Authorization", "Bearer "+v.AccessToken) } + fmt.Println("URL:", v.baseURL+uri) return v.htt.doJSON(ctx, method, v.baseURL+uri, body, params, headers, obj) } diff --git a/client_test.go b/client_test.go index 678fcc6..ce74489 100644 --- a/client_test.go +++ b/client_test.go @@ -33,22 +33,38 @@ const mockBaseDir = "./vortex-mocks" var MockResponders = [][]interface{}{ // GET REQUESTS - {http.MethodGet, URIFunds, url.Values{}, "funds.json"}, - {http.MethodGet, URIHoldings, url.Values{}, "holdings.json"}, - {http.MethodGet, URIPositions, url.Values{}, "positions.json"}, - {http.MethodGet, URIOrderBook, url.Values{"limit": []string{"20"}, "offset": []string{"1"}}, "orders.json"}, - {http.MethodGet, URIQuotes, url.Values{"q": []string{"NSE_EQ-22"}, "mode": []string{string(QuoteModesFULL)}}, "quotes.json"}, - {http.MethodGet, URITrades, url.Values{"limit": []string{"20"}, "offset": []string{"1"}}, "trades.json"}, - {http.MethodGet, URIHistory, url.Values{"exchange": []string{string(ExchangeTypesNSEEQUITY)}, "token": []string{"22"}, "from": []string{"1494505756"}, "to": []string{"1494505756"}, "resolution": []string{string(ResolutionsMin1)}}, "history.json"}, - {http.MethodGet, fmt.Sprintf(URIOrderHistory, "test"), url.Values{}, "order_history.json"}, + {http.MethodGet, URIFunds, url.Values{}, "user/funds.json"}, + {http.MethodGet, URIHoldings, url.Values{}, "portfolio/holdings.json"}, + {http.MethodGet, URIPositions, url.Values{}, "portfolio/positions.json"}, + {http.MethodGet, URIOrderBook, url.Values{}, "portfolio/orders.json"}, + {http.MethodGet, URIQuotes, url.Values{"q": []string{"NSE_EQ-22"}, "mode": []string{string(QuoteModesFULL)}}, "data/quotes.json"}, + {http.MethodGet, URITrades, url.Values{"limit": []string{"20"}, "offset": []string{"1"}}, "portfolio/trades.json"}, + {http.MethodGet, URIHistory, url.Values{"exchange": []string{string(ExchangeTypesNSEEQUITY)}, "token": []string{"22"}, "from": []string{"1494505756"}, "to": []string{"1494505756"}, "resolution": []string{string(ResolutionsMin1)}}, "data/history.json"}, + {http.MethodGet, fmt.Sprintf(URIOrderHistory, "test"), url.Values{}, "regular_orders/order_history.json"}, + {http.MethodGet, URIGttOrderBook, url.Values{}, "gtt_orders/list.json"}, + {http.MethodGet, URITags, url.Values{}, "reports/tags/list.json"}, + // DELETE REQUESTS - {http.MethodDelete, fmt.Sprintf(URIDeleteOrder, "regular", ExchangeTypesNSEEQUITY, "NXAAE00002K3"), url.Values{}, "order.json"}, + {http.MethodDelete, fmt.Sprintf(URIDeleteOrder, "regular", "NXAAE00002K3"), url.Values{}, "regular_orders/order.json"}, + {http.MethodDelete, fmt.Sprintf(URIDeleteOrder, "gtt", "99823d7b-fd37-4d75-af7f-f21ec4671852"), url.Values{}, "gtt_orders/delete.json"}, + {http.MethodDelete, fmt.Sprintf(URITag, 1), url.Values{}, "reports/tags/delete.json"}, + {http.MethodDelete, fmt.Sprintf(URIDeleteOrder, "iceberg", "5eaefd25-518c-4a39-b556-93fc8e78e855"), url.Values{}, "iceberg_orders/delete.json"}, // POST REQUESTS - {http.MethodPost, fmt.Sprintf(URIPlaceOrder, "regular"), url.Values{}, "order.json"}, + {http.MethodPost, fmt.Sprintf(URIPlaceOrder, "regular"), url.Values{}, "regular_orders/order.json"}, + {http.MethodPost, fmt.Sprintf(URIPlaceOrder, "gtt"), url.Values{}, "gtt_orders/create.json"}, + {http.MethodPost, fmt.Sprintf(URIPlaceOrder, "iceberg"), url.Values{}, "iceberg_orders/create.json"}, + {http.MethodPost, URITags, url.Values{}, "reports/tags/create.json"}, + {http.MethodPost, URIStrategies, url.Values{}, "strategies/all.json"}, + {http.MethodPost, URIOptionChain, url.Values{}, "strategies/option_chain.json"}, + {http.MethodPost, URIBuildStrategies, url.Values{}, "strategies/build_strategy.json"}, + {http.MethodPost, URIPayoffStrategies, url.Values{}, "strategies/payoff.json"}, // PUT REQUESTS - {http.MethodPut, fmt.Sprintf(URIModifyOrder, "regular", ExchangeTypesNSEEQUITY, "NXAAE00002K3"), url.Values{}, "order.json"}, - {http.MethodPut, URIConvertposition, url.Values{}, "position_conversion.json"}, + {http.MethodPut, fmt.Sprintf(URIModifyOrder, "regular", "NXAAE00002K3"), url.Values{}, "regular_orders/order.json"}, + {http.MethodPut, URIConvertposition, url.Values{}, "portfolio/position_conversion.json"}, + {http.MethodPut, fmt.Sprintf(URIModifyOrder, "gtt", "99823d7b-fd37-4d75-af7f-f21ec4671852"), url.Values{}, "gtt_orders/modify.json"}, + {http.MethodPut, fmt.Sprintf(URIModifyOrder, "iceberg", "5eaefd25-518c-4a39-b556-93fc8e78e855"), url.Values{}, "iceberg_orders/modify.json"}, + {http.MethodPut, fmt.Sprintf(URITag, 1), url.Values{}, "reports/tags/update.json"}, } const suiteTestMethodPrefix = "Test" diff --git a/go.mod b/go.mod index 69a7cfd..47eb8f7 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/AsthaTech/govortex go 1.16 require ( - github.com/gofrs/uuid v4.4.0+incompatible github.com/jarcoal/httpmock v1.3.0 github.com/lib/pq v1.10.9 nhooyr.io/websocket v1.8.7 diff --git a/go.sum b/go.sum index 4dad81f..c51db2c 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,6 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= -github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= diff --git a/gtt_orders.go b/gtt_orders.go index 87bc353..0679654 100644 --- a/gtt_orders.go +++ b/gtt_orders.go @@ -5,6 +5,9 @@ import ( "fmt" ) +// PlaceGttOrder places a Good Till Trigger (GTT) order with the Vortex API. +// It takes a context and a PlaceGttRequest as input. +// It returns an OrderResponse and an error. func (v *VortexApi) PlaceGttOrder(ctx context.Context, request PlaceGttRequest) (*OrderResponse, error) { var resp OrderResponse _, err := v.doJson(ctx, "POST", fmt.Sprintf(URIPlaceOrder, "gtt"), request, nil, nil, &resp) @@ -14,6 +17,9 @@ func (v *VortexApi) PlaceGttOrder(ctx context.Context, request PlaceGttRequest) return &resp, nil } +// ModifyGttOrder modifies an existing Good Till Trigger (GTT) order with the Vortex API. +// It takes a context, a GTT order ID, and a ModifyGttRequest as input. +// It returns an OrderResponse and an error. func (v *VortexApi) ModifyGttOrder(ctx context.Context, gtt_order_id string, request ModifyGttRequest) (*OrderResponse, error) { var resp OrderResponse _, err := v.doJson(ctx, "PUT", fmt.Sprintf(URIModifyOrder, "gtt", gtt_order_id), request, nil, nil, &resp) @@ -23,15 +29,21 @@ func (v *VortexApi) ModifyGttOrder(ctx context.Context, gtt_order_id string, req return &resp, nil } +// CancelGttOrder cancels an existing Good Till Trigger (GTT) order with the Vortex API. +// It takes a context and a GTT order ID as input. +// It returns an OrderResponse and an error. func (v *VortexApi) CancelGttOrder(ctx context.Context, gtt_order_id string) (*OrderResponse, error) { var resp OrderResponse - _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URIModifyOrder, "gtt", gtt_order_id), nil, nil, nil, &resp) + _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URIDeleteOrder, "gtt", gtt_order_id), nil, nil, nil, &resp) if err != nil { return nil, err } return &resp, nil } +// GttOrders retrieves the Good Till Trigger (GTT) orderbook from the Vortex API. +// It takes a context as input. +// It returns a GttOrderbookResponse and an error. func (v *VortexApi) GttOrders(ctx context.Context) (*GttOrderbookResponse, error) { var resp GttOrderbookResponse _, err := v.doJson(ctx, "GET", URIGttOrderBook, nil, nil, nil, &resp) diff --git a/gtt_orders_test.go b/gtt_orders_test.go new file mode 100644 index 0000000..e95fdc0 --- /dev/null +++ b/gtt_orders_test.go @@ -0,0 +1,59 @@ +package govortex + +import ( + "context" + "testing" +) + +func (ts *TestSuite) TestPlaceGttOrder(t *testing.T) { + t.Parallel() + ctx := context.Background() + request := PlaceGttRequest{} + resp, err := ts.VortexApiClient.PlaceGttOrder(ctx, request) + if err != nil { + t.Errorf("Error while placing order. %v", err) + return + } + if resp.Data.OrderID != "99823d7b-fd37-4d75-af7f-f21ec4671852" { + t.Errorf("Error while placing order. %s", "order id is not same") + } +} + +func (ts *TestSuite) TestGetGttOrder(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.GttOrders(ctx) + if err != nil { + t.Errorf("Error while fetching order book. %v", err) + return + } + if len(resp.Data) == 0 { + t.Errorf("Errorwhile fetching order book. %s", "order book is empty") + } +} + +func (ts *TestSuite) TestModifyGttOrder(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.ModifyGttOrder(ctx, "99823d7b-fd37-4d75-af7f-f21ec4671852", ModifyGttRequest{}) + if err != nil { + t.Errorf("Error while modifying order. %v", err) + return + } + if resp.Data.OrderID == "99823d7b-fd37-4d75-af7f-f21ec4671852" { + t.Errorf("Error while modifying order. %s", "order id is not same") + } +} + +func (ts *TestSuite) TestDeleteGttOrder(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.CancelGttOrder(ctx, "99823d7b-fd37-4d75-af7f-f21ec4671852") + if err != nil { + t.Errorf("Error while cancelling order. %v", err) + return + } + if resp.Status != "success" { + t.Errorf("Error while modifying order. %s", "status is not success") + } +} diff --git a/iceberg.go b/iceberg.go index 102a463..4ed6f9e 100644 --- a/iceberg.go +++ b/iceberg.go @@ -5,8 +5,11 @@ import ( "fmt" ) -func (v *VortexApi) PlaceIcebergOrder(ctx context.Context, request PlaceIcebergOrderRequest) (*PlaceIcebergOrderResponse, error) { - var resp PlaceIcebergOrderResponse +// PlaceIcebergOrder places an iceberg order with the Vortex API. +// It takes a context and a PlaceIcebergOrderRequest as input. +// It returns an IcebergOrderResponse and an error. +func (v *VortexApi) PlaceIcebergOrder(ctx context.Context, request PlaceIcebergOrderRequest) (*IcebergOrderResponse, error) { + var resp IcebergOrderResponse _, err := v.doJson(ctx, "POST", fmt.Sprintf(URIPlaceOrder, "iceberg"), request, nil, nil, &resp) if err != nil { return nil, err @@ -14,9 +17,24 @@ func (v *VortexApi) PlaceIcebergOrder(ctx context.Context, request PlaceIcebergO return &resp, nil } -func (v *VortexApi) ModifyIcebergOrder(ctx context.Context, request ModifyIcebergOrderRequest) (*PlaceIcebergOrderResponse, error) { - var resp PlaceIcebergOrderResponse - _, err := v.doJson(ctx, "POST", fmt.Sprintf(URIPlaceOrder, "iceberg"), request, nil, nil, &resp) +// ModifyIcebergOrder modifies an existing iceberg order with the Vortex API. +// It takes a context, an iceberg order ID, and a ModifyIcebergOrderRequest as input. +// It returns an IcebergOrderResponse and an error. +func (v *VortexApi) ModifyIcebergOrder(ctx context.Context, iceberg_order_id string, request ModifyIcebergOrderRequest) (*IcebergOrderResponse, error) { + var resp IcebergOrderResponse + _, err := v.doJson(ctx, "PUT", fmt.Sprintf(URIModifyOrder, "iceberg", iceberg_order_id), request, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +// CancelIcebergOrder cancels an existing iceberg order with the Vortex API. +// It takes a context and an iceberg order ID as input. +// It returns a CancelIcebergOrderResponse and an error. +func (v *VortexApi) CancelIcebergOrder(ctx context.Context, iceberg_order_id string) (*CancelIcebergOrderResponse, error) { + var resp CancelIcebergOrderResponse + _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URIDeleteOrder, "iceberg", iceberg_order_id), nil, nil, nil, &resp) if err != nil { return nil, err } diff --git a/iceberg_test.go b/iceberg_test.go new file mode 100644 index 0000000..9c0c8e5 --- /dev/null +++ b/iceberg_test.go @@ -0,0 +1,45 @@ +package govortex + +import ( + "context" + "testing" +) + +func (ts *TestSuite) TestPlaceIcebergOrder(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.PlaceIcebergOrder(ctx, PlaceIcebergOrderRequest{}) + if err != nil { + t.Errorf("Error while creating order. %v", err) + return + } + if resp.Data.IcebergOrderId != "5eaefd25-518c-4a39-b556-93fc8e78e855" { + t.Errorf("Error while creating order. %s", "order id is not same") + } +} + +func (ts *TestSuite) TestModifyIcebergOrder(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.ModifyIcebergOrder(ctx, "5eaefd25-518c-4a39-b556-93fc8e78e855", ModifyIcebergOrderRequest{}) + if err != nil { + t.Errorf("Error while modifying order. %v", err) + return + } + if resp.Data.IcebergOrderId == "5eaefd25-518c-4a39-b556-93fc8e78e855" { + t.Errorf("Error while modifying order. %s", "order id is not same") + } +} + +func (ts *TestSuite) TestCancelIcebergOrder(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.CancelIcebergOrder(ctx, "5eaefd25-518c-4a39-b556-93fc8e78e855") + if err != nil { + t.Errorf("Error while cancelling order. %v", err) + return + } + if resp.Status != "success" { + t.Errorf("Error while cancelling order. %s", "status is not success") + } +} diff --git a/models.go b/models.go index bd82979..ea0de73 100644 --- a/models.go +++ b/models.go @@ -3,7 +3,6 @@ package govortex import ( "time" - "github.com/gofrs/uuid" "github.com/lib/pq" ) @@ -288,9 +287,9 @@ type Order struct { Gtt *OrderBookGttInfo `json:"gtt,omitempty"` } type OrderBookIcebergInfo struct { - IcebergOrderId uuid.UUID `json:"iceberg_order_id"` - IcebergSequence int `json:"iceberg_sequence"` - Legs int `json:"legs"` + IcebergOrderId string `json:"iceberg_order_id"` + IcebergSequence int `json:"iceberg_sequence"` + Legs int `json:"legs"` } type OrderBookGttInfo struct { @@ -391,7 +390,7 @@ type OrderHistoryResponse struct { Status string `json:"status"` Code string `json:"code"` Message string `json:"message"` - Data []OrderHistory `json:"data"` + Data []OrderHistory `json:"orders"` Metadata Metadata `json:"metadata"` } @@ -464,7 +463,7 @@ type GttOrderbookResponse struct { } type GttOrderResponse struct { - Id uuid.UUID `json:"id"` + Id string `json:"id"` Token int `json:"token" binding:"required"` Exchange ExchangeTypes `json:"exchange" binding:"required"` Symbol string `json:"symbol" binding:"required"` @@ -558,13 +557,158 @@ type TagInfo struct { UpdatedAt time.Time `json:"updated_at"` } -type PlaceIcebergOrderResponse struct { +type IcebergOrderResponse struct { Message string `json:"message"` Code string `json:"code"` Status string `json:"status"` Data IcebergOrderData `json:"data"` } + +type CancelIcebergOrderResponse struct { + Message string `json:"message"` + Status string `json:"status"` +} type IcebergOrderData struct { IcebergOrderId string `json:"iceberg_order_id"` FirstOrderId string `json:"first_order_id"` } +type StrategiesResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Data StrategiesResult `json:"data"` +} +type StrategiesResult struct { + Symbol string `json:"symbol"` + Token int `json:"token"` + Ltp float64 `json:"ltp"` + Strategies []Strategy `json:"strategies"` +} + +type Strategy struct { + Name string `json:"strategy_name"` + TradingOpportunities []TradingOpportunity `json:"trading_opportunities"` +} +type TradingOpportunity struct { + Legs []StrategyLeg `json:"legs"` + MaxLoss float64 `json:"max_loss"` + MaxProfit float64 `json:"max_profit"` + IsInfiniteProfit bool `json:"is_infinite_profit"` + IsInfiniteLoss bool `json:"is_infinite_loss"` + BreakEven []float64 `json:"breakeven"` +} + +type StrategyLeg struct { + Option StrategyStock `json:"option"` + Action string `json:"action"` + Quantity int `json:"quantity"` +} + +type StrategyStock struct { + Token int `json:"token"` + InstrumentName string `json:"instrument_name"` + Symbol string `json:"symbol"` + StrikePrice float64 `json:"strike_price"` + OptionType OptionType `json:"option_type"` + LotSize int `json:"lot_size"` + SecurityDesc string `json:"security_description"` + Exchange ExchangeTypes `json:"exchange"` + ExpYyyymmdd string `json:"expiry_date"` + Ltp float64 `json:"ltp"` + Greeks struct { + Theta float64 `json:"theta"` + Delta float64 `json:"delta"` + Gamma float64 `json:"gamma"` + Vega float64 `json:"vega"` + Iv float64 `json:"iv"` + } `json:"greeks"` +} + +type OptionChainResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Response OptionchainResult `json:"response"` +} +type OptionchainResult struct { + Symbol string `json:"symbol"` + ExpiryDate string `json:"expiry_date"` + HasParentStock bool `json:"has_parent_stock"` + ExpiryDates []string `json:"expiry_dates"` + Options struct { + Exchange ExchangeTypes `json:"exchange"` + List []*DateOptionData `json:"list"` + } `json:"options"` + ParentStock struct { + Symbol string `json:"symbol"` + Exchange ExchangeTypes `json:"exchange"` + Token int `json:"token"` + ISINCode string `json:"isin"` + LTP float64 `json:"ltp"` + } `json:"parent"` +} + +type DateOptionData struct { + StrikePrice float64 `json:"strike_price"` + IV float64 `json:"iv"` + Theta float64 `json:"theta"` + Vega float64 `json:"vega"` + Gamma float64 `json:"gamma"` + CE StockWithGreek `json:"CE"` + PE StockWithGreek `json:"PE"` +} + +type StockWithGreek struct { + Token int `json:"token"` + InstrumentName string `json:"instrument_name"` + LotSize int `json:"lot_size"` + SecurityDesc string `json:"security_description"` + Eligibility int `json:"eligibility"` + Ltp float64 `json:"ltp"` + OpenInterest int `json:"open_interest"` + DayFirstTickOI int `json:"day_first_tick_oi" ` + Volume int `json:"volume"` + Delta float64 `json:"delta"` +} +type PayoffResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Data PayOffData `json:"data"` +} + +type PayOffData struct { + MaxLoss float64 `json:"max_loss"` + MaxProfit float64 `json:"max_profit"` + IsInfiniteProfit bool `json:"infinite_profit"` + IsInfiniteLoss bool `json:"infinite_loss"` + BreakEvens []float64 `json:"breakevens"` + PayOffs []PayOff `json:"payoffs"` + CombinedGreeks Greeks `json:"combined_greeks"` + LivePrice float64 `json:"last_trade_price"` + LegStocks []LegStockGreek `json:"leg_greeks"` + MinDaysToExpiry int `json:"min_days_to_expiry"` +} + +type LegStockGreek struct { + Token int `json:"token" binding:"required"` + StrikePrice float64 `json:"strike_price"` + OptionType OptionType `json:"option_type"` + ExpYYYYMMDD string `json:"expiry_date"` + Action string `json:"action"` + LotSize int `json:"lot_size"` + Quantity int `json:"quantity"` + Ltp float64 `json:"last_trade_price"` // Update + Iv float64 `json:"iv"` // Update *hide + Greeks Greeks `json:"greeks" gorm:"-"` +} +type Greeks struct { + Theta float64 `json:"theta"` + Delta float64 `json:"delta"` + Gamma float64 `json:"gamma"` + Vega float64 `json:"vega"` + Iv float64 `json:"iv"` +} + +type PayOff struct { + IPayoff float64 `json:"intraday_pay_off"` + EPayoff float64 `json:"expiry_pay_off"` + At float64 `json:"at"` +} diff --git a/orders.go b/orders.go index f14162d..c8414b7 100644 --- a/orders.go +++ b/orders.go @@ -3,7 +3,6 @@ package govortex import ( "context" "fmt" - "net/url" ) // PlaceOrder places an order with the Vortex API. @@ -46,7 +45,7 @@ func (v *VortexApi) ModifyOrder(ctx context.Context, request ModifyOrderRequest, request.ValidityDays = 1 } var resp OrderResponse - _, err := v.doJson(ctx, "PUT", fmt.Sprintf(URIModifyOrder, "regular", exchange, orderID), request, nil, nil, &resp) + _, err := v.doJson(ctx, "PUT", fmt.Sprintf(URIModifyOrder, "regular", orderID), request, nil, nil, &resp) if err != nil { return nil, err } @@ -71,8 +70,7 @@ func (v *VortexApi) CancelOrder(ctx context.Context, orderID string) (*OrderResp // It returns an OrderBookResponse and an error. func (v *VortexApi) Orders(ctx context.Context) (*OrderBookResponse, error) { var resp OrderBookResponse - params := url.Values{} - _, err := v.doJson(ctx, "GET", URIOrderBook, nil, params, nil, &resp) + _, err := v.doJson(ctx, "GET", URIOrderBook, nil, nil, nil, &resp) if err != nil { return nil, err } diff --git a/requests.go b/requests.go index 4df4dd1..dc9e054 100644 --- a/requests.go +++ b/requests.go @@ -1,6 +1,8 @@ package govortex -import "github.com/lib/pq" +import ( + "github.com/lib/pq" +) type PlaceOrderRequest struct { Exchange ExchangeTypes `json:"exchange"` @@ -132,3 +134,47 @@ type ModifyIcebergOrderRequest struct { TriggerPrice float64 `json:"trigger_price" ` TradedQuantity int `json:"traded_quantity"` } + +type StrategiesRequest struct { + Token int `json:"token"` + Symbol string `json:"symbol"` + ExpYYYYMMDD string `json:"expiry_date"` +} + +type OptionChainRequest struct { + Token int `json:"token"` // required + ExpiryDate string `json:"expiry_date"` //optional. format: YYYYMMDD. If not provided, result will be of closest expiry + Exchange ExchangeTypes `json:"exchange"` // required + AddGreek bool `json:"greeks"` // optional. default: false +} + +type StrategyBuilderRequest struct { + Token int `json:"token"` // required + Symbol string `json:"symbol"` + MarketView PredictionType `json:"prediction"` // ["ABOVE", "BELOW", "BETWEEN"] + ExpiryDate string `json:"expiry_date"` //required. format: YYYYMMDD + PriceRange []float64 `json:"price_range"` +} + +type PredictionType string + +const ( + PredictionTypeABOVE PredictionType = "ABOVE" + PredictionTypeBELOW PredictionType = "BELOW" + PredictionTypeBETWEEN PredictionType = "BETWEEN" +) + +type PayoffRequest struct { + Symbol string `json:"symbol" ` //required + Exchange ExchangeTypes `json:"exchange" ` //required + Legs []PayoffOption `json:"legs"` //required + InpDaysToExpiry *int `json:"days_to_expiry"` + CurrentPnl float64 `json:"current_pnl"` +} + +type PayoffOption struct { + Token int `json:"token"` //required + Action string `json:"action"` //required + Quantity int `json:"quantity"` //required, in lots + Ltp float64 `json:"last_trade_price"` //optional +} diff --git a/strategies.go b/strategies.go new file mode 100644 index 0000000..a33735d --- /dev/null +++ b/strategies.go @@ -0,0 +1,41 @@ +package govortex + +import ( + "context" +) + +func (v *VortexApi) GetStrategies(ctx context.Context, req StrategiesRequest) (*StrategiesResponse, error) { + var resp StrategiesResponse + _, err := v.doJson(ctx, "POST", URIStrategies, req, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) GetOptionChain(ctx context.Context, req OptionChainRequest) (*OptionChainResponse, error) { + var resp OptionChainResponse + _, err := v.doJson(ctx, "POST", URIOptionChain, req, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) BuildStrategy(ctx context.Context, req StrategyBuilderRequest) (*StrategiesResponse, error) { + var resp StrategiesResponse + _, err := v.doJson(ctx, "POST", URIBuildStrategies, req, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func (v *VortexApi) GetPayoff(ctx context.Context, req PayoffRequest) (*PayoffResponse, error) { + var resp PayoffResponse + _, err := v.doJson(ctx, "POST", URIPayoffStrategies, req, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/strategies_test.go b/strategies_test.go new file mode 100644 index 0000000..041c118 --- /dev/null +++ b/strategies_test.go @@ -0,0 +1,59 @@ +package govortex + +import ( + "context" + "testing" +) + +// func (v *VortexApi) PlaceGttOrder() { +// } +func (ts *TestSuite) TestGetStrategies(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.GetStrategies(ctx, StrategiesRequest{}) + if err != nil { + t.Errorf("Error while fetching strategies. %v", err) + return + } + if len(resp.Data.Strategies) == 0 { + t.Errorf("Error while fetching strategies. %s", "length is 0") + } +} + +func (ts *TestSuite) TestOptionChain(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.GetOptionChain(ctx, OptionChainRequest{}) + if err != nil { + t.Errorf("Error while fetching option chain %v", err) + return + } + if len(resp.Response.Options.List) == 0 { + t.Errorf("Error while fetching option chain %s", "length is 0") + } +} +func (ts *TestSuite) TestBuildStrategies(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.BuildStrategy(ctx, StrategyBuilderRequest{}) + if err != nil { + t.Errorf("Error while fetching strategies. %v", err) + return + } + if len(resp.Data.Strategies) == 0 { + t.Errorf("Error while fetching strategies. %s", "length is 0") + } +} + +func (ts *TestSuite) TestPayoff(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.GetPayoff(ctx, PayoffRequest{}) + if err != nil { + t.Errorf("Error while fetching payoffs. %v", err) + return + } + if len(resp.Data.PayOffs) == 0 { + t.Errorf("Error while fetching payoffs. %s", "length is 0") + } +} diff --git a/tags.go b/tags.go index 9cff0f9..8e25321 100644 --- a/tags.go +++ b/tags.go @@ -5,6 +5,9 @@ import ( "fmt" ) +// Tags retrieves the list of tags from the Vortex API. +// It takes a context as input. +// It returns a TagsResponse and an error. func (v *VortexApi) Tags(ctx context.Context) (*TagsResponse, error) { var resp TagsResponse _, err := v.doJson(ctx, "GET", URITags, nil, nil, nil, &resp) @@ -14,6 +17,9 @@ func (v *VortexApi) Tags(ctx context.Context) (*TagsResponse, error) { return &resp, nil } +// CreateTag creates a new tag with the Vortex API. +// It takes a context and a TagRequest as input. +// It returns a TagResponse and an error. func (v *VortexApi) CreateTag(ctx context.Context, request TagRequest) (*TagResponse, error) { var resp TagResponse _, err := v.doJson(ctx, "POST", URITags, request, nil, nil, &resp) @@ -23,6 +29,9 @@ func (v *VortexApi) CreateTag(ctx context.Context, request TagRequest) (*TagResp return &resp, nil } +// UpdateTag updates an existing tag with the Vortex API. +// It takes a context, a tag ID, and a TagRequest as input. +// It returns a TagResponse and an error. func (v *VortexApi) UpdateTag(ctx context.Context, tag_id int, request TagRequest) (*TagResponse, error) { var resp TagResponse _, err := v.doJson(ctx, "PUT", fmt.Sprintf(URITag, tag_id), request, nil, nil, &resp) @@ -32,6 +41,9 @@ func (v *VortexApi) UpdateTag(ctx context.Context, tag_id int, request TagReques return &resp, nil } +// DeleteTag deletes an existing tag with the Vortex API. +// It takes a context and a tag ID as input. +// It returns a TagResponse and an error. func (v *VortexApi) DeleteTag(ctx context.Context, tag_id int) (*TagResponse, error) { var resp TagResponse _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URITag, tag_id), nil, nil, nil, &resp) diff --git a/tags_test.go b/tags_test.go new file mode 100644 index 0000000..93b8e7b --- /dev/null +++ b/tags_test.go @@ -0,0 +1,59 @@ +package govortex + +import ( + "context" + "testing" +) + +func (ts *TestSuite) TestCreateTag(t *testing.T) { + t.Parallel() + ctx := context.Background() + request := TagRequest{} + resp, err := ts.VortexApiClient.CreateTag(ctx, request) + if err != nil { + t.Errorf("rror while creating tag. %v", err) + return + } + if resp.Status != "success" { + t.Errorf("Error while creating tag") + } +} + +func (ts *TestSuite) TestGetTags(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.Tags(ctx) + if err != nil { + t.Errorf("Error while fetching tags. %v", err) + return + } + if len(resp.Data) == 0 { + t.Errorf("Error while fetching tags. %s", "tags are empty") + } +} + +func (ts *TestSuite) TestUpdateTag(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.UpdateTag(ctx, 1, TagRequest{}) + if err != nil { + t.Errorf("Error while updating tag. %v", err) + return + } + if resp.Status != "success" { + t.Errorf("Error while updating tag. %s", "status is not success") + } +} + +func (ts *TestSuite) TestDeleteTag(t *testing.T) { + t.Parallel() + ctx := context.Background() + resp, err := ts.VortexApiClient.DeleteTag(ctx, 1) + if err != nil { + t.Errorf("Error while deleting tag. %v", err) + return + } + if resp.Status != "success" { + t.Errorf("Error while deleting tag. %s", "status is not success") + } +} diff --git a/vortex-mocks b/vortex-mocks index 2e4a0dc..de38f69 160000 --- a/vortex-mocks +++ b/vortex-mocks @@ -1 +1 @@ -Subproject commit 2e4a0dca3e71df3efb0505d8e0ff7e4cacb7537a +Subproject commit de38f6999c0cd211065d242c253594e2ed0fa0cc From e9e9c58f3964e00391f28fa91526b4703e5f6c2d Mon Sep 17 00:00:00 2001 From: shauryam Date: Wed, 7 Feb 2024 10:50:53 +0530 Subject: [PATCH 03/12] partial documentation --- doc.txt | 803 ++++++++++++++++++++++++++++++++++++++++++-------- requests.go | 268 +++++++++-------- strategies.go | 12 + 3 files changed, 841 insertions(+), 242 deletions(-) diff --git a/doc.txt b/doc.txt index 4fe3a03..2a050fd 100644 --- a/doc.txt +++ b/doc.txt @@ -4,23 +4,46 @@ package govortex // import "github.com/AsthaTech/govortex" CONSTANTS const ( - URILogin string = "/user/login" - URIInstruments string = "/data/instruments" - URIPlaceOrder string = "/orders/%s" // "/orders/regular" - URIModifyOrder string = "/orders/%s/%s/%s" //"/orders/regular/{exchange}/{order_id}" - URIDeleterOrder string = "/orders/%s/%s/%s" //"/orders/regular/{exchange}/{order_id}" - URIOrderBook string = "/orders" //"/orders?limit={limit}&offset={offset}" - URIOrderHistory string = "/orders/%s" //"/orders/{order_id}" - URITrades string = "/trades" - - URIPositions string = "/portfolio/positions" - URIConvertposition string = "/portfolio/positions" - URIHoldings string = "/portfolio/holdings" - - URIFunds string = "/user/funds" + URILogin string = "/user/login" + URIInstruments string = "/data/instruments" + URIPlaceOrder string = "/trading/orders/%s" //"/trading/orders/regular" + URIModifyOrder string = "/trading/orders/%s/%s" //"/trading/orders/{{order_type}}/{order_id}" + URIModifyOrderTags string = "/trading/orders/%s/%s/tags" //"/trading/orders/{{order_type}}/{order_id}/tags" + URIDeleteOrder string = "/trading/orders/%s/%s" //"/orders/{{order_type}}/{order_id}" + URIDeleteMultipleOrder string = "/trading/orders/%s/multi_delete" //"/orders/{{order_type}}/{order_id}" + URIGttOrderBook string = "/trading/orders/gtt" //"/orders/gtt" + URIOrderBook string = "/trading/orders" //"/orders" + URIOrderHistory string = "/trading/orders/%s" //"/orders/{order_id}" + URITrades string = "/trading/trades" + + URIPositions string = "/trading/portfolio/positions" + URIConvertposition string = "/trading/portfolio/positions" + URIHoldings string = "/trading/portfolio/holdings" + + URIFunds string = "/trading/user/funds" + URIBanks string = "/trading/user/banks" + URIBrokerage string = "/trading/user/brokerage" + + URIWithdrawal string = "/user/funds/withdrawal" URIOrderMargin string = "/margins/order" + URIOrderBasket string = "/margins/basket" URIQuotes string = "/data/quote" URIHistory string = "/data/history" + + URIOptionChain string = "/strategies/option_chain" + + URIStrategies string = "/strategies" + URIBuildStrategies string = "/strategies/build" + URIPayoffStrategies string = "/strategies/payoff" + + URITradeReport string = "/reports/trades/%s?from_date=%s&to_date=%s" + URITurnoverSummaryReport string = "/reports/turnover/summary/%s?from_date=%s&to_date=%s" + URITurnoverDetailsReport string = "/reports/turnover/details/%s?from_date=%s&to_date=%s" + URIPnLReport string = "/reports/pnl/%s?from_date=%s&to_date=%s" + URIMTFInterestReport string = "/reports/mtf_interest/%s?from_date=%s&to_date=%s" + + URITags string = "/reports/tags" + URITag string = "/reports/tags/%d" ) Constants for the API endpoints @@ -55,13 +78,20 @@ func NewError(etype string, message string, data interface{}) error TYPES -type ConvertPositionObject struct { - Exchange ExchangeTypes `json:"exchange"` - Token int `json:"token"` - TransactionType TransactionTypes `json:"transaction_type"` - OldProductType ProductTypes `json:"old_product_type"` - NewProductType ProductTypes `json:"new_product_type"` +type CancelIcebergOrderResponse struct { + Message string `json:"message"` + Status string `json:"status"` +} + +type ConvertPositionRequest struct { + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Quantity int `json:"quantity"` // Required: Quantity of the position to convert. + OldProductType ProductTypes `json:"old_product"` // Required: Old product type of the position. + NewProductType ProductTypes `json:"new_product"` // Required: New product type to convert the position to. } + ConvertPositionRequest represents a request to convert a position. type ConvertPositionResponse struct { Status string `json:"status"` @@ -69,6 +99,16 @@ type ConvertPositionResponse struct { Message string `json:"message"` } +type DateOptionData struct { + StrikePrice float64 `json:"strike_price"` + IV float64 `json:"iv"` + Theta float64 `json:"theta"` + Vega float64 `json:"vega"` + Gamma float64 `json:"gamma"` + CE StockWithGreek `json:"CE"` + PE StockWithGreek `json:"PE"` +} + type Error struct { Code int ErrorType string @@ -80,12 +120,33 @@ type Error struct { func (e Error) Error() string This makes Error a valid Go error type. +type ExchangeDetail struct { + Token int `json:"token"` + Exchange ExchangeTypes `json:"exchange"` + Symbol string `json:"symbol"` +} + type ExchangeDetails struct { Token int `json:"token"` Exchange string `json:"exchange"` Symbol string `json:"symbol"` } +type ExchangeFundResponse struct { + Deposit float64 `json:"deposit"` + FundsTransferred float64 `json:"funds_transferred"` + Collateral float64 `json:"collateral"` + CreditForSale float64 `json:"credit_for_sale"` + OptionCreditForSale float64 `json:"option_credit_for_sale"` + LimitUtilization float64 `json:"limit_utilization"` + MtmAndBookedLoss float64 `json:"mtm_and_booked_loss"` + BookedProfit float64 `json:"booked_profit"` + TotalTradingPower float64 `json:"total_trading_power"` + TotalUtilization float64 `json:"total_utilization"` + NetAvailable float64 `json:"net_available"` + FundsWithdrawal float64 `json:"funds_withdrawal"` +} + type ExchangeTypes string const ( @@ -130,11 +191,113 @@ type FundDetails struct { NetAvailable float64 `json:"net_available"` } +type FundResponse struct { + Nse ExchangeFundResponse `json:"nse"` + Mcx ExchangeFundResponse `json:"mcx"` +} + +type FundWithdrawalCancelRequest struct { + TransactionId string `json:"transaction_id"` // Required: Transaction ID. + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Amount float64 `json:"amount"` // Required: Amount of the withdrawal. +} + FundWithdrawalCancelRequest represents a request to cancel a fund + withdrawal. + +type FundWithdrawalItem struct { + TransactionId string `json:"transaction_id"` + Amount float64 `json:"amount"` + CreatedAt time.Time `json:"created_at"` + Status string `json:"status"` + Exchange ExchangeTypes `json:"exchange"` +} + +type FundWithdrawalListResponse struct { + Status string `json:"status"` + Message string `json:"message,omitempty"` + Data []FundWithdrawalItem `json:"data"` +} + +type FundWithdrawalRequest struct { + BankAccountNumber string `json:"bank_account_number"` // Required: Bank account number. + Ifsc string `json:"ifsc"` // Required: IFSC code. + Amount float64 `json:"amount"` // Required: Amount to withdraw. + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. +} + FundWithdrawalRequest represents a request to withdraw funds. + type FundsResponse struct { NSE FundDetails `json:"nse"` MCX FundDetails `json:"mcx"` } +type Greeks struct { + Theta float64 `json:"theta"` + Delta float64 `json:"delta"` + Gamma float64 `json:"gamma"` + Vega float64 `json:"vega"` + Iv float64 `json:"iv"` +} + +type GttLegs struct { + SlTriggerPercent *float64 `json:"sl_trigger_percent"` // Optional: Stop loss trigger percentage. + ProfitTriggerPercent *float64 `json:"profit_trigger_percent"` // Optional: Profit trigger percentage. +} + GttLegs represents legs of a Good 'til Triggered (GTT) order. + +type GttOrderResponse struct { + Id string `json:"id"` + Token int `json:"token" binding:"required"` + Exchange ExchangeTypes `json:"exchange" binding:"required"` + Symbol string `json:"symbol" binding:"required"` + Series string `json:"series" binding:"required"` + InstrumentName InstrumentName `json:"instrument_name" binding:"required"` + ExpiryDate string `json:"expiry_date" binding:"required"` + StrikePrice float64 `json:"strike_price" binding:"required"` + OptionType OptionType `json:"option_type" binding:"required"` + LotSize int `json:"lot_size" binding:"required"` + TriggerType GttTriggerType `json:"trigger_type" binding:"required"` + TransactionType TransactionTypes `json:"transaction_type" binding:"required"` + TagIds pq.Int32Array `json:"tag_ids"` + Orders []GttOrderResponseOrders `json:"orders" binding:"required"` +} + +type GttOrderResponseOrders struct { + Id uint `json:"id"` + ProductType ProductTypes `json:"product"` + Variety VarietyTypes `json:"variety"` + TransactionType TransactionTypes `json:"transaction_type"` + Price float64 `json:"price"` + TriggerPrice float64 `json:"trigger_price"` + Quantity int `json:"quantity"` + Status GttOrderStatus `json:"status"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + TrigerredAt time.Time `json:"trigerred_at"` +} + +type GttOrderStatus string + +const ( + GttOrderStatusTriggered GttOrderStatus = "triggered" + GttOrderStatusActive GttOrderStatus = "active" + GttOrderStatusCancelled GttOrderStatus = "cancelled" + GttOrderStatusExpired GttOrderStatus = "expired" + GttOrderStatusCompleted GttOrderStatus = "completed" +) +type GttOrderbookResponse struct { + Status string `json:"status"` + Data []*GttOrderResponse `json:"data"` +} + +type GttTriggerType string + GttTriggerType represents the trigger type for a Good 'til Triggered (GTT) + order. + +const ( + GttTriggerTypeSingle GttTriggerType = "single" // Single trigger type. + GttTriggerTypeOCO GttTriggerType = "oco" // One Cancels the Other (OCO) trigger type. +) type HTTPClient interface { GetClient() *httpClient // Has unexported methods. @@ -165,20 +328,67 @@ type HistoricalResponse struct { type Holding struct { ISIN string `json:"isin"` - NSE ExchangeDetails `json:"nse"` - BSE ExchangeDetails `json:"bse"` + NSE *ExchangeDetail `json:"nse,omitempty"` + BSE *ExchangeDetail `json:"bse,omitempty"` TotalFree int `json:"total_free"` DPFree int `json:"dp_free"` PoolFree int `json:"pool_free"` T1Quantity int `json:"t1_quantity"` AveragePrice float64 `json:"average_price"` + LastPrice float64 `json:"last_price"` + Product string `json:"product"` CollateralQuantity int `json:"collateral_quantity"` CollateralValue float64 `json:"collateral_value"` } type HoldingsResponse struct { - Status string `json:"status"` - Data []Holding `json:"data"` + Status string `json:"status"` + Message string `json:"message,omitempty"` + Data []Holding `json:"data"` +} + +type IcebergOrderData struct { + IcebergOrderId string `json:"iceberg_order_id"` + FirstOrderId string `json:"first_order_id"` +} + +type IcebergOrderResponse struct { + Message string `json:"message"` + Code string `json:"code"` + Status string `json:"status"` + Data IcebergOrderData `json:"data"` +} + +type InstrumentName string + +const ( + InstrumentNameEqIndex InstrumentName = "EQIDX" + InstrumentNameCom InstrumentName = "COM" + InstrumentNameEquities InstrumentName = "EQUITIES" + InstrumentNameCommodityFuture InstrumentName = "FUTCOM" + InstrumentNameCurrencyFuture InstrumentName = "FUTCUR" + InstrumentNameIndexFuture InstrumentName = "FUTIDX" + InstrumentNameInterestFuture InstrumentName = "FUTIRC" + InstrumentNameInterestFutureT InstrumentName = "FUTIRT" + InstrumentNameStockFuture InstrumentName = "FUTSTK" + InstrumentNameCurrencyOption InstrumentName = "OPTCUR" + InstrumentNameCommodityOption InstrumentName = "OPTFUT" + InstrumentNameIndexOption InstrumentName = "OPTIDX" + InstrumentNameInterestOption InstrumentName = "OPTIRC" + InstrumentNameStockOption InstrumentName = "OPTSTK" + InstrumentNameCurrentcyUnderlying InstrumentName = "UNDCUR" +) +type LegStockGreek struct { + Token int `json:"token" binding:"required"` + StrikePrice float64 `json:"strike_price"` + OptionType OptionType `json:"option_type"` + ExpYYYYMMDD string `json:"expiry_date"` + Action string `json:"action"` + LotSize int `json:"lot_size"` + Quantity int `json:"quantity"` + Ltp float64 `json:"last_trade_price"` // Update + Iv float64 `json:"iv"` // Update *hide + Greeks Greeks `json:"greeks" gorm:"-"` } type LoginResponse struct { @@ -213,15 +423,37 @@ type Metadata struct { TotalRecords int `json:"total_records"` } +type ModifyGttRequest struct { + Id uint `json:"id"` // Required: Identifier of the GTT order to modify. + TriggerPrice *float64 `json:"trigger_price"` // Required: New trigger price for the GTT order. + Price *float64 `json:"price"` // Required: New price for the GTT order. + Quantity *int `json:"quantity"` // Required: New quantity for the GTT order. +} + ModifyGttRequest represents a request to modify a Good 'til Triggered (GTT) + order. + +type ModifyIcebergOrderRequest struct { + Price float64 `json:"price"` // Required: Price of the order. + TriggerPrice float64 `json:"trigger_price"` // Required: Trigger price for the order. + TradedQuantity int `json:"traded_quantity"` // Required: Quantity already traded. +} + ModifyIcebergOrderRequest represents a request to modify an Iceberg order. + type ModifyOrderRequest struct { - Variety VarietyTypes `json:"variety"` - Quantity int `json:"quantity"` - TradedQuantity int `json:"traded_quantity"` - Price float64 `json:"price"` - TriggerPrice float64 `json:"trigger_price"` - DisclosedQuantity int `json:"disclosed_quantity"` - Validity ValidityTypes `json:"validity"` - ValidityDays int `json:"validity_days"` + Variety VarietyTypes `json:"variety" ` // Required: Type of variety. + Quantity int `json:"quantity" ` // Required: Quantity of the order. + TradedQuantity *int `json:"traded_quantity" ` // Required: Quantity which has already been traded according to you. This is important.. + Price float64 `json:"price" ` // Optional if market order. Price of the order. + TriggerPrice float64 `json:"trigger_price"` // Optional if not stoploss order. Trigger price for the order. + DisclosedQuantity int `json:"disclosed_quantity"` // Optional: Disclosed quantity for the order. + Validity ValidityTypes `json:"validity" ` // Required: Validity type for the order. + ValidityDays int `json:"validity_days"` // Optional: Number of validity days. + TagIds []int `json:"tag_ids"` // Optional: IDs of tags associated with the order. +} + +type NetDayPositions struct { + Net []PositionItem `json:"net"` + Day []PositionItem `json:"day"` } type OhlcvQuoteData struct { @@ -236,49 +468,97 @@ type OhlcvQuoteData struct { ClosePrice float64 `json:"close_price"` } +type OptionChainRequest struct { + Token int `json:"token"` // Required: Token of the underlying instrument. + ExpiryDate string `json:"expiry_date"` // Optional: Expiry date of options in format YYYYMMDD. If not provided, the result will be of the closest expiry. + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + AddGreek bool `json:"greeks"` // Optional: Include Greeks in the result. Default is false. +} + OptionChainRequest represents a request to retrieve an option chain. + +type OptionChainResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Response OptionchainResult `json:"response"` +} + +type OptionType string + +const ( + OptionTypeCall OptionType = "CE" + OptionTypePut OptionType = "PE" +) +type OptionchainResult struct { + Symbol string `json:"symbol"` + ExpiryDate string `json:"expiry_date"` + HasParentStock bool `json:"has_parent_stock"` + ExpiryDates []string `json:"expiry_dates"` + Options struct { + Exchange ExchangeTypes `json:"exchange"` + List []*DateOptionData `json:"list"` + } `json:"options"` + ParentStock struct { + Symbol string `json:"symbol"` + Exchange ExchangeTypes `json:"exchange"` + Token int `json:"token"` + ISINCode string `json:"isin"` + LTP float64 `json:"ltp"` + } `json:"parent"` +} + type Order struct { - OrderID string `json:"order_id"` - Exchange ExchangeTypes `json:"exchange"` - Token int `json:"token"` - OrderNumber string `json:"order_number"` - Status string `json:"status"` - ErrorReason string `json:"error_reason"` - TransactionType TransactionTypes `json:"transaction_type"` - Product ProductTypes `json:"product"` - Variety VarietyTypes `json:"variety"` - TotalQuantity int `json:"total_quantity"` - PendingQuantity int `json:"pending_quantity"` - TradedQuantity int `json:"traded_quantity"` - DisclosedQuantity int `json:"disclosed_quantity"` - DisclosedQuantityRemaining int `json:"disclosed_quantity_remaining"` - OrderPrice float64 `json:"order_price"` - TriggerPrice float64 `json:"trigger_price"` - TradedPrice float64 `json:"traded_price"` - Validity ValidityTypes `json:"validity"` - ValidityDays int `json:"validity_days"` - Symbol string `json:"symbol"` - Series string `json:"series"` - InstrumentName string `json:"instrument_name"` - ExpiryDate string `json:"expiry_date"` - StrikePrice float64 `json:"strike_price"` - OptionType string `json:"option_type"` - LotSize int `json:"lot_size"` - OrderCreatedAt string `json:"order_created_at"` - InitiatedBy string `json:"initiated_by"` - ModifiedBy string `json:"modified_by"` - IsAMO bool `json:"is_amo"` - OrderIdentifier string `json:"order_identifier"` + OrderID string `json:"order_id"` + Exchange ExchangeTypes `json:"exchange"` + Token int `json:"token"` + OrderNumber string `json:"order_number"` + Status string `json:"status"` + ErrorReason string `json:"error_reason"` + TransactionType TransactionTypes `json:"transaction_type"` + Product ProductTypes `json:"product"` + Variety VarietyTypes `json:"variety"` + TotalQuantity int `json:"total_quantity"` + PendingQuantity int `json:"pending_quantity"` + TradedQuantity int `json:"traded_quantity"` + DisclosedQuantity int `json:"disclosed_quantity"` + DisclosedQuantityRemaining int `json:"disclosed_quantity_remaining"` + OrderPrice float64 `json:"order_price"` + TriggerPrice float64 `json:"trigger_price"` + TradedPrice float64 `json:"traded_price,omitempty"` + Validity ValidityTypes `json:"validity"` + Symbol string `json:"symbol"` + Series string `json:"series"` + InstrumentName InstrumentName `json:"instrument_name"` + ExpiryDate string `json:"expiry_date"` + StrikePrice float64 `json:"strike_price"` + OptionType OptionType `json:"option_type"` + LotSize int `json:"lot_size"` + OrderCreatedAt string `json:"order_created_at"` + InitiatedBy string `json:"initiated_by"` + ModifiedBy string `json:"modified_by"` + IsAMO bool `json:"is_amo"` + OrderIdentifier string `json:"order_identifier"` + TagsIds pq.Int32Array `json:"tags_ids"` + MiddlewareOrderId uint `json:"middleware_order_id"` + Iceberg *OrderBookIcebergInfo `json:"iceberg,omitempty"` + Gtt *OrderBookGttInfo `json:"gtt,omitempty"` +} + +type OrderBookGttInfo struct { + TriggerType GttTriggerType `json:"trigger_type"` + SlTriggerPercent *float64 `json:"sl_trigger_percent,omitempty"` + ProfitTriggerPercent *float64 `json:"profit_trigger_percent,omitempty"` +} + +type OrderBookIcebergInfo struct { + IcebergOrderId string `json:"iceberg_order_id"` + IcebergSequence int `json:"iceberg_sequence"` + Legs int `json:"legs"` } type OrderBookResponse struct { - Status string `json:"status"` - Orders []Order `json:"orders"` - Metadata struct { - TotalRecords int `json:"total_records"` - AllRecords int `json:"all_records"` - CompletedRecords int `json:"completed_records"` - OpenRecords int `json:"open_records"` - } `json:"metadata"` + Status string `json:"status"` + Orders []Order `json:"orders"` + Metadata Metadata `json:"metadata"` } type OrderHistory struct { @@ -301,10 +581,10 @@ type OrderHistory struct { ValidityDays int `json:"validity_days"` Symbol string `json:"symbol"` Series string `json:"series"` - InstrumentName string `json:"instrument_name"` + InstrumentName InstrumentName `json:"instrument_name"` ExpiryDate string `json:"expiry_date"` StrikePrice float64 `json:"strike_price"` - OptionType string `json:"option_type"` + OptionType OptionType `json:"option_type"` OrderCreatedAt string `json:"order_created_at"` ExchangeOrderCreatedAt string `json:"exchange_order_created_at"` InitiatedBy string `json:"initiated_by"` @@ -317,52 +597,150 @@ type OrderHistoryResponse struct { Status string `json:"status"` Code string `json:"code"` Message string `json:"message"` - Data []OrderHistory `json:"data"` + Data []OrderHistory `json:"orders"` Metadata Metadata `json:"metadata"` } type OrderMarginRequest struct { - Exchange ExchangeTypes `json:"exchange"` - Token int `json:"token"` - TransactionType TransactionTypes `json:"transaction_type"` - Product ProductTypes `json:"product"` - Variety VarietyTypes `json:"variety"` - Quantity int `json:"quantity"` - Price float64 `json:"price"` - OldPrice float64 `json:"old_price"` - OldQuantity int `json:"old_quantity"` - Mode MarginModes `json:"mode"` + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Product ProductTypes `json:"product"` // Required: Type of product. + Variety VarietyTypes `json:"variety"` // Required: Type of variety. + Quantity int `json:"quantity"` // Required: Quantity of the order. + Price float64 `json:"price"` // Required: Price of the order. + OldPrice float64 `json:"old_price"` // Required: Old price of the order. + OldQuantity int `json:"old_quantity"` // Required: Old quantity of the order. + Mode MarginModes `json:"mode"` // Required: Mode of margin calculation. } + OrderMarginRequest represents a request to calculate margin for an order. type OrderResponse struct { Status string `json:"status"` Code string `json:"code"` Message string `json:"message"` Data struct { - OrderID string `json:"orderId"` + OrderID string `json:"order_id"` } `json:"data"` } +type PayOff struct { + IPayoff float64 `json:"intraday_pay_off"` + EPayoff float64 `json:"expiry_pay_off"` + At float64 `json:"at"` +} + +type PayOffData struct { + MaxLoss float64 `json:"max_loss"` + MaxProfit float64 `json:"max_profit"` + IsInfiniteProfit bool `json:"infinite_profit"` + IsInfiniteLoss bool `json:"infinite_loss"` + BreakEvens []float64 `json:"breakevens"` + PayOffs []PayOff `json:"payoffs"` + CombinedGreeks Greeks `json:"combined_greeks"` + LivePrice float64 `json:"last_trade_price"` + LegStocks []LegStockGreek `json:"leg_greeks"` + MinDaysToExpiry int `json:"min_days_to_expiry"` +} + +type PayoffAction string + +const ( + PayoffActionBUY PayoffAction = "BUY" + PayoffActionSELL PayoffAction = "SELL" +) + PayoffAction represents the action for a trading strategy. + +type PayoffOption struct { + Token int `json:"token"` // Required: Token of the underlying instrument. + Action PayoffAction `json:"action"` // Required: Action for the option. + Quantity int `json:"quantity"` // Required: Quantity of the option. + Ltp float64 `json:"last_trade_price"` // Optional: Last traded price for the option. +} + PayoffOption represents an option within a trading strategy. + +type PayoffRequest struct { + Symbol string `json:"symbol" ` // Required: Symbol for the underlying asset. + Exchange ExchangeTypes `json:"exchange" ` // Required: Exchange type. + Legs []PayoffOption `json:"legs"` // Required: Legs of the trading strategy. + InpDaysToExpiry *int `json:"days_to_expiry"` // Optional: Number of days to expiry. + CurrentPnl float64 `json:"current_pnl"` // Optional: Current profit or loss. +} + PayoffRequest represents a request to calculate the payoff for a trading + strategy. + +type PayoffResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Data PayOffData `json:"data"` +} + +type PlaceGttLegRequest struct { + Quantity int `json:"quantity"` // Required: Quantity of the leg. + Price float64 `json:"price"` // Required: Price of the leg. + TriggerPrice float64 `json:"trigger_price"` // Required: Trigger price for the leg. + ProductType ProductTypes `json:"product"` // Required: Type of product for the leg. +} + PlaceGttLegRequest represents a leg of a Good 'til Triggered (GTT) order. + +type PlaceGttRequest struct { + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Quantity *int `json:"quantity"` // Required: Quantity of the order. + TriggerPrice *float64 `json:"trigger_price"` // Required: Trigger price for the order. + Price *float64 `json:"price"` // Required: Price of the order. + OrderIdentifier string `json:"order_identifier"` // Required: Identifier for the order. + GttTriggerType GttTriggerType `json:"gtt_trigger_type"` // Required: Type of GTT trigger. + Product ProductTypes `json:"product"` // Required: Type of product. + Stoploss *PlaceGttLegRequest `json:"stoploss"` // Optional: Stop loss leg of the GTT order. + Profit *PlaceGttLegRequest `json:"profit"` // Optional: Profit leg of the GTT order. + TagIds []int `json:"tag_ids"` // Required: IDs of tags associated with the order. +} + PlaceGttRequest represents a request to place a Good 'til Triggered (GTT) + order. + +type PlaceIcebergOrderRequest struct { + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Product ProductTypes `json:"product"` // Required: Type of product. + Variety VarietyTypes `json:"variety"` // Required: Type of variety. + Quantity int `json:"quantity"` // Required: Quantity of the order. + Price *float64 `json:"price"` // Optional if market order. Price of the order. + TriggerPrice float64 `json:"trigger_price"` // Optional if not stoploss order. Trigger price for the order. + OrderIdentifier string `json:"order_identifier"` // Optional: Your identifier for the order. + Validity ValidityTypes `json:"validity"` // Required: Validity type for the order. + Legs int `json:"legs"` // Required: Number of legs for the order. + TagIds pq.Int32Array `json:"tag_ids"` // IDs of tags associated with the order. +} + PlaceIcebergOrderRequest represents a request to place an Iceberg order. + type PlaceOrderRequest struct { - Exchange ExchangeTypes `json:"exchange"` - Token int `json:"token"` - TransactionType TransactionTypes `json:"transaction_type"` - Product ProductTypes `json:"product"` - Variety VarietyTypes `json:"variety"` - Quantity int `json:"quantity"` - Price float64 `json:"price"` - TriggerPrice float64 `json:"trigger_price"` - DisclosedQuantity int `json:"disclosed_quantity"` - Validity ValidityTypes `json:"validity"` - ValidityDays int `json:"validity_days"` - IsAMO bool `json:"is_amo"` -} - -type Position struct { + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Product ProductTypes `json:"product"` // Required: Type of product. + Variety VarietyTypes `json:"variety"` // Required: Type of variety. + Quantity int `json:"quantity"` // Required: Quantity of the order. + Price float64 `json:"price"` // Optional if market order. Price of the order. + TriggerPrice float64 `json:"trigger_price"` // Optional if not stoploss order. Trigger price for the order. + OrderIdentifier string `json:"order_identifier"` // Optional: Your identifier for the order. + DisclosedQuantity int `json:"disclosed_quantity"` // Optional: Disclosed quantity for the order. + Validity ValidityTypes `json:"validity"` // Required: Validity type for the order. + ValidityDays int `json:"validity_days"` // Optional: Number of validity days. + IsAMO bool `json:"is_amo"` // Optional: Flag indicating if the order is an after-market order. + Gtt *GttLegs `json:"gtt"` // Optional: Good 'til Triggered (GTT) legs. + TagIds []int `json:"tag_ids"` // Optional: IDs of tags associated with the order. +} + PlaceOrderRequest represents a request to place an order. + +type PositionItem struct { Exchange ExchangeTypes `json:"exchange"` Symbol string `json:"symbol"` ExpiryDate string `json:"expiry_date"` - OptionType string `json:"option_type"` + OptionType OptionType `json:"option_type"` + StrikePrice float64 `json:"strike_price"` Token int `json:"token"` Product ProductTypes `json:"product"` Quantity int `json:"quantity"` @@ -381,16 +759,19 @@ type Position struct { SellPrice float64 `json:"sell_price"` } -type PositionData struct { - Net []Position `json:"net"` - Day []Position `json:"day"` -} - type PositionResponse struct { - Status string `json:"status"` - Data PositionData `json:"data"` + Status string `json:"status"` + Data NetDayPositions `json:"data"` } +type PredictionType string + PredictionType represents the type of prediction for a trading strategy. + +const ( + PredictionTypeABOVE PredictionType = "ABOVE" // Predict that the asset price will be above a certain level. + PredictionTypeBELOW PredictionType = "BELOW" // Predict that the asset price will be below a certain level. + PredictionTypeBETWEEN PredictionType = "BETWEEN" // Predict that the asset price will be within a certain range. +) type ProductTypes string const ( @@ -504,6 +885,105 @@ type SocketMessageData struct { GtdOrderStatus string `json:"gtd_order_status"` } +type StockWithGreek struct { + Token int `json:"token"` + InstrumentName string `json:"instrument_name"` + LotSize int `json:"lot_size"` + SecurityDesc string `json:"security_description"` + Eligibility int `json:"eligibility"` + Ltp float64 `json:"ltp"` + OpenInterest int `json:"open_interest"` + DayFirstTickOI int `json:"day_first_tick_oi" ` + Volume int `json:"volume"` + Delta float64 `json:"delta"` +} + +type StrategiesRequest struct { + Token int `json:"token"` // Required: Token for authentication. + Symbol string `json:"symbol"` // Required: Symbol for the underlying asset. + ExpYYYYMMDD string `json:"expiry_date"` // Required: Expiry date of the strategy in format YYYYMMDD. +} + StrategiesRequest represents a request to retrieve strategies. + +type StrategiesResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Data StrategiesResult `json:"data"` +} + +type StrategiesResult struct { + Symbol string `json:"symbol"` + Token int `json:"token"` + Ltp float64 `json:"ltp"` + Strategies []Strategy `json:"strategies"` +} + +type Strategy struct { + Name string `json:"strategy_name"` + TradingOpportunities []TradingOpportunity `json:"trading_opportunities"` +} + +type StrategyBuilderRequest struct { + Token int `json:"token"` // Required: Token of the underlying instrument. + Symbol string `json:"symbol"` // Required: Symbol of the underlying instrument. + MarketView PredictionType `json:"prediction"` // Required: Prediction type. Should be one of ["ABOVE", "BELOW", "BETWEEN"] + ExpiryDate string `json:"expiry_date"` // Required: Expiry date of options in format: YYYYMMDD + PriceRange []float64 `json:"price_range"` // Price range for the strategy. +} + +type StrategyLeg struct { + Option StrategyStock `json:"option"` + Action string `json:"action"` + Quantity int `json:"quantity"` +} + +type StrategyStock struct { + Token int `json:"token"` + InstrumentName string `json:"instrument_name"` + Symbol string `json:"symbol"` + StrikePrice float64 `json:"strike_price"` + OptionType OptionType `json:"option_type"` + LotSize int `json:"lot_size"` + SecurityDesc string `json:"security_description"` + Exchange ExchangeTypes `json:"exchange"` + ExpYyyymmdd string `json:"expiry_date"` + Ltp float64 `json:"ltp"` + Greeks struct { + Theta float64 `json:"theta"` + Delta float64 `json:"delta"` + Gamma float64 `json:"gamma"` + Vega float64 `json:"vega"` + Iv float64 `json:"iv"` + } `json:"greeks"` +} + +type TagInfo struct { + Id int `json:"id"` + ClientCode string `json:"client_code"` + Name string `json:"name"` + Description string `json:"description"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +type TagRequest struct { + Name string `json:"name"` // Name of the tag. + Description string `json:"description"` // Description of the tag. +} + TagRequest represents a request to create a tag. + +type TagResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Data TagInfo `json:"data"` +} + +type TagsResponse struct { + Status string `json:"status"` + Message string `json:"message"` + Data []TagInfo `json:"data"` +} + type Trade struct { OrderID string `json:"order_id"` Exchange ExchangeTypes `json:"exchange"` @@ -520,7 +1000,7 @@ type Trade struct { InstrumentName string `json:"instrument_name"` ExpiryDate string `json:"expiry_date"` StrikePrice float64 `json:"strike_price"` - OptionType string `json:"option_type"` + OptionType OptionType `json:"option_type"` TradedAt string `json:"traded_at"` InitiatedBy string `json:"initiated_by"` ModifiedBy string `json:"modified_by"` @@ -535,6 +1015,15 @@ type TradeBookResponse struct { } `json:"metadata"` } +type TradingOpportunity struct { + Legs []StrategyLeg `json:"legs"` + MaxLoss float64 `json:"max_loss"` + MaxProfit float64 `json:"max_profit"` + IsInfiniteProfit bool `json:"is_infinite_profit"` + IsInfiniteLoss bool `json:"is_infinite_loss"` + BreakEven []float64 `json:"breakeven"` +} + type TransactionTypes string const ( @@ -579,12 +1068,36 @@ type VortexApi struct { } VortexApi is a struct representing the Vortex API client -func (v *VortexApi) CancelOrder(ctx context.Context, exchange ExchangeTypes, orderID string) (*OrderResponse, error) +func (v *VortexApi) BuildStrategy(ctx context.Context, req StrategyBuilderRequest) (*StrategiesResponse, error) + BuildStrategy initiates the strategy building process with the Vortex API + based on the provided StrategyBuilderRequest. It takes a context and a + StrategyBuilderRequest as input. It returns a StrategiesResponse and an + error. + +func (v *VortexApi) CancelGttOrder(ctx context.Context, gtt_order_id string) (*OrderResponse, error) + CancelGttOrder cancels an existing Good Till Trigger (GTT) order with the + Vortex API. It takes a context and a GTT order ID as input. It returns an + OrderResponse and an error. + +func (v *VortexApi) CancelIcebergOrder(ctx context.Context, iceberg_order_id string) (*CancelIcebergOrderResponse, error) + CancelIcebergOrder cancels an existing iceberg order with the Vortex API. + It takes a context and an iceberg order ID as input. It returns a + CancelIcebergOrderResponse and an error. + +func (v *VortexApi) CancelOrder(ctx context.Context, orderID string) (*OrderResponse, error) CancelOrder cancels an existing order with the Vortex API. It takes a context, an ExchangeTypes value, and an order ID as input. It returns an OrderResponse and an error. -func (v *VortexApi) ConvertPosition(ctx context.Context, req ConvertPositionObject) (*ConvertPositionResponse, error) +func (v *VortexApi) ConvertPosition(ctx context.Context, req ConvertPositionRequest) (*ConvertPositionResponse, error) + +func (v *VortexApi) CreateTag(ctx context.Context, request TagRequest) (*TagResponse, error) + CreateTag creates a new tag with the Vortex API. It takes a context and a + TagRequest as input. It returns a TagResponse and an error. + +func (v *VortexApi) DeleteTag(ctx context.Context, tag_id int) (*TagResponse, error) + DeleteTag deletes an existing tag with the Vortex API. It takes a context + and a tag ID as input. It returns a TagResponse and an error. func (v *VortexApi) DownloadMaster(ctx context.Context) ([]map[string]string, error) DownloadMaster retrieves the master data from the Vortex API. It returns a @@ -596,6 +1109,26 @@ func (v *VortexApi) Funds(ctx context.Context) (*FundsResponse, error) func (v *VortexApi) GetLoginUrl() string GetLoginUrl returns the login URL for the Vortex API +func (v *VortexApi) GetOptionChain(ctx context.Context, req OptionChainRequest) (*OptionChainResponse, error) + GetOptionChain retrieves the option chain from the Vortex API based on the + provided OptionChainRequest. It takes a context and an OptionChainRequest as + input. It returns an OptionChainResponse and an error. + +func (v *VortexApi) GetPayoff(ctx context.Context, req PayoffRequest) (*PayoffResponse, error) + GetPayoff calculates the payoff for strategies with the Vortex API based on + the provided PayoffRequest. It takes a context and a PayoffRequest as input. + It returns a PayoffResponse and an error. + +func (v *VortexApi) GetStrategies(ctx context.Context, req StrategiesRequest) (*StrategiesResponse, error) + GetStrategies retrieves strategies from the Vortex API based on the provided + StrategiesRequest. It takes a context and a StrategiesRequest as input. + It returns a StrategiesResponse and an error. + +func (v *VortexApi) GttOrders(ctx context.Context) (*GttOrderbookResponse, error) + GttOrders retrieves the Good Till Trigger (GTT) orderbook from the Vortex + API. It takes a context as input. It returns a GttOrderbookResponse and an + error. + func (v *VortexApi) HistoricalCandles(ctx context.Context, exchange ExchangeTypes, token int, from time.Time, to time.Time, resolution Resolutions) (*HistoricalResponse, error) HistoricalCandles retrieves historical candlestick data from the Vortex API. It takes a context, an ExchangeTypes value, a token, a start time, an end @@ -608,10 +1141,20 @@ func (v *VortexApi) Holdings(ctx context.Context) (*HoldingsResponse, error) func (v *VortexApi) Login(ctx context.Context, clientCode string, password string, totp string) (*LoginResponse, error) Login performs the login operation in the Vortex API. It takes a context, - client code, password, and TOTP (Time-Based One-Time Password) as input. If - the login is successful, the method updates the accessToken field of the + client code, password, and TOTP (Time-Based One-Time Password) as input. + If the login is successful, the method updates the accessToken field of the VortexApi instance. It returns the LoginResponse and an error. +func (v *VortexApi) ModifyGttOrder(ctx context.Context, gtt_order_id string, request ModifyGttRequest) (*OrderResponse, error) + ModifyGttOrder modifies an existing Good Till Trigger (GTT) order with the + Vortex API. It takes a context, a GTT order ID, and a ModifyGttRequest as + input. It returns an OrderResponse and an error. + +func (v *VortexApi) ModifyIcebergOrder(ctx context.Context, iceberg_order_id string, request ModifyIcebergOrderRequest) (*IcebergOrderResponse, error) + ModifyIcebergOrder modifies an existing iceberg order with the Vortex API. + It takes a context, an iceberg order ID, and a ModifyIcebergOrderRequest as + input. It returns an IcebergOrderResponse and an error. + func (v *VortexApi) ModifyOrder(ctx context.Context, request ModifyOrderRequest, exchange ExchangeTypes, orderID string) (*OrderResponse, error) ModifyOrder modifies an existing order with the Vortex API. It takes a context, a ModifyOrderRequest, an ExchangeTypes value, and an order ID as @@ -625,38 +1168,56 @@ func (v *VortexApi) OrderMargin(ctx context.Context, request *OrderMarginRequest context and an OrderMarginRequest as input. It returns a MarginResponse and an error. -func (v *VortexApi) Orders(ctx context.Context, offset int, limit int) (*OrderBookResponse, error) +func (v *VortexApi) Orders(ctx context.Context) (*OrderBookResponse, error) Orders retrieves the order book information from the Vortex API. It takes a context, an offset, and a limit as input. It returns an OrderBookResponse and an error. +func (v *VortexApi) PlaceGttOrder(ctx context.Context, request PlaceGttRequest) (*OrderResponse, error) + PlaceGttOrder places a Good Till Trigger (GTT) order with the Vortex API. It + takes a context and a PlaceGttRequest as input. It returns an OrderResponse + and an error. + +func (v *VortexApi) PlaceIcebergOrder(ctx context.Context, request PlaceIcebergOrderRequest) (*IcebergOrderResponse, error) + PlaceIcebergOrder places an iceberg order with the Vortex API. + It takes a context and a PlaceIcebergOrderRequest as input. It returns an + IcebergOrderResponse and an error. + func (v *VortexApi) PlaceOrder(ctx context.Context, request PlaceOrderRequest) (*OrderResponse, error) - PlaceOrder places an order with the Vortex API. It takes a context and a - PlaceOrderRequest as input. The request's Validity field is used to + PlaceOrder places an order with the Vortex API. It takes a context and + a PlaceOrderRequest as input. The request's Validity field is used to determine the ValidityDays and IsAMO values. It returns an OrderResponse and an error. func (v *VortexApi) Positions(ctx context.Context) (*PositionResponse, error) - Positions retrieves the positions information from the Vortex API. It - returns a PositionsResponse and an error. + Positions retrieves the positions information from the Vortex API. + It returns a PositionsResponse and an error. func (v *VortexApi) Quotes(ctx context.Context, instruments []string, mode QuoteModes) (*QuoteResponse, error) Quotes retrieves real-time quote information for the specified instruments - from the Vortex API. It takes a context, a slice of instrument names, and a - quote mode as input. It returns a QuoteResponse and an error. + from the Vortex API. It takes a context, a slice of instrument names, + and a quote mode as input. It returns a QuoteResponse and an error. func (v *VortexApi) SetAccessToken(accessToken string) func (v *VortexApi) SetHTTPClient(h *http.Client) SetHTTPClient sets the HTTP client for the Vortex API client -func (v *VortexApi) SetLogging(h *http.Client) +func (v *VortexApi) SetLogging(flag bool) SetLogging sets the HTTP client with logging enabled +func (v *VortexApi) Tags(ctx context.Context) (*TagsResponse, error) + Tags retrieves the list of tags from the Vortex API. It takes a context as + input. It returns a TagsResponse and an error. + func (v *VortexApi) Trades(ctx context.Context, offset int, limit int) (*TradeBookResponse, error) Trades retrieves the trade book information from the Vortex API. It returns a TradeBookResponse and an error. +func (v *VortexApi) UpdateTag(ctx context.Context, tag_id int, request TagRequest) (*TagResponse, error) + UpdateTag updates an existing tag with the Vortex API. It takes a context, + a tag ID, and a TagRequest as input. It returns a TagResponse and an error. + type Wire struct { Conn *websocket.Conn diff --git a/requests.go b/requests.go index dc9e054..1f6703a 100644 --- a/requests.go +++ b/requests.go @@ -4,177 +4,203 @@ import ( "github.com/lib/pq" ) +// PlaceOrderRequest represents a request to place an order. type PlaceOrderRequest struct { - Exchange ExchangeTypes `json:"exchange"` - Token int `json:"token"` - TransactionType TransactionTypes `json:"transaction_type"` - Product ProductTypes `json:"product"` - Variety VarietyTypes `json:"variety"` - Quantity int `json:"quantity"` - Price float64 `json:"price"` - TriggerPrice float64 `json:"trigger_price"` - OrderIdentifier string `json:"order_identifier"` - DisclosedQuantity int `json:"disclosed_quantity"` - Validity ValidityTypes `json:"validity"` - ValidityDays int `json:"validity_days"` - IsAMO bool `json:"is_amo"` - Gtt *GttLegs `json:"gtt"` - TagIds []int `json:"tag_ids"` -} - + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Product ProductTypes `json:"product"` // Required: Type of product. + Variety VarietyTypes `json:"variety"` // Required: Type of variety. + Quantity int `json:"quantity"` // Required: Quantity of the order. + Price float64 `json:"price"` // Optional if market order. Price of the order. + TriggerPrice float64 `json:"trigger_price"` // Optional if not stoploss order. Trigger price for the order. + OrderIdentifier string `json:"order_identifier"` // Optional: Your identifier for the order. + DisclosedQuantity int `json:"disclosed_quantity"` // Optional: Disclosed quantity for the order. + Validity ValidityTypes `json:"validity"` // Required: Validity type for the order. + ValidityDays int `json:"validity_days"` // Optional: Number of validity days. + IsAMO bool `json:"is_amo"` // Optional: Flag indicating if the order is an after-market order. + Gtt *GttLegs `json:"gtt"` // Optional: Good 'til Triggered (GTT) legs. + TagIds []int `json:"tag_ids"` // Optional: IDs of tags associated with the order. +} + +// GttLegs represents legs of a Good 'til Triggered (GTT) order. type GttLegs struct { - SlTriggerPercent *float64 `json:"sl_trigger_percent"` - ProfitTriggerPercent *float64 `json:"profit_trigger_percent"` + SlTriggerPercent *float64 `json:"sl_trigger_percent"` // Optional: Stop loss trigger percentage. + ProfitTriggerPercent *float64 `json:"profit_trigger_percent"` // Optional: Profit trigger percentage. } type ModifyOrderRequest struct { - Variety VarietyTypes `json:"variety" ` - Quantity int `json:"quantity" ` - TradedQuantity *int `json:"traded_quantity" ` - Price float64 `json:"price" ` - TriggerPrice float64 `json:"trigger_price"` - DisclosedQuantity int `json:"disclosed_quantity"` - Validity ValidityTypes `json:"validity" ` - ValidityDays int `json:"validity_days"` - TagIds []int `json:"tag_ids"` -} - + Variety VarietyTypes `json:"variety" ` // Required: Type of variety. + Quantity int `json:"quantity" ` // Required: Quantity of the order. + TradedQuantity *int `json:"traded_quantity" ` // Required: Quantity which has already been traded according to you. This is important.. + Price float64 `json:"price" ` // Optional if market order. Price of the order. + TriggerPrice float64 `json:"trigger_price"` // Optional if not stoploss order. Trigger price for the order. + DisclosedQuantity int `json:"disclosed_quantity"` // Optional: Disclosed quantity for the order. + Validity ValidityTypes `json:"validity" ` // Required: Validity type for the order. + ValidityDays int `json:"validity_days"` // Optional: Number of validity days. + TagIds []int `json:"tag_ids"` // Optional: IDs of tags associated with the order. +} + +// OrderMarginRequest represents a request to calculate margin for an order. type OrderMarginRequest struct { - Exchange ExchangeTypes `json:"exchange"` - Token int `json:"token"` - TransactionType TransactionTypes `json:"transaction_type"` - Product ProductTypes `json:"product"` - Variety VarietyTypes `json:"variety"` - Quantity int `json:"quantity"` - Price float64 `json:"price"` - OldPrice float64 `json:"old_price"` - OldQuantity int `json:"old_quantity"` - Mode MarginModes `json:"mode"` -} - + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Product ProductTypes `json:"product"` // Required: Type of product. + Variety VarietyTypes `json:"variety"` // Required: Type of variety. + Quantity int `json:"quantity"` // Required: Quantity of the order. + Price float64 `json:"price"` // Required: Price of the order. + OldPrice float64 `json:"old_price"` // Required: Old price of the order. + OldQuantity int `json:"old_quantity"` // Required: Old quantity of the order. + Mode MarginModes `json:"mode"` // Required: Mode of margin calculation. +} + +// ConvertPositionRequest represents a request to convert a position. type ConvertPositionRequest struct { - Exchange ExchangeTypes `json:"exchange" ` - Token int `json:"token" ` - TransactionType TransactionTypes `json:"transaction_type" ` - Quantity int `json:"quantity" ` - OldProductType ProductTypes `json:"old_product" ` - NewProductType ProductTypes `json:"new_product" ` + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Quantity int `json:"quantity"` // Required: Quantity of the position to convert. + OldProductType ProductTypes `json:"old_product"` // Required: Old product type of the position. + NewProductType ProductTypes `json:"new_product"` // Required: New product type to convert the position to. } +// ModifyGttRequest represents a request to modify a Good 'til Triggered (GTT) order. type ModifyGttRequest struct { - Id uint `json:"id" ` - TriggerPrice *float64 `json:"trigger_price"` - Price *float64 `json:"price"` - Quantity *int `json:"quantity"` + Id uint `json:"id"` // Required: Identifier of the GTT order to modify. + TriggerPrice *float64 `json:"trigger_price"` // Required: New trigger price for the GTT order. + Price *float64 `json:"price"` // Required: New price for the GTT order. + Quantity *int `json:"quantity"` // Required: New quantity for the GTT order. } +// PlaceGttRequest represents a request to place a Good 'til Triggered (GTT) order. type PlaceGttRequest struct { - Exchange ExchangeTypes `json:"exchange"` - Token int `json:"token"` - TransactionType TransactionTypes `json:"transaction_type"` - Quantity *int `json:"quantity"` - TriggerPrice *float64 `json:"trigger_price"` - Price *float64 `json:"price"` - OrderIdentifier string `json:"order_identifier"` - GttTriggerType GttTriggerType `json:"gtt_trigger_type"` - Product ProductTypes `json:"product"` - Stoploss *PlaceGttLegRequest `json:"stoploss"` - Profit *PlaceGttLegRequest `json:"profit"` - TagIds []int `json:"tag_ids"` -} + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Quantity *int `json:"quantity"` // Required: Quantity of the order. + TriggerPrice *float64 `json:"trigger_price"` // Required: Trigger price for the order. + Price *float64 `json:"price"` // Required: Price of the order. + OrderIdentifier string `json:"order_identifier"` // Required: Identifier for the order. + GttTriggerType GttTriggerType `json:"gtt_trigger_type"` // Required: Type of GTT trigger. + Product ProductTypes `json:"product"` // Required: Type of product. + Stoploss *PlaceGttLegRequest `json:"stoploss"` // Optional: Stop loss leg of the GTT order. + Profit *PlaceGttLegRequest `json:"profit"` // Optional: Profit leg of the GTT order. + TagIds []int `json:"tag_ids"` // Required: IDs of tags associated with the order. +} + +// PlaceGttLegRequest represents a leg of a Good 'til Triggered (GTT) order. type PlaceGttLegRequest struct { - Quantity int `json:"quantity"` - Price float64 `json:"price"` - TriggerPrice float64 `json:"trigger_price"` - ProductType ProductTypes `json:"product"` + Quantity int `json:"quantity"` // Required: Quantity of the leg. + Price float64 `json:"price"` // Required: Price of the leg. + TriggerPrice float64 `json:"trigger_price"` // Required: Trigger price for the leg. + ProductType ProductTypes `json:"product"` // Required: Type of product for the leg. } +// GttTriggerType represents the trigger type for a Good 'til Triggered (GTT) order. type GttTriggerType string const ( - GttTriggerTypeSingle GttTriggerType = "single" - GttTriggerTypeOCO GttTriggerType = "oco" + GttTriggerTypeSingle GttTriggerType = "single" // Single trigger type. + GttTriggerTypeOCO GttTriggerType = "oco" // One Cancels the Other (OCO) trigger type. ) +// PlaceIcebergOrderRequest represents a request to place an Iceberg order. type PlaceIcebergOrderRequest struct { - Exchange ExchangeTypes `json:"exchange" ` - Token int `json:"token" ` - TransactionType TransactionTypes `json:"transaction_type" ` - Product ProductTypes `json:"product" ` - Variety VarietyTypes `json:"variety" ` - Quantity int `json:"quantity" ` - Price *float64 `json:"price" ` - TriggerPrice float64 `json:"trigger_price"` - OrderIdentifier string `json:"order_identifier"` - Validity ValidityTypes `json:"validity" ` - Legs int `json:"legs" ` - TagIds pq.Int32Array `json:"tag_ids"` -} - + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Token int `json:"token"` // Required: Token of the underlying instrument. + TransactionType TransactionTypes `json:"transaction_type"` // Required: Type of transaction. + Product ProductTypes `json:"product"` // Required: Type of product. + Variety VarietyTypes `json:"variety"` // Required: Type of variety. + Quantity int `json:"quantity"` // Required: Quantity of the order. + Price *float64 `json:"price"` // Optional if market order. Price of the order. + TriggerPrice float64 `json:"trigger_price"` // Optional if not stoploss order. Trigger price for the order. + OrderIdentifier string `json:"order_identifier"` // Optional: Your identifier for the order. + Validity ValidityTypes `json:"validity"` // Required: Validity type for the order. + Legs int `json:"legs"` // Required: Number of legs for the order. + TagIds pq.Int32Array `json:"tag_ids"` // IDs of tags associated with the order. +} + +// FundWithdrawalRequest represents a request to withdraw funds. type FundWithdrawalRequest struct { - BankAccountNumber string `json:"bank_account_number"` - Ifsc string `json:"ifsc"` - Amount float64 `json:"amount"` - Exchange ExchangeTypes `json:"exchange"` + BankAccountNumber string `json:"bank_account_number"` // Required: Bank account number. + Ifsc string `json:"ifsc"` // Required: IFSC code. + Amount float64 `json:"amount"` // Required: Amount to withdraw. + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. } +// FundWithdrawalCancelRequest represents a request to cancel a fund withdrawal. type FundWithdrawalCancelRequest struct { - TransactionId string `json:"transaction_id"` - Exchange ExchangeTypes `json:"exchange"` - Amount float64 `json:"amount"` + TransactionId string `json:"transaction_id"` // Required: Transaction ID. + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + Amount float64 `json:"amount"` // Required: Amount of the withdrawal. } +// TagRequest represents a request to create a tag. type TagRequest struct { - Name string `json:"name"` - Description string `json:"description"` + Name string `json:"name"` // Name of the tag. + Description string `json:"description"` // Description of the tag. } +// ModifyIcebergOrderRequest represents a request to modify an Iceberg order. type ModifyIcebergOrderRequest struct { - Price float64 `json:"price"` - TriggerPrice float64 `json:"trigger_price" ` - TradedQuantity int `json:"traded_quantity"` + Price float64 `json:"price"` // Required: Price of the order. + TriggerPrice float64 `json:"trigger_price"` // Required: Trigger price for the order. + TradedQuantity int `json:"traded_quantity"` // Required: Quantity already traded. } +// StrategiesRequest represents a request to retrieve strategies. type StrategiesRequest struct { - Token int `json:"token"` - Symbol string `json:"symbol"` - ExpYYYYMMDD string `json:"expiry_date"` + Token int `json:"token"` // Required: Token for authentication. + Symbol string `json:"symbol"` // Required: Symbol for the underlying asset. + ExpYYYYMMDD string `json:"expiry_date"` // Required: Expiry date of the strategy in format YYYYMMDD. } +// OptionChainRequest represents a request to retrieve an option chain. type OptionChainRequest struct { - Token int `json:"token"` // required - ExpiryDate string `json:"expiry_date"` //optional. format: YYYYMMDD. If not provided, result will be of closest expiry - Exchange ExchangeTypes `json:"exchange"` // required - AddGreek bool `json:"greeks"` // optional. default: false + Token int `json:"token"` // Required: Token of the underlying instrument. + ExpiryDate string `json:"expiry_date"` // Optional: Expiry date of options in format YYYYMMDD. If not provided, the result will be of the closest expiry. + Exchange ExchangeTypes `json:"exchange"` // Required: Exchange type. + AddGreek bool `json:"greeks"` // Optional: Include Greeks in the result. Default is false. } type StrategyBuilderRequest struct { - Token int `json:"token"` // required - Symbol string `json:"symbol"` - MarketView PredictionType `json:"prediction"` // ["ABOVE", "BELOW", "BETWEEN"] - ExpiryDate string `json:"expiry_date"` //required. format: YYYYMMDD - PriceRange []float64 `json:"price_range"` + Token int `json:"token"` // Required: Token of the underlying instrument. + Symbol string `json:"symbol"` // Required: Symbol of the underlying instrument. + MarketView PredictionType `json:"prediction"` // Required: Prediction type. Should be one of ["ABOVE", "BELOW", "BETWEEN"] + ExpiryDate string `json:"expiry_date"` // Required: Expiry date of options in format: YYYYMMDD + PriceRange []float64 `json:"price_range"` // Price range for the strategy. } +// PredictionType represents the type of prediction for a trading strategy. type PredictionType string +type PayoffAction string + +const ( + PredictionTypeABOVE PredictionType = "ABOVE" // Predict that the asset price will be above a certain level. + PredictionTypeBELOW PredictionType = "BELOW" // Predict that the asset price will be below a certain level. + PredictionTypeBETWEEN PredictionType = "BETWEEN" // Predict that the asset price will be within a certain range. +) +// PayoffAction represents the action for a trading strategy. const ( - PredictionTypeABOVE PredictionType = "ABOVE" - PredictionTypeBELOW PredictionType = "BELOW" - PredictionTypeBETWEEN PredictionType = "BETWEEN" + PayoffActionBUY PayoffAction = "BUY" + PayoffActionSELL PayoffAction = "SELL" ) +// PayoffRequest represents a request to calculate the payoff for a trading strategy. type PayoffRequest struct { - Symbol string `json:"symbol" ` //required - Exchange ExchangeTypes `json:"exchange" ` //required - Legs []PayoffOption `json:"legs"` //required - InpDaysToExpiry *int `json:"days_to_expiry"` - CurrentPnl float64 `json:"current_pnl"` + Symbol string `json:"symbol" ` // Required: Symbol for the underlying asset. + Exchange ExchangeTypes `json:"exchange" ` // Required: Exchange type. + Legs []PayoffOption `json:"legs"` // Required: Legs of the trading strategy. + InpDaysToExpiry *int `json:"days_to_expiry"` // Optional: Number of days to expiry. + CurrentPnl float64 `json:"current_pnl"` // Optional: Current profit or loss. } +// PayoffOption represents an option within a trading strategy. type PayoffOption struct { - Token int `json:"token"` //required - Action string `json:"action"` //required - Quantity int `json:"quantity"` //required, in lots - Ltp float64 `json:"last_trade_price"` //optional + Token int `json:"token"` // Required: Token of the underlying instrument. + Action PayoffAction `json:"action"` // Required: Action for the option. + Quantity int `json:"quantity"` // Required: Quantity of the option. + Ltp float64 `json:"last_trade_price"` // Optional: Last traded price for the option. } diff --git a/strategies.go b/strategies.go index a33735d..521768e 100644 --- a/strategies.go +++ b/strategies.go @@ -4,6 +4,9 @@ import ( "context" ) +// GetStrategies retrieves strategies from the Vortex API based on the provided StrategiesRequest. +// It takes a context and a StrategiesRequest as input. +// It returns a StrategiesResponse and an error. func (v *VortexApi) GetStrategies(ctx context.Context, req StrategiesRequest) (*StrategiesResponse, error) { var resp StrategiesResponse _, err := v.doJson(ctx, "POST", URIStrategies, req, nil, nil, &resp) @@ -13,6 +16,9 @@ func (v *VortexApi) GetStrategies(ctx context.Context, req StrategiesRequest) (* return &resp, nil } +// GetOptionChain retrieves the option chain from the Vortex API based on the provided OptionChainRequest. +// It takes a context and an OptionChainRequest as input. +// It returns an OptionChainResponse and an error. func (v *VortexApi) GetOptionChain(ctx context.Context, req OptionChainRequest) (*OptionChainResponse, error) { var resp OptionChainResponse _, err := v.doJson(ctx, "POST", URIOptionChain, req, nil, nil, &resp) @@ -22,6 +28,9 @@ func (v *VortexApi) GetOptionChain(ctx context.Context, req OptionChainRequest) return &resp, nil } +// BuildStrategy initiates the strategy building process with the Vortex API based on the provided StrategyBuilderRequest. +// It takes a context and a StrategyBuilderRequest as input. +// It returns a StrategiesResponse and an error. func (v *VortexApi) BuildStrategy(ctx context.Context, req StrategyBuilderRequest) (*StrategiesResponse, error) { var resp StrategiesResponse _, err := v.doJson(ctx, "POST", URIBuildStrategies, req, nil, nil, &resp) @@ -31,6 +40,9 @@ func (v *VortexApi) BuildStrategy(ctx context.Context, req StrategyBuilderReques return &resp, nil } +// GetPayoff calculates the payoff for strategies with the Vortex API based on the provided PayoffRequest. +// It takes a context and a PayoffRequest as input. +// It returns a PayoffResponse and an error. func (v *VortexApi) GetPayoff(ctx context.Context, req PayoffRequest) (*PayoffResponse, error) { var resp PayoffResponse _, err := v.doJson(ctx, "POST", URIPayoffStrategies, req, nil, nil, &resp) From a9402795a1c96099d33f11aaafab3042da10dbb2 Mon Sep 17 00:00:00 2001 From: shauryam Date: Wed, 7 Feb 2024 10:55:58 +0530 Subject: [PATCH 04/12] fixes examples --- examples/api/api.go | 52 +++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/examples/api/api.go b/examples/api/api.go index c40d67f..c3c08bc 100644 --- a/examples/api/api.go +++ b/examples/api/api.go @@ -2,48 +2,40 @@ package main import ( "context" - "encoding/json" - "fmt" govortex "github.com/AsthaTech/govortex" ) const ( - applicationId string = "dev_hK7M2HWR" - apiKey string = "TYB7g0bdJFvvQOfIXsgquaDfupLieYZlOHNMRAeO" + applicationId string = "testApplicationId" + apiKey string = "testApiKey" ) func main() { var client govortex.VortexApi govortex.InitializeVortexApi(applicationId, apiKey, &client) - client.SetLogging(true) ctx := context.Background() - client.Login(ctx, "600S1871", "ApiTesting1$", "136000") - client.SetAccessToken("eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDcxODY2MDAsImlhdCI6MTcwNzEzMjQyMCwiaXNzIjoiQXN0aGFUcmFkZSIsInN1YiI6IjYwMFMxODcxIiwiZGV2aWNlSWQiOiJhcGktY2xpZW50IiwiYXBwbGljYXRpb25JZCI6ImRldl9oSzdNMkhXUiIsImlwIjoiMTMuMjMyLjY0LjE0MSIsInNjb3BlIjoicHJvZmlsZS5yZWFkLG9yZGVycy5yZWFkLG9yZGVycy53cml0ZSxob2xkaW5ncy5yZWFkLHBvc2l0aW9ucy5yZWFkLHBvc2l0aW9ucy53cml0ZSxmdW5kcy5yZWFkLHRyYWRlcy5yZWFkLG1hcmdpbnMucmVhZCxkYXRhLnJlYWQiLCJjbGllbnRfY29kZSI6IjYwMFMxODcxIiwic291cmNlIjoiYXBpX2F1dGgiLCJwb2EiOnRydWV9.w4Lzj3Gu1tyeVjrWBMODMuUz3sHBLHRtEogTPImoT5uF_C7og4pvolddaET3AkqrJ_Z6fSI9fy-czWyUxHRuzsi0OijLatbdJidWzX48HqMrropBj5ggAq7Uhkqpo7qcqympmDI9ej8p3f91bZCWIevgnEGFJI9zNIu_NnIIqTU94q0kM5xiks5HNwrE4abS6jlTJ_OpuKsXgRhIqCtdgSl_QTcSaniZ0HHsYoxwJFhO2Mr-lcD22lP8BArNGpp765r36lkN1FhDvYwt2j-tRLOjWkUe-RyoFPBWh-whQ-BiE1aN0f53FwMI_TL2nf3pgM5M_CvOdF3_SEi4CuNfgAbhStirTq-E2MTLzrxOD3p5dMhms9dOlWmwK8uLV7xA2puMETUPY0_gyKAjQv9LX-29vFO6rKJzbJDMVJsD_QXQYDfJ1j35G_dPoWKRTjObWxcWOOdCBPXtcxj1N-oYO-2-ZFyGtEm-7c-HMnQ89fS4Td0brWMD8qSLIlV7nAlZ") - + client.Login(ctx, "clientCode", "password", "totp") // Access token is automatically set upon successful login call - // client.Orders(ctx) //orders need an offset and limit - // client.Positions(ctx) //positions need an offset and limit - - // client.PlaceOrder(ctx, govortex.PlaceOrderRequest{ - // Exchange: govortex.ExchangeTypesNSEEQUITY, - // Token: 22, - // TransactionType: govortex.TransactionTypesBUY, - // Product: govortex.ProductTypesDelivery, - // Variety: govortex.VarietyTypesRegularMarketOrder, - // Quantity: 1, - // Price: 1800, - // TriggerPrice: 0, - // DisclosedQuantity: 0, - // Validity: govortex.ValidityTypesFullDay, - // ValidityDays: 1, - // IsAMO: false, - // }) - // client.Funds(ctx) - - aa, _ := client.Tags(ctx) - bb, _ := json.Marshal(aa) - fmt.Println(string(bb)) + client.Orders(ctx) //orders need an offset and limit + client.Positions(ctx) //positions need an offset and limit + + client.PlaceOrder(ctx, govortex.PlaceOrderRequest{ + Exchange: govortex.ExchangeTypesNSEEQUITY, + Token: 22, + TransactionType: govortex.TransactionTypesBUY, + Product: govortex.ProductTypesDelivery, + Variety: govortex.VarietyTypesRegularMarketOrder, + Quantity: 1, + Price: 1800, + TriggerPrice: 0, + DisclosedQuantity: 0, + Validity: govortex.ValidityTypesFullDay, + ValidityDays: 1, + IsAMO: false, + }) + + client.Funds(ctx) } From a672aaefc2fd64da13e707c9bd020bcf741c1f12 Mon Sep 17 00:00:00 2001 From: shauryam Date: Wed, 7 Feb 2024 11:10:04 +0530 Subject: [PATCH 05/12] module new version --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 47eb8f7..9b002eb 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/AsthaTech/govortex +module github.com/AsthaTech/govortex/v2 go 1.16 From 8008e00da73648670170841ad0e754e7aa32689d Mon Sep 17 00:00:00 2001 From: shauryam Date: Wed, 7 Feb 2024 11:18:48 +0530 Subject: [PATCH 06/12] documentation fix --- examples/api/api.go | 2 +- examples/wire/wire.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/api/api.go b/examples/api/api.go index c3c08bc..5169f74 100644 --- a/examples/api/api.go +++ b/examples/api/api.go @@ -3,7 +3,7 @@ package main import ( "context" - govortex "github.com/AsthaTech/govortex" + govortex "github.com/AsthaTech/govortex/v2" ) const ( diff --git a/examples/wire/wire.go b/examples/wire/wire.go index 1e0a8eb..fc30c72 100644 --- a/examples/wire/wire.go +++ b/examples/wire/wire.go @@ -6,7 +6,7 @@ import ( "fmt" "time" - "github.com/AsthaTech/govortex" + "github.com/AsthaTech/govortex/v2" ) var wire *govortex.Wire From a9e0222904193e063d451ee8dd902a18960c7cf4 Mon Sep 17 00:00:00 2001 From: shauryam Date: Wed, 7 Feb 2024 11:19:54 +0530 Subject: [PATCH 07/12] documentation fix --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9dc6dd6..a19ad82 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ package main import ( "context" - govortex "github.com/AsthaTech/govortex" + govortex "github.com/AsthaTech/govortex/v2" ) const ( @@ -75,7 +75,7 @@ import ( "fmt" "time" - "github.com/AsthaTech/govortex" + "github.com/AsthaTech/govortex/v2" ) var wire *govortex.Wire From 311ff975f34787350074ddb99547b4a5b89f6dc4 Mon Sep 17 00:00:00 2001 From: shauryam Date: Fri, 9 Feb 2024 09:32:24 +0530 Subject: [PATCH 08/12] adds methods for exchanging auth token and logging out --- client.go | 1 + login.go | 33 +++++++++++++++++++++++++++++++++ requests.go | 6 ++++++ 3 files changed, 40 insertions(+) diff --git a/client.go b/client.go index 48c2cd6..72550d9 100644 --- a/client.go +++ b/client.go @@ -20,6 +20,7 @@ const ( // Constants for the API endpoints const ( URILogin string = "/user/login" + URISession string = "/user/session" URIInstruments string = "/data/instruments" URIPlaceOrder string = "/trading/orders/%s" //"/trading/orders/regular" URIModifyOrder string = "/trading/orders/%s/%s" //"/trading/orders/{{order_type}}/{order_id}" diff --git a/login.go b/login.go index da2cf52..f0870a3 100644 --- a/login.go +++ b/login.go @@ -2,6 +2,8 @@ package govortex import ( "context" + "crypto/sha256" + "fmt" "net/http" ) @@ -28,3 +30,34 @@ func (v *VortexApi) Login(ctx context.Context, clientCode string, password strin v.AccessToken = resp.Data.AccessToken return &resp, nil } + +func (v *VortexApi) ExchangeToken(ctx context.Context, auth_token string) (*LoginResponse, error) { + request := ExchangeAuthTokenRequest{ + Token: auth_token, + ApplicationId: v.applicationId, + Checksum: getSha256(v.applicationId + auth_token + v.apiKey), + } + var resp LoginResponse + header := http.Header{} + _, err := v.doJson(ctx, "POST", URISession, request, nil, header, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} + +func getSha256(s string) string { + h := sha256.New() + h.Write([]byte(s)) + bs := h.Sum(nil) + return fmt.Sprintf("%x", bs) +} + +func (v *VortexApi) Logout(ctx context.Context) (*map[string]interface{}, error) { + var resp map[string]interface{} + _, err := v.doJson(ctx, "POST", URISession, nil, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/requests.go b/requests.go index 1f6703a..f91613a 100644 --- a/requests.go +++ b/requests.go @@ -204,3 +204,9 @@ type PayoffOption struct { Quantity int `json:"quantity"` // Required: Quantity of the option. Ltp float64 `json:"last_trade_price"` // Optional: Last traded price for the option. } + +type ExchangeAuthTokenRequest struct { + Checksum string `json:"checksum"` + ApplicationId string `json:"applicationId"` + Token string `json:"token"` +} From 2f48ab1e81b6dba0c6702a732bc64b287a233175 Mon Sep 17 00:00:00 2001 From: shauryam Date: Fri, 9 Feb 2024 15:06:44 +0530 Subject: [PATCH 09/12] adds multi cancel --- client.go | 17 +++++++++-------- client_test.go | 1 + models.go | 5 +++++ orders.go | 9 +++++++++ orders_test.go | 14 ++++++++++++++ requests.go | 4 ++++ vortex-mocks | 2 +- 7 files changed, 43 insertions(+), 9 deletions(-) diff --git a/client.go b/client.go index 72550d9..7bee92c 100644 --- a/client.go +++ b/client.go @@ -22,14 +22,15 @@ const ( URILogin string = "/user/login" URISession string = "/user/session" URIInstruments string = "/data/instruments" - URIPlaceOrder string = "/trading/orders/%s" //"/trading/orders/regular" - URIModifyOrder string = "/trading/orders/%s/%s" //"/trading/orders/{{order_type}}/{order_id}" - URIModifyOrderTags string = "/trading/orders/%s/%s/tags" //"/trading/orders/{{order_type}}/{order_id}/tags" - URIDeleteOrder string = "/trading/orders/%s/%s" //"/orders/{{order_type}}/{order_id}" - URIDeleteMultipleOrder string = "/trading/orders/%s/multi_delete" //"/orders/{{order_type}}/{order_id}" - URIGttOrderBook string = "/trading/orders/gtt" //"/orders/gtt" - URIOrderBook string = "/trading/orders" //"/orders" - URIOrderHistory string = "/trading/orders/%s" //"/orders/{order_id}" + URIPlaceOrder string = "/trading/orders/%s" //"/trading/orders/regular" + URIModifyOrder string = "/trading/orders/%s/%s" //"/trading/orders/{{order_type}}/{order_id}" + URIModifyOrderTags string = "/trading/orders/%s/%s/tags" //"/trading/orders/{{order_type}}/{order_id}/tags" + URIDeleteOrder string = "/trading/orders/%s/%s" //"/trading/orders/{{order_type}}/{order_id}" + URIDeleteMultipleOrder string = "/trading/orders/%s/multi_delete" //"/trading/orders/{{order_type}}/{order_id}" + URIGttOrderBook string = "/trading/orders/gtt" //"/trading/orders/gtt" + URIOrderBook string = "/trading/orders" //"/trading/orders" + URIMultiCancelrders string = "/trading/orders/regular/multi_delete" //"/trading/orders/regular/multi_delete" + URIOrderHistory string = "/trading/orders/%s" //"/trading/orders/{order_id}" URITrades string = "/trading/trades" URIPositions string = "/trading/portfolio/positions" diff --git a/client_test.go b/client_test.go index ce74489..aec1854 100644 --- a/client_test.go +++ b/client_test.go @@ -58,6 +58,7 @@ var MockResponders = [][]interface{}{ {http.MethodPost, URIOptionChain, url.Values{}, "strategies/option_chain.json"}, {http.MethodPost, URIBuildStrategies, url.Values{}, "strategies/build_strategy.json"}, {http.MethodPost, URIPayoffStrategies, url.Values{}, "strategies/payoff.json"}, + {http.MethodPost, URIMultiCancelrders, url.Values{}, "regular_orders/multi_cancel.json"}, // PUT REQUESTS {http.MethodPut, fmt.Sprintf(URIModifyOrder, "regular", "NXAAE00002K3"), url.Values{}, "regular_orders/order.json"}, diff --git a/models.go b/models.go index ea0de73..b483ee0 100644 --- a/models.go +++ b/models.go @@ -712,3 +712,8 @@ type PayOff struct { EPayoff float64 `json:"expiry_pay_off"` At float64 `json:"at"` } + +type MultipleOrderResponse struct { + Status string `json:"status"` + Data []OrderResponse `json:"data"` +} diff --git a/orders.go b/orders.go index c8414b7..61c7f1f 100644 --- a/orders.go +++ b/orders.go @@ -85,3 +85,12 @@ func (v *VortexApi) OrderHistory(ctx context.Context, orderId string) (*OrderHis } return &resp, nil } + +func (v *VortexApi) CancelMultipleRegularOrders(ctx context.Context, req MultipleOrderCancelRequest) (*MultipleOrderResponse, error) { + var resp MultipleOrderResponse + _, err := v.doJson(ctx, "POST", URIMultiCancelrders, req, nil, nil, &resp) + if err != nil { + return nil, err + } + return &resp, nil +} diff --git a/orders_test.go b/orders_test.go index becc1da..da8c2e9 100644 --- a/orders_test.go +++ b/orders_test.go @@ -71,3 +71,17 @@ func (ts *TestSuite) TestOrderHistory(t *testing.T) { t.Errorf("Error while fetching order history. %s", "order history is empty") } } + +func (ts *TestSuite) TestMultipleOrderCancel(t *testing.T) { + t.Parallel() + ctx := context.Background() + request := MultipleOrderCancelRequest{} + resp, err := ts.VortexApiClient.CancelMultipleRegularOrders(ctx, request) + if err != nil { + t.Errorf("Error while cancelling order: %v", err.Error()) + return + } + if len(resp.Data) == 0 { + t.Errorf("Error while cancelling order: %s", "order history is empty") + } +} diff --git a/requests.go b/requests.go index f91613a..de30bfe 100644 --- a/requests.go +++ b/requests.go @@ -210,3 +210,7 @@ type ExchangeAuthTokenRequest struct { ApplicationId string `json:"applicationId"` Token string `json:"token"` } + +type MultipleOrderCancelRequest struct { + OrderIds []string `json:"order_ids"` +} diff --git a/vortex-mocks b/vortex-mocks index de38f69..0a1f159 160000 --- a/vortex-mocks +++ b/vortex-mocks @@ -1 +1 @@ -Subproject commit de38f6999c0cd211065d242c253594e2ed0fa0cc +Subproject commit 0a1f159b65575e5002c32659c9b9e8266bfcc499 From 4bfb60538f830717aea1a35d6e0459acc0c82f64 Mon Sep 17 00:00:00 2001 From: shauryam Date: Thu, 15 Feb 2024 20:57:00 +0530 Subject: [PATCH 10/12] encodes order ids --- orders.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/orders.go b/orders.go index 61c7f1f..8de70c2 100644 --- a/orders.go +++ b/orders.go @@ -3,6 +3,7 @@ package govortex import ( "context" "fmt" + "net/url" ) // PlaceOrder places an order with the Vortex API. @@ -45,7 +46,8 @@ func (v *VortexApi) ModifyOrder(ctx context.Context, request ModifyOrderRequest, request.ValidityDays = 1 } var resp OrderResponse - _, err := v.doJson(ctx, "PUT", fmt.Sprintf(URIModifyOrder, "regular", orderID), request, nil, nil, &resp) + encodedOrderId := url.QueryEscape(orderID) + _, err := v.doJson(ctx, "PUT", fmt.Sprintf(URIModifyOrder, "regular", encodedOrderId), request, nil, nil, &resp) if err != nil { return nil, err } @@ -57,7 +59,8 @@ func (v *VortexApi) ModifyOrder(ctx context.Context, request ModifyOrderRequest, // It returns an OrderResponse and an error. func (v *VortexApi) CancelOrder(ctx context.Context, orderID string) (*OrderResponse, error) { var resp OrderResponse - _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URIDeleteOrder, "regular", orderID), nil, nil, nil, &resp) + encodedOrderId := url.QueryEscape(orderID) + _, err := v.doJson(ctx, "DELETE", fmt.Sprintf(URIDeleteOrder, "regular", encodedOrderId), nil, nil, nil, &resp) if err != nil { return nil, err } @@ -79,7 +82,8 @@ func (v *VortexApi) Orders(ctx context.Context) (*OrderBookResponse, error) { func (v *VortexApi) OrderHistory(ctx context.Context, orderId string) (*OrderHistoryResponse, error) { var resp OrderHistoryResponse - _, err := v.doJson(ctx, "GET", fmt.Sprintf(URIOrderHistory, orderId), nil, nil, nil, &resp) + encodedOrderId := url.QueryEscape(orderId) + _, err := v.doJson(ctx, "GET", fmt.Sprintf(URIOrderHistory, encodedOrderId), nil, nil, nil, &resp) if err != nil { return nil, err } From a1acde1c83e912a7223de9b9a7569e3073b14ff5 Mon Sep 17 00:00:00 2001 From: shauryam Date: Mon, 19 Feb 2024 17:41:22 +0530 Subject: [PATCH 11/12] wire changes --- models.go | 11 +++++ wire.go | 125 +++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 96 insertions(+), 40 deletions(-) diff --git a/models.go b/models.go index b483ee0..6b7c5c9 100644 --- a/models.go +++ b/models.go @@ -212,6 +212,17 @@ const ( ExchangeTypesMCX ExchangeTypes = "MCX_FO" ) +type OrderStatus string + +const ( + OrderStatusPending OrderStatus = "PENDING" + OrderStausMiddlewarePending OrderStatus = "middleware_pending" + OrderStatusMiddlewareRejected OrderStatus = "middleware_rejected" + OrderStatusRejected OrderStatus = "REJECTED" + OrderStatusCancelled OrderStatus = "CANCELLED" + OrderStatusCompleted OrderStatus = "COMPLETED" +) + type TransactionTypes string const ( diff --git a/wire.go b/wire.go index 620c9b5..38eff0d 100644 --- a/wire.go +++ b/wire.go @@ -14,51 +14,96 @@ import ( "sync" "time" + "github.com/gofrs/uuid" + "github.com/lib/pq" "nhooyr.io/websocket" ) type SocketMessage struct { - Type string `json:"type"` - Data SocketMessageData `json:"data"` + Type string `json:"type"` + Data *SocketMessageData `json:"data,omitempty"` + AlertInfo *AlertInfo `json:"alert_info,omitempty"` + Gtt *GttInfo `json:"gtt,omitempty"` + ClientCode string `json:"client_code,omitempty"` +} +type AlertInfo struct { + Name string `json:"name"` + ClientCode string `json:"client_code"` + Token int `json:"token"` + MarketSegmentId MarketSegmentId `json:"market_segment_id"` + TriggerValue float64 `json:"trigger_value"` + Property AlertProperty `json:"property"` + Condition AlertCondition `json:"condition"` + Status string `json:"status" ` + Note string `json:"note"` + Expiry time.Time `json:"expiry"` + LastExecutedAt time.Time `json:"last_executed_at"` + IsExecuted *bool `json:"is_executed"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +type GttInfo struct { + Id uuid.UUID `json:"id"` + MarketSegmentId MarketSegmentId `json:"market_segment_id"` + Token int `json:"token"` + Exchange ExchangeTypes `json:"exchange"` + Symbol string `json:"symbol"` + InstrumentName string `json:"instrument_name"` + ExpiryDate string `json:"expiry_date"` + OptionType OptionType `json:"option_type"` + LotSize int `json:"lot_size"` + TriggerType GttTriggerType `json:"trigger_type"` + TransactionType TransactionTypes `json:"transaction_type"` + TagIds pq.Int32Array `json:"tag_ids"` + OrderIdentifier string `json:"order_identifier"` + Orders []GttInfoOrder `json:"orders"` } + type SocketMessageData struct { - OrderId string `json:"order_id"` - OrderNumber string `json:"order_number"` - AmoOrderId string `json:"amo_order_id"` - PlacedBy string `json:"placed_by"` - ModifiedBy string `json:"modified_by"` - Status string `json:"status"` - StatusMessage string `json:"status_message"` - Symbol string `json:"symbol"` - Series string `json:"series"` - InstrumentName string `json:"instrument_name"` - Token int `json:"token"` - Exchange string `json:"exchange"` - ExpiryDate string `json:"expiry_date"` - StrikePrice float32 `json:"strike_price"` - OptionType string `json:"option_type"` - TransactionType string `json:"transaction_type"` - Validity string `json:"validity"` - ValidityDays int `json:"validity_days"` - Product string `json:"product"` - Variety string `json:"variety"` - DisclosedQuantity int `json:"disclosed_quantity"` - DisclosedQuantityRemaining int `json:"disclosed_quantity_remaining"` - TotalQuantity int `json:"total_quantity"` - PendingQuantity int `json:"pending_quantity"` - TradedQuantity int `json:"traded_quantity"` - MarketType string `json:"market_type"` - OrderPrice float32 `json:"order_price"` - TriggerPrice float32 `json:"trigger_price"` - TradedPrice float32 `json:"traded_price"` - IsAmo bool `json:"is_amo"` - OrderIdentifier string `json:"order_identifier"` - OrderCreatedAt string `json:"order_created_at"` - OrderUpdatedAt string `json:"order_updated_at"` - TradeNumber string `json:"trade_number,omitempty"` - TradeTime string `json:"trade_time,omitempty"` - MarketSegmentId int `json:"market_segment_id"` - GtdOrderStatus string `json:"gtd_order_status"` + OrderId string `json:"order_id"` + MiddlewareOrderId uint `json:"middleware_order_id"` + TriggersGtt bool `json:"triggers_gtt"` + OrderNumber string `json:"order_number"` + AmoOrderId string `json:"amo_order_id"` + PlacedBy string `json:"placed_by"` + ModifiedBy string `json:"modified_by"` + Status OrderStatus `json:"status"` + StatusMessage string `json:"status_message"` + Symbol string `json:"symbol"` + Series string `json:"series"` + InstrumentName string `json:"instrument_name"` + Token int `json:"token"` + Exchange ExchangeTypes `json:"exchange"` + ExpiryDate string `json:"expiry_date"` + StrikePrice float32 `json:"strike_price"` + OptionType string `json:"option_type"` + TransactionType TransactionTypes `json:"transaction_type"` + Validity ValidityTypes `json:"validity"` + ValidityDays int `json:"validity_days"` + Product ProductTypes `json:"product"` //Intraday, Delivery or MTF + Variety VarietyTypes `json:"variety"` //regular , SL , SL-MKT,amo etc + DisclosedQuantity int `json:"disclosed_quantity"` + DisclosedQuantityRemaining int `json:"disclosed_quantity_remaining"` + TotalQuantity int `json:"total_quantity"` + PendingQuantity int `json:"pending_quantity"` + TradedQuantity int `json:"traded_quantity"` + ThisTradeQuantity int `json:"this_trade_quantity,omitempty"` + MarketType string `json:"market_type"` + OrderPrice float32 `json:"order_price"` + TriggerPrice float32 `json:"trigger_price"` + CoverTriggerPrice float32 `json:"cover_trigger_price"` + TradedPrice float32 `json:"traded_price"` + IsAmo bool `json:"is_amo"` + OrderIdentifier string `json:"order_identifier"` + InternalRemarks string `json:"internal_remarks"` + OrderCreatedAt string `json:"order_created_at"` + OrderUpdatedAt string `json:"order_updated_at"` + TradeNumber string `json:"trade_number,omitempty"` + TradeTime string `json:"trade_time,omitempty"` + MarketSegmentId int `json:"market_segment_id"` + GtdOrderStatus OrderStatus `json:"gtd_order_status"` + SequenceNumber int `json:"sequence_number"` } type packet struct { @@ -211,7 +256,7 @@ var ( websocketUrl = url.URL{Scheme: "wss", Host: "wire.asthatrade.com", Path: "ws"} ) -//Default method to create a new instance of Wire which can be used to get price updates and order updates +// Default method to create a new instance of Wire which can be used to get price updates and order updates func InitializeWire(accessToken string, wire *Wire) error { wire.accessToken = accessToken wire.url = websocketUrl From 3ed3f416a20d84465a38c7c40dc9d6eec1d6f46b Mon Sep 17 00:00:00 2001 From: shauryam Date: Mon, 19 Feb 2024 17:47:25 +0530 Subject: [PATCH 12/12] wire changes --- wire.go | 61 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/wire.go b/wire.go index 38eff0d..ccaa192 100644 --- a/wire.go +++ b/wire.go @@ -14,7 +14,6 @@ import ( "sync" "time" - "github.com/gofrs/uuid" "github.com/lib/pq" "nhooyr.io/websocket" ) @@ -26,29 +25,43 @@ type SocketMessage struct { Gtt *GttInfo `json:"gtt,omitempty"` ClientCode string `json:"client_code,omitempty"` } +type AlertProperty string type AlertInfo struct { - Name string `json:"name"` - ClientCode string `json:"client_code"` - Token int `json:"token"` - MarketSegmentId MarketSegmentId `json:"market_segment_id"` - TriggerValue float64 `json:"trigger_value"` - Property AlertProperty `json:"property"` - Condition AlertCondition `json:"condition"` - Status string `json:"status" ` - Note string `json:"note"` - Expiry time.Time `json:"expiry"` - LastExecutedAt time.Time `json:"last_executed_at"` - IsExecuted *bool `json:"is_executed"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` -} + Name string `json:"name"` + ClientCode string `json:"client_code"` + Token int `json:"token"` + Exchange ExchangeTypes `json:"exchange"` + TriggerValue float64 `json:"trigger_value"` + Property AlertProperty `json:"property"` + Condition AlertCondition `json:"condition"` + Status string `json:"status" ` + Note string `json:"note"` + Expiry time.Time `json:"expiry"` + LastExecutedAt time.Time `json:"last_executed_at"` + IsExecuted *bool `json:"is_executed"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} +type AlertCondition string + +const ( + AlertConditionLE AlertCondition = "LE" + AlertConditionGE AlertCondition = "GE" + AlertConditionEQ AlertCondition = "EQ" +) + +const ( + AlertPropertyLTP AlertProperty = "LTP" + AlertPropertyVOLUME AlertProperty = "VOLUME" + AlertPropertyAVGPRICE AlertProperty = "AVGPRICE" +) type GttInfo struct { - Id uuid.UUID `json:"id"` - MarketSegmentId MarketSegmentId `json:"market_segment_id"` + Id string `json:"id"` Token int `json:"token"` Exchange ExchangeTypes `json:"exchange"` Symbol string `json:"symbol"` + StrikePrice float64 `json:"strike_price"` InstrumentName string `json:"instrument_name"` ExpiryDate string `json:"expiry_date"` OptionType OptionType `json:"option_type"` @@ -59,6 +72,18 @@ type GttInfo struct { OrderIdentifier string `json:"order_identifier"` Orders []GttInfoOrder `json:"orders"` } +type GttInfoOrder struct { + Id uint `json:"id"` + Product ProductTypes `json:"product"` + Variety VarietyTypes `json:"variety"` + Price *float64 `json:"price"` + TriggerPrice *float64 `json:"trigger_price"` + Quantity int `json:"quantity"` + Status GttOrderStatus `json:"status"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + TrigerredAt time.Time `json:"trigerred_at"` +} type SocketMessageData struct { OrderId string `json:"order_id"`