Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
434 changes: 434 additions & 0 deletions packages/alphavantage/client.test.ts

Large diffs are not rendered by default.

420 changes: 420 additions & 0 deletions packages/alphavantage/client.ts

Large diffs are not rendered by default.

1,014 changes: 1,014 additions & 0 deletions packages/alphavantage/endpoints.test.ts

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions packages/alphavantage/endpoints/commodities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { AlphaVantageEndpoints } from '../index';
import { indicatorSeriesEndpoint } from './indicator-series';

/**
* Global commodity price series.
*
* Every operation here returns the shared indicator envelope, so all nine are
* built from the same factory. Note the interval range differs: Brent crude is
* published daily, weekly and monthly, while the metals and agricultural
* commodities are monthly, quarterly and annual. That difference is enforced by
* the input schemas in `types.ts`.
*
* The catalog omits WTI crude and natural gas even though Alpha Vantage
* publishes both; this plugin matches the catalog rather than adding them.
*/

export const all: AlphaVantageEndpoints['commoditiesAll'] =
indicatorSeriesEndpoint('ALL_COMMODITIES', 'commodities.all');

export const aluminum: AlphaVantageEndpoints['commoditiesAluminum'] =
indicatorSeriesEndpoint('ALUMINUM', 'commodities.aluminum');

export const brent: AlphaVantageEndpoints['commoditiesBrent'] =
indicatorSeriesEndpoint('BRENT', 'commodities.brent');

export const coffee: AlphaVantageEndpoints['commoditiesCoffee'] =
indicatorSeriesEndpoint('COFFEE', 'commodities.coffee');

export const copper: AlphaVantageEndpoints['commoditiesCopper'] =
indicatorSeriesEndpoint('COPPER', 'commodities.copper');

export const corn: AlphaVantageEndpoints['commoditiesCorn'] =
indicatorSeriesEndpoint('CORN', 'commodities.corn');

export const cotton: AlphaVantageEndpoints['commoditiesCotton'] =
indicatorSeriesEndpoint('COTTON', 'commodities.cotton');

export const sugar: AlphaVantageEndpoints['commoditiesSugar'] =
indicatorSeriesEndpoint('SUGAR', 'commodities.sugar');

export const wheat: AlphaVantageEndpoints['commoditiesWheat'] =
indicatorSeriesEndpoint('WHEAT', 'commodities.wheat');
128 changes: 128 additions & 0 deletions packages/alphavantage/endpoints/crypto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { logEventFromContext } from 'corsair/core';
import { makeAlphaVantageRequest } from '../client';
import type { AlphaVantageEndpoints } from '../index';
import { auditPayload } from './logging';
import { assertSeriesHasData, compactQuery } from './shared';
import type { AlphaVantageEndpointOutputs } from './types';

/**
* Intraday bars for a digital currency quoted in a fiat market.
*
* Premium-plan only — verified live: a free-tier key receives the premium
* notice. The daily, weekly and monthly crypto operations are all free.
*/
export const intraday: AlphaVantageEndpoints['cryptoIntraday'] = async (
ctx,
input,
) => {
const result = await makeAlphaVantageRequest<
AlphaVantageEndpointOutputs['cryptoIntraday']
>(
'CRYPTO_INTRADAY',
ctx.key,
compactQuery({
symbol: input.symbol,
market: input.market,
interval: input.interval,
outputsize: input.outputsize,
}),
);

assertSeriesHasData(
result,
'crypto.intraday',
`${input.symbol}/${input.market}`,
);

await logEventFromContext(
ctx,
'alphavantage.crypto.intraday',
auditPayload(input, ['symbol', 'market', 'interval']),
'completed',
);
return result;
};

/** Daily bars for a digital currency. */
export const daily: AlphaVantageEndpoints['cryptoDaily'] = async (
ctx,
input,
) => {
const result = await makeAlphaVantageRequest<
AlphaVantageEndpointOutputs['cryptoDaily']
>(
'DIGITAL_CURRENCY_DAILY',
ctx.key,
compactQuery({ symbol: input.symbol, market: input.market }),
);

assertSeriesHasData(
result,
'crypto.daily',
`${input.symbol}/${input.market}`,
);

await logEventFromContext(
ctx,
'alphavantage.crypto.daily',
auditPayload(input, ['symbol', 'market']),
'completed',
);
return result;
};

/** Weekly bars for a digital currency. */
export const weekly: AlphaVantageEndpoints['cryptoWeekly'] = async (
ctx,
input,
) => {
const result = await makeAlphaVantageRequest<
AlphaVantageEndpointOutputs['cryptoWeekly']
>(
'DIGITAL_CURRENCY_WEEKLY',
ctx.key,
compactQuery({ symbol: input.symbol, market: input.market }),
);

assertSeriesHasData(
result,
'crypto.weekly',
`${input.symbol}/${input.market}`,
);

await logEventFromContext(
ctx,
'alphavantage.crypto.weekly',
auditPayload(input, ['symbol', 'market']),
'completed',
);
return result;
};

/** Monthly bars for a digital currency. */
export const monthly: AlphaVantageEndpoints['cryptoMonthly'] = async (
ctx,
input,
) => {
const result = await makeAlphaVantageRequest<
AlphaVantageEndpointOutputs['cryptoMonthly']
>(
'DIGITAL_CURRENCY_MONTHLY',
ctx.key,
compactQuery({ symbol: input.symbol, market: input.market }),
);

assertSeriesHasData(
result,
'crypto.monthly',
`${input.symbol}/${input.market}`,
);

await logEventFromContext(
ctx,
'alphavantage.crypto.monthly',
auditPayload(input, ['symbol', 'market']),
'completed',
);
return result;
};
67 changes: 67 additions & 0 deletions packages/alphavantage/endpoints/economic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { logEventFromContext } from 'corsair/core';
import { makeAlphaVantageRequest } from '../client';
import type { AlphaVantageEndpoints } from '../index';
import { indicatorSeriesEndpoint } from './indicator-series';
import { auditPayload } from './logging';
import { compactQuery } from './shared';
import type { AlphaVantageEndpointOutputs } from './types';

/**
* United States macroeconomic indicators.
*
* All ten return the shared indicator envelope. Nine take at most an interval
* and are built from the common factory; the treasury yield also takes a
* maturity and is written out in full.
*/

export const realGdp: AlphaVantageEndpoints['economicRealGdp'] =
indicatorSeriesEndpoint('REAL_GDP', 'economic.realGdp');

export const realGdpPerCapita: AlphaVantageEndpoints['economicRealGdpPerCapita'] =
indicatorSeriesEndpoint('REAL_GDP_PER_CAPITA', 'economic.realGdpPerCapita');

export const federalFundsRate: AlphaVantageEndpoints['economicFederalFundsRate'] =
indicatorSeriesEndpoint('FEDERAL_FUNDS_RATE', 'economic.federalFundsRate');

export const cpi: AlphaVantageEndpoints['economicCpi'] =
indicatorSeriesEndpoint('CPI', 'economic.cpi');

export const inflation: AlphaVantageEndpoints['economicInflation'] =
indicatorSeriesEndpoint('INFLATION', 'economic.inflation');

export const retailSales: AlphaVantageEndpoints['economicRetailSales'] =
indicatorSeriesEndpoint('RETAIL_SALES', 'economic.retailSales');

export const durables: AlphaVantageEndpoints['economicDurables'] =
indicatorSeriesEndpoint('DURABLES', 'economic.durables');

export const nonfarmPayroll: AlphaVantageEndpoints['economicNonfarmPayroll'] =
indicatorSeriesEndpoint('NONFARM_PAYROLL', 'economic.nonfarmPayroll');

export const unemployment: AlphaVantageEndpoints['economicUnemployment'] =
indicatorSeriesEndpoint('UNEMPLOYMENT', 'economic.unemployment');

/**
* US treasury yield for a given constant maturity.
*
* The only indicator in this group that takes a second parameter, so it does
* not use the shared factory.
*/
export const treasuryYield: AlphaVantageEndpoints['economicTreasuryYield'] =
async (ctx, input) => {
const result = await makeAlphaVantageRequest<
AlphaVantageEndpointOutputs['economicTreasuryYield']
>(
'TREASURY_YIELD',
ctx.key,
compactQuery({ interval: input.interval, maturity: input.maturity }),
);

await logEventFromContext(
ctx,
'alphavantage.economic.treasuryYield',
auditPayload(input, ['interval', 'maturity']),
'completed',
);
return result;
};
Loading
Loading