github.com/polygon-io/client-go@v1.16.4/rest/aggs_test.go (about)

     1  package polygon_test
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"net/http"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/jarcoal/httpmock"
    12  	polygon "github.com/polygon-io/client-go/rest"
    13  	"github.com/polygon-io/client-go/rest/models"
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  const (
    18  	expectedAggsResponseURL = "https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/day/1626912000000/1629590400000?adjusted=true&limit=2&sort=desc"
    19  
    20  	agg1 = `{
    21  	"v": 135647456,
    22  	"vw": 74.6099,
    23  	"o": 74.06,
    24  	"c": 75.0875,
    25  	"h": 75.15,
    26  	"l": 73.7975,
    27  	"t": 1577941200000,
    28  	"n": 1
    29  }`
    30  
    31  	agg2 = `{
    32  	"v": 146535512,
    33  	"vw": 74.7026,
    34  	"o": 74.2875,
    35  	"c": 74.3575,
    36  	"h": 75.145,
    37  	"l": 74.125,
    38  	"t": 1578027600000,
    39  	"n": 1
    40  }`
    41  )
    42  
    43  var (
    44  	expectedAggsResponse = `{
    45  	"status": "OK",
    46  	"request_id": "6a7e466379af0a71039d60cc78e72282",
    47  	"next_url": "https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/day/1626912000000/1629590400000?cursor=AGGSCURSOR",
    48  	"ticker": "AAPL",
    49  	"queryCount": 2,
    50  	"resultsCount": 2,
    51  	"adjusted": true,
    52  	"results": [
    53  ` + indent(true, agg1, "\t\t") + `,
    54  ` + indent(true, agg2, "\t\t") + `
    55  	]
    56  }`
    57  )
    58  
    59  func TestListAggs(t *testing.T) {
    60  	c := polygon.New("API_KEY")
    61  
    62  	httpmock.ActivateNonDefault(c.HTTP.GetClient())
    63  	defer httpmock.DeactivateAndReset()
    64  	registerResponder(expectedAggsResponseURL, expectedAggsResponse)
    65  	registerResponder("https://api.polygon.io/v2/aggs/ticker/AAPL/range/1/day/1626912000000/1629590400000?cursor=AGGSCURSOR", "{}")
    66  
    67  	iter := c.ListAggs(context.Background(), models.ListAggsParams{
    68  		Ticker:     "AAPL",
    69  		Multiplier: 1,
    70  		Timespan:   "day",
    71  		From:       models.Millis(time.Date(2021, 7, 22, 0, 0, 0, 0, time.UTC)),
    72  		To:         models.Millis(time.Date(2021, 8, 22, 0, 0, 0, 0, time.UTC)),
    73  	}.WithOrder(models.Desc).WithLimit(2).WithAdjusted(true))
    74  
    75  	// iter creation
    76  	assert.Nil(t, iter.Err())
    77  	assert.NotNil(t, iter.Item())
    78  
    79  	// first item
    80  	assert.True(t, iter.Next())
    81  	assert.Nil(t, iter.Err())
    82  	var expect1 models.Agg
    83  	err := json.Unmarshal([]byte(agg1), &expect1)
    84  	assert.Nil(t, err)
    85  	assert.Equal(t, expect1, iter.Item())
    86  
    87  	// second item
    88  	assert.True(t, iter.Next())
    89  	assert.Nil(t, iter.Err())
    90  	var expect2 models.Agg
    91  	err = json.Unmarshal([]byte(agg2), &expect2)
    92  	assert.Nil(t, err)
    93  	assert.Equal(t, expect2, iter.Item())
    94  
    95  	// end of list
    96  	assert.False(t, iter.Next())
    97  	assert.Nil(t, iter.Err())
    98  }
    99  
   100  func TestGetAggs(t *testing.T) {
   101  	c := polygon.New("API_KEY")
   102  
   103  	httpmock.ActivateNonDefault(c.HTTP.GetClient())
   104  	defer httpmock.DeactivateAndReset()
   105  	registerResponder(expectedAggsResponseURL, expectedAggsResponse)
   106  
   107  	res, err := c.GetAggs(context.Background(), models.GetAggsParams{
   108  		Ticker:     "AAPL",
   109  		Multiplier: 1,
   110  		Timespan:   "day",
   111  		From:       models.Millis(time.Date(2021, 7, 22, 0, 0, 0, 0, time.UTC)),
   112  		To:         models.Millis(time.Date(2021, 8, 22, 0, 0, 0, 0, time.UTC)),
   113  	}.WithOrder(models.Desc).WithLimit(2).WithAdjusted(true))
   114  	assert.Nil(t, err)
   115  
   116  	var expect models.GetAggsResponse
   117  	err = json.Unmarshal([]byte(expectedAggsResponse), &expect)
   118  	assert.Nil(t, err)
   119  	assert.Equal(t, &expect, res)
   120  }
   121  
   122  func TestGetAggsWithQueryParam(t *testing.T) {
   123  	c := polygon.New("API_KEY")
   124  
   125  	httpmock.ActivateNonDefault(c.HTTP.GetClient())
   126  	defer httpmock.DeactivateAndReset()
   127  	registerResponder(expectedAggsResponseURL, expectedAggsResponse)
   128  
   129  	res, err := c.GetAggs(context.Background(), models.GetAggsParams{
   130  		Ticker:     "AAPL",
   131  		Multiplier: 1,
   132  		Timespan:   "day",
   133  		From:       models.Millis(time.Date(2021, 7, 22, 0, 0, 0, 0, time.UTC)),
   134  		To:         models.Millis(time.Date(2021, 8, 22, 0, 0, 0, 0, time.UTC)),
   135  	}.WithOrder(models.Desc).WithLimit(2), models.QueryParam("adjusted", "true"))
   136  	assert.Nil(t, err)
   137  
   138  	var expect models.GetAggsResponse
   139  	err = json.Unmarshal([]byte(expectedAggsResponse), &expect)
   140  	assert.Nil(t, err)
   141  	assert.Equal(t, &expect, res)
   142  }
   143  
   144  func TestGetGroupedDailyAggs(t *testing.T) {
   145  	c := polygon.New("API_KEY")
   146  
   147  	httpmock.ActivateNonDefault(c.HTTP.GetClient())
   148  	defer httpmock.DeactivateAndReset()
   149  
   150  	expectedResponse := `{
   151  	"status": "OK",
   152  	"queryCount": 3,
   153  	"resultsCount": 3,
   154  	"adjusted": true,
   155  	"results": [
   156  		{
   157  			"T": "KIMpL",
   158  			"v": 4369,
   159  			"vw": 26.0407,
   160  			"o": 26.07,
   161  			"c": 25.9102,
   162  			"h": 26.25,
   163  			"l": 25.91,
   164  			"t": 1602705600000,
   165  			"n": 74
   166  		},
   167  		{
   168  			"T": "TANH",
   169  			"v": 25933.6,
   170  			"vw": 23.493,
   171  			"o": 24.5,
   172  			"c": 23.4,
   173  			"h": 24.763,
   174  			"l": 22.65,
   175  			"t": 1602705600000,
   176  			"n": 1096
   177  		},
   178  		{
   179  			"T": "VSAT",
   180  			"v": 312583,
   181  			"vw": 34.4736,
   182  			"o": 34.9,
   183  			"c": 34.24,
   184  			"h": 35.47,
   185  			"l": 34.21,
   186  			"t": 1602705600000,
   187  			"n": 4966
   188  		}
   189  	]
   190  }`
   191  
   192  	registerResponder("https://api.polygon.io/v2/aggs/grouped/locale/us/market/stocks/2021-07-22", expectedResponse)
   193  	res, err := c.GetGroupedDailyAggs(context.Background(), models.GetGroupedDailyAggsParams{
   194  		Locale:     models.US,
   195  		MarketType: models.Stocks,
   196  		Date:       models.Date(time.Date(2021, 7, 22, 0, 0, 0, 0, time.Local)),
   197  	}.WithAdjusted(true))
   198  	assert.Nil(t, err)
   199  
   200  	var expect models.GetGroupedDailyAggsResponse
   201  	err = json.Unmarshal([]byte(expectedResponse), &expect)
   202  	assert.Nil(t, err)
   203  	assert.Equal(t, &expect, res)
   204  }
   205  
   206  func TestGetDailyOpenCloseAgg(t *testing.T) {
   207  	c := polygon.New("API_KEY")
   208  
   209  	httpmock.ActivateNonDefault(c.HTTP.GetClient())
   210  	defer httpmock.DeactivateAndReset()
   211  
   212  	expectedResponse := `{
   213  	"status": "OK",
   214  	"symbol": "AAPL",
   215  	"from": "2020-10-14T00:00:00.000Z",
   216  	"open": 324.66,
   217  	"high": 326.2,
   218  	"low": 322.3,
   219  	"close": 325.12,
   220  	"volume": 26122646,
   221  	"afterHours": 322.1,
   222  	"preMarket": 324.5
   223  }`
   224  
   225  	registerResponder("https://api.polygon.io/v1/open-close/AAPL/2020-10-14?adjusted=true", expectedResponse)
   226  	res, err := c.GetDailyOpenCloseAgg(context.Background(), models.GetDailyOpenCloseAggParams{
   227  		Ticker: "AAPL",
   228  		Date:   models.Date(time.Date(2020, 10, 14, 0, 0, 0, 0, time.Local)),
   229  	}.WithAdjusted(true))
   230  	assert.Nil(t, err)
   231  
   232  	var expect models.GetDailyOpenCloseAggResponse
   233  	err = json.Unmarshal([]byte(expectedResponse), &expect)
   234  	assert.Nil(t, err)
   235  	assert.Equal(t, &expect, res)
   236  }
   237  
   238  func TestGetPreviousCloseAgg(t *testing.T) {
   239  	c := polygon.New("API_KEY")
   240  
   241  	httpmock.ActivateNonDefault(c.HTTP.GetClient())
   242  	defer httpmock.DeactivateAndReset()
   243  
   244  	expectedResponse := `{
   245  	"status": "OK",
   246  	"request_id": "6a7e466379af0a71039d60cc78e72282",
   247  	"ticker": "AAPL",
   248  	"queryCount": 1,
   249  	"resultsCount": 1,
   250  	"adjusted": true,
   251  	"results": [
   252  		{
   253  			"T": "AAPL",
   254  			"v": 131704427,
   255  			"vw": 116.3058,
   256  			"o": 115.55,
   257  			"c": 115.97,
   258  			"h": 117.59,
   259  			"l": 114.13,
   260  			"t": 1605042000000
   261  		}
   262  	]
   263  }`
   264  
   265  	registerResponder("https://api.polygon.io/v2/aggs/ticker/AAPL/prev", expectedResponse)
   266  	res, err := c.GetPreviousCloseAgg(context.Background(), models.GetPreviousCloseAggParams{
   267  		Ticker: "AAPL",
   268  	}.WithAdjusted(true))
   269  	assert.Nil(t, err)
   270  
   271  	var expect models.GetPreviousCloseAggResponse
   272  	err = json.Unmarshal([]byte(expectedResponse), &expect)
   273  	assert.Nil(t, err)
   274  	assert.Equal(t, &expect, res)
   275  }
   276  
   277  func registerResponder(url, body string) {
   278  	httpmock.RegisterResponder("GET", url,
   279  		func(req *http.Request) (*http.Response, error) {
   280  			resp := httpmock.NewStringResponse(200, body)
   281  			resp.Header.Add("Content-Type", "application/json")
   282  			return resp, nil
   283  		},
   284  	)
   285  }
   286  
   287  func indent(first bool, data, indent string) string {
   288  	lines := strings.Split(data, "\n")
   289  	for i := range lines {
   290  		if i == 0 && !first {
   291  			continue
   292  		}
   293  		lines[i] = indent + lines[i]
   294  	}
   295  	return strings.Join(lines, "\n")
   296  }