From ab23fb7145b951cbdec66634d38c1aefa174e6aa Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 27 Oct 2023 16:48:15 -0400 Subject: [PATCH 01/12] Fix Alpaca tests and exports --- src/index.ts | 4 ++++ test/alpaca.test.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index c85fec1..91576fc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,3 +2,7 @@ export * from './interface/exchange'; export * from './interface/portfolio'; export * from './interface/quote'; export * from './interface/actions'; + +export * from './alpaca/exchange'; +export * from './alpaca/portfolio'; +export * from './alpaca/quote'; \ No newline at end of file diff --git a/test/alpaca.test.ts b/test/alpaca.test.ts index a96b15d..25611f5 100644 --- a/test/alpaca.test.ts +++ b/test/alpaca.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from '@jest/globals'; import 'dotenv/config'; -import { AlpacaExchange } from '../src/alpaca/exchange'; +import { AlpacaExchange } from '../src/index'; describe('Alpaca Tests', () => { test('portfolio fetch', () => { From 5f1cd195aff3a9a76d7f3527f9769cbf6dbee324 Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 27 Oct 2023 17:29:42 -0400 Subject: [PATCH 02/12] Begin implementing action fetching for Alpaca --- src/alpaca/actions.ts | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/alpaca/actions.ts diff --git a/src/alpaca/actions.ts b/src/alpaca/actions.ts new file mode 100644 index 0000000..bf9eb8c --- /dev/null +++ b/src/alpaca/actions.ts @@ -0,0 +1,50 @@ +import Alpaca from '@alpacahq/alpaca-trade-api'; +import { Action, ActionSide, ActionFetchOptions, ActionFetchResponse } from '../interface/actions'; + +class AlpacaActivity { + id!: string; + activity_type!: string; + transaction_time!: string; + type!: string; + price!: string; + qty!: string; + side!: string; + symbol!: string; + leaves_qty!: string; + order_id!: string; + cum_qty!: string; + order_status!: string; +} + +export class AlpacaActionProvider { + readonly alpaca: Alpaca; + + readonly fetchActions = (options: ActionFetchOptions): Promise => { + return (this.alpaca.getAccountActivities({ + activityTypes: "FILL", + until: undefined as any, + after: undefined as any, + direction: "desc", + date: undefined as any, + pageSize: undefined as any, + pageToken: undefined as any, + }) as Promise).then((activities) => { + return new ActionFetchResponse( + activities.map((activity) => { + return new Action( + activity.symbol, + parseInt(activity.qty, 10), + activity.side === "buy" ? ActionSide.Buy : ActionSide.Sell, + parseFloat(activity.price) + ); + }) + ); + }).catch((err) => { + return err; + }); + } + + constructor(alpaca: Alpaca) { + this.alpaca = alpaca; + } +} \ No newline at end of file From 8437515904a615cc8432b60077b08ad4baa51660 Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 27 Oct 2023 17:31:44 -0400 Subject: [PATCH 03/12] Make ActionFetchResponse a class with a constructor. --- src/interface/actions.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/interface/actions.ts b/src/interface/actions.ts index 2fdad9c..d072fd7 100644 --- a/src/interface/actions.ts +++ b/src/interface/actions.ts @@ -99,7 +99,7 @@ export class ActionFetchOptions { /** * Represents the response of a fetch action request. */ -export interface ActionFetchResponse { +export class ActionFetchResponse { /** * An array of `Action` objects. @@ -111,6 +111,17 @@ export interface ActionFetchResponse { * Returns a promise that resolves to an `ActionFetchResponse` object. */ readonly fetchNextPage?: () => Promise; + + /** + * Creates an instance of the Actions class. + * @constructor + * @param actions The list of actions. + * @param fetchNextPage A function that fetches the next page of actions. + */ + constructor(actions: Action[], fetchNextPage?: () => Promise) { + this.actions = actions; + this.fetchNextPage = fetchNextPage; + } } /** From 327ab308bf8db5a5afe68c76216d89c03ae41a14 Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 27 Oct 2023 17:41:57 -0400 Subject: [PATCH 04/12] Setup basic Alpaca action fetch and test. --- src/alpaca/actions.ts | 3 ++- src/alpaca/exchange.ts | 3 ++- test/alpaca.test.ts | 24 +++++++++++++++++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/alpaca/actions.ts b/src/alpaca/actions.ts index bf9eb8c..cbe8955 100644 --- a/src/alpaca/actions.ts +++ b/src/alpaca/actions.ts @@ -37,7 +37,8 @@ export class AlpacaActionProvider { activity.side === "buy" ? ActionSide.Buy : ActionSide.Sell, parseFloat(activity.price) ); - }) + }), + undefined ); }).catch((err) => { return err; diff --git a/src/alpaca/exchange.ts b/src/alpaca/exchange.ts index eceadd4..3ada9ee 100644 --- a/src/alpaca/exchange.ts +++ b/src/alpaca/exchange.ts @@ -1,6 +1,7 @@ import Alpaca from '@alpacahq/alpaca-trade-api'; import { AlpacaPortfolioProvider } from './portfolio'; import { AlpacaQuoteProvider } from './quote'; +import { AlpacaActionProvider } from './actions'; import { Exchange } from '../interface/exchange'; import { PortfolioProvider } from '../interface/portfolio'; import { QuoteProvider } from '../interface/quote'; @@ -51,7 +52,7 @@ export class AlpacaExchange implements Exchange { this.portfolioProvider = new AlpacaPortfolioProvider(this.alpaca); this.quoteProvider = new AlpacaQuoteProvider(this.alpaca); - this.actionProvider = null!; + this.actionProvider = new AlpacaActionProvider(this.alpaca); this.name = 'Alpaca'; } diff --git a/test/alpaca.test.ts b/test/alpaca.test.ts index 25611f5..7a98870 100644 --- a/test/alpaca.test.ts +++ b/test/alpaca.test.ts @@ -1,6 +1,21 @@ import { describe, expect, test } from '@jest/globals'; import 'dotenv/config'; -import { AlpacaExchange } from '../src/index'; +import { ActionFetchOptions, AlpacaExchange } from '../src/index'; +import { createLogger, transports, format } from "winston"; + +const logger = createLogger({ + transports: [new transports.Console()], + format: format.combine( + format.colorize(), + format.timestamp(), + format.printf(({ timestamp, level, message, service }) => { + return `[${timestamp}] ${service} ${level}: ${message}`; + }) + ), + defaultMeta: { + service: "AlpacaTest", + }, +}); describe('Alpaca Tests', () => { test('portfolio fetch', () => { @@ -16,4 +31,11 @@ describe('Alpaca Tests', () => { const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); expect(exchange.quoteProvider.fetchQuote("AAPL")).resolves.toBeDefined(); }); + + test('action fetch', async () => { + expect(process.env.ALPACA_API_KEY).toBeDefined(); + expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); + const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); + expect(exchange.actionProvider.fetchActions(new ActionFetchOptions)).resolves.toBeDefined(); + }); }); From 54a33419686033c4169a17730d8b1e62a9502ef3 Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 27 Oct 2023 17:44:57 -0400 Subject: [PATCH 05/12] Filter action fetch response to eliminate partial order fills. --- src/alpaca/actions.ts | 4 +++- test/alpaca.test.ts | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/alpaca/actions.ts b/src/alpaca/actions.ts index cbe8955..b0efe5d 100644 --- a/src/alpaca/actions.ts +++ b/src/alpaca/actions.ts @@ -30,7 +30,9 @@ export class AlpacaActionProvider { pageToken: undefined as any, }) as Promise).then((activities) => { return new ActionFetchResponse( - activities.map((activity) => { + activities + .filter((activity) => activity.order_status === "filled") + .map((activity) => { return new Action( activity.symbol, parseInt(activity.qty, 10), diff --git a/test/alpaca.test.ts b/test/alpaca.test.ts index 7a98870..4bfd690 100644 --- a/test/alpaca.test.ts +++ b/test/alpaca.test.ts @@ -36,6 +36,10 @@ describe('Alpaca Tests', () => { expect(process.env.ALPACA_API_KEY).toBeDefined(); expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); - expect(exchange.actionProvider.fetchActions(new ActionFetchOptions)).resolves.toBeDefined(); + + const actions = await exchange.actionProvider.fetchActions(new ActionFetchOptions); + logger.info(JSON.stringify(actions)); + + //expect(exchange.actionProvider.fetchActions(new ActionFetchOptions)).resolves.toBeDefined(); }); }); From 91134a42d539f5145899e3e48d37733a724373cd Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Tue, 31 Oct 2023 16:58:06 -0400 Subject: [PATCH 06/12] Fix timeout issues in Alpaca tests. --- src/alpaca/actions.ts | 11 +++-------- src/index.ts | 2 +- src/interface/actions.ts | 1 - test/alpaca.test.ts | 20 ++++++++------------ 4 files changed, 12 insertions(+), 22 deletions(-) diff --git a/src/alpaca/actions.ts b/src/alpaca/actions.ts index b0efe5d..e3d7375 100644 --- a/src/alpaca/actions.ts +++ b/src/alpaca/actions.ts @@ -18,16 +18,11 @@ class AlpacaActivity { export class AlpacaActionProvider { readonly alpaca: Alpaca; - + readonly fetchActions = (options: ActionFetchOptions): Promise => { return (this.alpaca.getAccountActivities({ activityTypes: "FILL", - until: undefined as any, - after: undefined as any, direction: "desc", - date: undefined as any, - pageSize: undefined as any, - pageToken: undefined as any, }) as Promise).then((activities) => { return new ActionFetchResponse( activities @@ -45,9 +40,9 @@ export class AlpacaActionProvider { }).catch((err) => { return err; }); - } + }; constructor(alpaca: Alpaca) { this.alpaca = alpaca; } -} \ No newline at end of file +} diff --git a/src/index.ts b/src/index.ts index 91576fc..099cffe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,4 +5,4 @@ export * from './interface/actions'; export * from './alpaca/exchange'; export * from './alpaca/portfolio'; -export * from './alpaca/quote'; \ No newline at end of file +export * from './alpaca/quote'; diff --git a/src/interface/actions.ts b/src/interface/actions.ts index d072fd7..31db230 100644 --- a/src/interface/actions.ts +++ b/src/interface/actions.ts @@ -100,7 +100,6 @@ export class ActionFetchOptions { * Represents the response of a fetch action request. */ export class ActionFetchResponse { - /** * An array of `Action` objects. */ diff --git a/test/alpaca.test.ts b/test/alpaca.test.ts index 4bfd690..1dbbb59 100644 --- a/test/alpaca.test.ts +++ b/test/alpaca.test.ts @@ -18,28 +18,24 @@ const logger = createLogger({ }); describe('Alpaca Tests', () => { - test('portfolio fetch', () => { + test('portfolio fetch', async () => { expect(process.env.ALPACA_API_KEY).toBeDefined(); expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); - expect(exchange.portfolioProvider.fetchPortfolio()).resolves.toBeDefined(); - }); + await expect(exchange.portfolioProvider.fetchPortfolio()).resolves.toBeDefined(); + }, 10000); - test('quote fetch', () => { + test('quote fetch', async () => { expect(process.env.ALPACA_API_KEY).toBeDefined(); expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); - expect(exchange.quoteProvider.fetchQuote("AAPL")).resolves.toBeDefined(); - }); + await expect(exchange.quoteProvider.fetchQuote("AAPL")).resolves.toBeDefined(); + }, 10000); test('action fetch', async () => { expect(process.env.ALPACA_API_KEY).toBeDefined(); expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); - - const actions = await exchange.actionProvider.fetchActions(new ActionFetchOptions); - logger.info(JSON.stringify(actions)); - - //expect(exchange.actionProvider.fetchActions(new ActionFetchOptions)).resolves.toBeDefined(); - }); + await expect(exchange.actionProvider.fetchActions(new ActionFetchOptions)).resolves.toBeDefined(); + }, 10000); }); From 158c92c4a55e33de1be10b97f9a9bc2a7f1da3dd Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Tue, 31 Oct 2023 17:12:24 -0400 Subject: [PATCH 07/12] Remove no-undefined linter setting. --- .eslintrc.js | 1 - src/alpaca/actions.ts | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.eslintrc.js b/.eslintrc.js index f8e2339..e4da6a6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -73,7 +73,6 @@ module.exports = { "@typescript-eslint/no-shadow": ["error"], "no-throw-literal": "error", "no-undef-init": "error", - "no-undefined": "error", "no-underscore-dangle": "error", "no-unneeded-ternary": "error", "no-unused-expressions": "error", diff --git a/src/alpaca/actions.ts b/src/alpaca/actions.ts index e3d7375..83fc753 100644 --- a/src/alpaca/actions.ts +++ b/src/alpaca/actions.ts @@ -22,7 +22,12 @@ export class AlpacaActionProvider { readonly fetchActions = (options: ActionFetchOptions): Promise => { return (this.alpaca.getAccountActivities({ activityTypes: "FILL", + until: undefined, + after: undefined, direction: "desc", + date: undefined, + pageSize: undefined, + pageToken: undefined, }) as Promise).then((activities) => { return new ActionFetchResponse( activities From 5b66bcd2c06f5374e80380eb78b055e53cd4d299 Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 3 Nov 2023 16:19:58 -0400 Subject: [PATCH 08/12] Add support for Alpaca action fetch options. --- src/alpaca/actions.ts | 10 +++++----- test/alpaca.test.ts | 15 +++++++++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/alpaca/actions.ts b/src/alpaca/actions.ts index 83fc753..43c3b13 100644 --- a/src/alpaca/actions.ts +++ b/src/alpaca/actions.ts @@ -1,5 +1,5 @@ import Alpaca from '@alpacahq/alpaca-trade-api'; -import { Action, ActionSide, ActionFetchOptions, ActionFetchResponse } from '../interface/actions'; +import { Action, ActionSide, ActionFetchOptions, ActionFetchResponse, ActionDateType } from '../interface/actions'; class AlpacaActivity { id!: string; @@ -22,11 +22,11 @@ export class AlpacaActionProvider { readonly fetchActions = (options: ActionFetchOptions): Promise => { return (this.alpaca.getAccountActivities({ activityTypes: "FILL", - until: undefined, - after: undefined, + until: options.dateOptions?.dateType === ActionDateType.Before ? options.dateOptions.date : undefined, + after: options.dateOptions?.dateType === ActionDateType.After ? options.dateOptions.date : undefined, direction: "desc", - date: undefined, - pageSize: undefined, + date: options.dateOptions?.dateType === ActionDateType.On ? options.dateOptions.date : undefined, + pageSize: options.pageSize, pageToken: undefined, }) as Promise).then((activities) => { return new ActionFetchResponse( diff --git a/test/alpaca.test.ts b/test/alpaca.test.ts index 1dbbb59..19304f8 100644 --- a/test/alpaca.test.ts +++ b/test/alpaca.test.ts @@ -3,6 +3,8 @@ import 'dotenv/config'; import { ActionFetchOptions, AlpacaExchange } from '../src/index'; import { createLogger, transports, format } from "winston"; +const timeout = 10000; + const logger = createLogger({ transports: [new transports.Console()], format: format.combine( @@ -23,19 +25,24 @@ describe('Alpaca Tests', () => { expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); await expect(exchange.portfolioProvider.fetchPortfolio()).resolves.toBeDefined(); - }, 10000); + }, timeout); test('quote fetch', async () => { expect(process.env.ALPACA_API_KEY).toBeDefined(); expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); await expect(exchange.quoteProvider.fetchQuote("AAPL")).resolves.toBeDefined(); - }, 10000); + }, timeout); test('action fetch', async () => { expect(process.env.ALPACA_API_KEY).toBeDefined(); expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); - await expect(exchange.actionProvider.fetchActions(new ActionFetchOptions)).resolves.toBeDefined(); - }, 10000); + + const response = await exchange.actionProvider.fetchActions(new ActionFetchOptions()); + + logger.info(JSON.stringify(response)); + + await expect(exchange.actionProvider.fetchActions(new ActionFetchOptions())).resolves.toBeDefined(); + }, timeout); }); From 27b49dc6dcdedce25debd07411da3b2d09136c62 Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 3 Nov 2023 16:23:33 -0400 Subject: [PATCH 09/12] Add timestamp to actions. --- src/alpaca/actions.ts | 3 ++- src/interface/actions.ts | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/alpaca/actions.ts b/src/alpaca/actions.ts index 43c3b13..64a601f 100644 --- a/src/alpaca/actions.ts +++ b/src/alpaca/actions.ts @@ -37,7 +37,8 @@ export class AlpacaActionProvider { activity.symbol, parseInt(activity.qty, 10), activity.side === "buy" ? ActionSide.Buy : ActionSide.Sell, - parseFloat(activity.price) + parseFloat(activity.price), + new Date(activity.transaction_time), ); }), undefined diff --git a/src/interface/actions.ts b/src/interface/actions.ts index 31db230..2c6d52a 100644 --- a/src/interface/actions.ts +++ b/src/interface/actions.ts @@ -30,6 +30,11 @@ export class Action { */ readonly pricePerShare: number; + /** + * The timestamp of the action + */ + readonly timestamp: Date; + /** * Represents a user Action. * @constructor @@ -37,12 +42,14 @@ export class Action { * @param {number} quantity - The quantity of the asset being traded. * @param {ActionSide} side - The side of the trade (buy or sell). * @param {number} pricePerShare - The price per share of the asset being traded. + * @param {Date} timestamp - The timestamp of the action. */ - constructor(symbol: string, quantity: number, side: ActionSide, pricePerShare: number) { + constructor(symbol: string, quantity: number, side: ActionSide, pricePerShare: number, timestamp: Date) { this.symbol = symbol; this.quantity = quantity; this.side = side; this.pricePerShare = pricePerShare; + this.timestamp = timestamp; } } From 34bcafb07fcc45c036693d194e793a300ed9c616 Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 3 Nov 2023 16:48:57 -0400 Subject: [PATCH 10/12] Add constructor for ActionFetchOptions. --- src/interface/actions.ts | 11 +++++++++++ test/alpaca.test.ts | 2 ++ 2 files changed, 13 insertions(+) diff --git a/src/interface/actions.ts b/src/interface/actions.ts index 2c6d52a..91ca388 100644 --- a/src/interface/actions.ts +++ b/src/interface/actions.ts @@ -101,6 +101,17 @@ export class ActionFetchOptions { * The date options for filtering actions. */ readonly dateOptions?: ActionDateOptions; + + /** + * Creates a set of options for an Action fetch. + * @constructor + * @param pageSize - The size of the page if paging is desired. + * @param dateOptions - The options for Date filtering. + */ + constructor(pageSize?: number, dateOptions?: ActionDateOptions) { + this.pageSize = pageSize; + this.dateOptions = dateOptions; + } } /** diff --git a/test/alpaca.test.ts b/test/alpaca.test.ts index 19304f8..ff06348 100644 --- a/test/alpaca.test.ts +++ b/test/alpaca.test.ts @@ -39,6 +39,8 @@ describe('Alpaca Tests', () => { expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); + const fetchOptions = {}; + const response = await exchange.actionProvider.fetchActions(new ActionFetchOptions()); logger.info(JSON.stringify(response)); From 960285e503423e3c5e89a24f8a064b750f171836 Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 3 Nov 2023 21:19:31 -0400 Subject: [PATCH 11/12] Update alpaca actions test to test date. --- test/alpaca.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/alpaca.test.ts b/test/alpaca.test.ts index ff06348..25689e1 100644 --- a/test/alpaca.test.ts +++ b/test/alpaca.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from '@jest/globals'; import 'dotenv/config'; -import { ActionFetchOptions, AlpacaExchange } from '../src/index'; +import { ActionDateOptions, ActionDateType, ActionFetchOptions, AlpacaExchange } from '../src/index'; import { createLogger, transports, format } from "winston"; const timeout = 10000; @@ -39,12 +39,12 @@ describe('Alpaca Tests', () => { expect(process.env.ALPACA_SECRET_KEY).toBeDefined(); const exchange = new AlpacaExchange(process.env.ALPACA_API_KEY!, process.env.ALPACA_SECRET_KEY!, true); - const fetchOptions = {}; + const fetchOptions = new ActionFetchOptions(undefined, new ActionDateOptions(new Date("2023-10-23T13:30:28.163Z"), ActionDateType.On)); - const response = await exchange.actionProvider.fetchActions(new ActionFetchOptions()); + const response = await exchange.actionProvider.fetchActions(fetchOptions); logger.info(JSON.stringify(response)); - await expect(exchange.actionProvider.fetchActions(new ActionFetchOptions())).resolves.toBeDefined(); + await expect(exchange.actionProvider.fetchActions(fetchOptions)).resolves.toBeDefined(); }, timeout); }); From ef1ee52a383f2a7fcccbf32027b5152760dc60da Mon Sep 17 00:00:00 2001 From: Carter Bertolini Date: Fri, 10 Nov 2023 16:32:44 -0500 Subject: [PATCH 12/12] Use an interface for AlpacaActivity and add date checks to tests. --- src/alpaca/actions.ts | 26 +++++++++++++------------- test/alpaca.test.ts | 15 ++++++++++++++- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/alpaca/actions.ts b/src/alpaca/actions.ts index 64a601f..471f6dc 100644 --- a/src/alpaca/actions.ts +++ b/src/alpaca/actions.ts @@ -1,19 +1,19 @@ import Alpaca from '@alpacahq/alpaca-trade-api'; import { Action, ActionSide, ActionFetchOptions, ActionFetchResponse, ActionDateType } from '../interface/actions'; -class AlpacaActivity { - id!: string; - activity_type!: string; - transaction_time!: string; - type!: string; - price!: string; - qty!: string; - side!: string; - symbol!: string; - leaves_qty!: string; - order_id!: string; - cum_qty!: string; - order_status!: string; +interface AlpacaActivity { + id: string; + activity_type: string; + transaction_time: string; + type: string; + price: string; + qty: string; + side: string; + symbol: string; + leaves_qty: string; + order_id: string; + cum_qty: string; + order_status: string; } export class AlpacaActionProvider { diff --git a/test/alpaca.test.ts b/test/alpaca.test.ts index 25689e1..9c23980 100644 --- a/test/alpaca.test.ts +++ b/test/alpaca.test.ts @@ -43,8 +43,21 @@ describe('Alpaca Tests', () => { const response = await exchange.actionProvider.fetchActions(fetchOptions); + expect(response).toBeDefined(); + logger.info(JSON.stringify(response)); - await expect(exchange.actionProvider.fetchActions(fetchOptions)).resolves.toBeDefined(); + for (const action of response.actions) { + expect(action).toBeDefined(); + expect(action.symbol).toBeDefined(); + expect(action.quantity).toBeDefined(); + expect(action.side).toBeDefined(); + expect(action.pricePerShare).toBeDefined(); + + expect(action.timestamp).toBeDefined(); + expect(action.timestamp.getFullYear()).toBe(2023); + expect(action.timestamp.getMonth()).toBe(9); + expect(action.timestamp.getDate()).toBe(23); + } }, timeout); });