Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new module recommendationsBySymbol #28

Merged
merged 5 commits into from
Feb 9, 2021
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
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ insiderTransactions, institutionOwnership, majorDirectHolders,
majorHoldersBreakdown, netSharePurchaseActivity, price, quoteType,
recommendationTrend, secFilings, sectorTrend, summaryDetail, summaryProfile,
symbol, topHoldings, upgradeDowngradeHistory),
[`search`](./docs/modules/search.md), with more
[`search`](./docs/modules/search.md),
[`recommendationsBySymbol`](./docs/modules/recommendationsBySymbol.md), with more
[coming soon](https://github.com/gadicc/node-yahoo-finance2/issues/8).

See the [Full Documentation](./docs/README.md).
Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
1. [historical](./modules/historical.md)
1. [quoteSummary](./modules/quoteSummary.md)
1. [search](./modules/search.md)
1. [recommendationsBySymbol](./modules/recommendationsBySymbol.md)

1. [Errors Handling](#error-handling)

Expand Down
56 changes: 56 additions & 0 deletions docs/modules/recommendationsBySymbol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# recommendationsBySymbol

## Usage:

```js
import yahooFinance from 'yahoo-finance2';

// 1. Get recommended symbols for Apple
const searchSingle = await yahooFinance2.recommendationsBySymbol('AAPL');

{
symbol: 'AAPL',
recommendedSymbols: [
{ symbol: 'AMZN', score: 0.292276 },
{ symbol: 'FB', score: 0.274045 },
{ symbol: 'GOOG', score: 0.272778 },
{ symbol: 'TSLA', score: 0.270931 },
{ symbol: 'NFLX', score: 0.209186 }
]
}

// 2. Get recommended symbols for Apple and BMW
const searchMultiple = await yahooFinance2.recommendationsBySymbol([
'AAPL',
'BMW.DE',
]);

[
{
symbol: 'AAPL',
recommendedSymbols: [ [Object], [Object], [Object], [Object], [Object] ]
},
{
symbol: 'BMW.DE',
recommendedSymbols: [ [Object], [Object], [Object], [Object], [Object] ]
}
]
```

## API

```js
await yahooFinance.recommendationsBySymbol(query, queryOptions, moduleOptions);
```

### Query

You can pass a single symbol as a string, e.g `AAPL` or multiple symbols in an array, e.g `['AAPL', 'BMW.DE']`.

### Query Options

There are no query options for this module that we know of.

### Module Options

See [Common Options](../README.md#common-options).
42 changes: 42 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3949,6 +3949,48 @@
],
"type": "object"
},
"RecommendationsBySymbolOptions": {
"additionalProperties": false,
"type": "object"
},
"RecommendationsBySymbolResponse": {
"additionalProperties": false,
"properties": {
"recommendedSymbols": {
"items": {
"additionalProperties": false,
"properties": {
"score": {
"yahooFinanceType": "number"
},
"symbol": {
"type": "string"
}
},
"required": [
"score",
"symbol"
],
"type": "object"
},
"type": "array"
},
"symbol": {
"type": "string"
}
},
"required": [
"recommendedSymbols",
"symbol"
],
"type": "object"
},
"RecommendationsBySymbolResponseArray": {
"items": {
"$ref": "#/definitions/RecommendationsBySymbolResponse"
},
"type": "array"
},
"Relation": {
"enum": [
"Chairman of the Board",
Expand Down
2 changes: 2 additions & 0 deletions src/index-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import historical from './modules/historical';
import quote from './modules/quote';
import quoteSummary from './modules/quoteSummary';
import search from './modules/search';
import recommendationsBySymbol from './modules/recommendationsBySymbol';

export default {
_env: {},
Expand All @@ -21,4 +22,5 @@ export default {
quote,
quoteSummary,
search,
recommendationsBySymbol,
};
32 changes: 32 additions & 0 deletions src/modules/recommendationsBySymbol.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import recommendationsBySymbol from './recommendationsBySymbol';
import { testSymbols } from '../../tests/symbols';

import _env from '../env-node';
import _fetch from '../lib/yahooFinanceFetch';
import _moduleExec from '../lib/moduleExec';

const yf = {
_env,
_fetch,
_opts: { validation: { logErrors: true }},
_moduleExec,
recommendationsBySymbol
};

describe('recommendationsBySymbol', () => {

// make sure it passes validation for some symbols
testSymbols.forEach((symbol) => {
it(`passes validation for symbol: ${symbol}`, async () => {
const devel = `recommendationsBySymbol-${symbol}.json`;
await yf.recommendationsBySymbol(symbol, {}, { devel });
});
});

// make sure it passes validation for multiple symbols
it(`passes validation for multiple symbols ("AAPL" and "BMW.DE")`, async () => {
const devel = `recommendationsBySymbol-AAPL-BMW.DE.json`;
await yf.recommendationsBySymbol(['AAPL', 'BMW.DE'], {}, { devel });
});

});
76 changes: 76 additions & 0 deletions src/modules/recommendationsBySymbol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import type {
ModuleOptions,
ModuleOptionsWithValidateFalse,
ModuleOptionsWithValidateTrue,
ModuleThis,
} from '../lib/moduleCommon';

export interface RecommendationsBySymbolResponse {
recommendedSymbols: Array<{
score: number; // 0.1927
symbol: string; // "BMW.DE"
}>,
symbol: string,
}

export type RecommendationsBySymbolResponseArray = RecommendationsBySymbolResponse[];

export interface RecommendationsBySymbolOptions {}

const queryOptionsDefaults = {};

export default function recommendationsBySymbol(
this: ModuleThis,
query: string,
queryOptionsOverrides?: RecommendationsBySymbolOptions,
moduleOptions?: ModuleOptionsWithValidateTrue,
): Promise<RecommendationsBySymbolResponse>;

export default function recommendationsBySymbol(
this: ModuleThis,
query: string | string[],
queryOptionsOverrides?: RecommendationsBySymbolOptions,
moduleOptions?: ModuleOptionsWithValidateTrue,
): Promise<RecommendationsBySymbolResponseArray>;

export default function recommendationsBySymbol(
this: ModuleThis,
query: string | string[],
queryOptionsOverrides?: RecommendationsBySymbolOptions,
moduleOptions?: ModuleOptionsWithValidateFalse,
): Promise<any>;

export default function recommendationsBySymbol(
this: ModuleThis,
query: string | string[],
queryOptionsOverrides?: RecommendationsBySymbolOptions,
moduleOptions?: ModuleOptions
): Promise<any> {

const symbols = typeof query === 'string' ? query : query.join(',');

return this._moduleExec({
moduleName: "recommendationsBySymbol",

query: {
url: `https://query2.finance.yahoo.com/v6/finance/recommendationsbysymbol/${symbols}`,
schemaKey: "#/definitions/RecommendationsBySymbolOptions",
defaults: queryOptionsDefaults,
overrides: queryOptionsOverrides || {},
},

result: {
schemaKey: "#/definitions/RecommendationsBySymbolResponseArray",
transformWith(result: any) {
if (!result.finance)
throw new Error("Unexpected result: " + JSON.stringify(result));
return result.finance.result;
}
},

moduleOptions,
}).then((results: RecommendationsBySymbolResponseArray) => {
return typeof query === 'string' ? results[0] as RecommendationsBySymbolResponse : results as RecommendationsBySymbolResponseArray;
});;

}
64 changes: 64 additions & 0 deletions tests/http/recommendationsBySymbol-0P000071W8.TO.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"request": {
"url": "https://query2.finance.yahoo.com/v6/finance/recommendationsbysymbol/0P000071W8.TO?"
},
"response": {
"ok": true,
"status": 200,
"statusText": "OK",
"headers": {
"x-yahoo-request-id": [
"en732atg239t2"
],
"cache-control": [
"max-age=60, stale-while-revalidate=15, stale-if-error=3600"
],
"content-encoding": [
"gzip"
],
"content-type": [
"application/json;charset=utf-8"
],
"vary": [
"Origin"
],
"content-length": [
"156"
],
"date": [
"Mon, 08 Feb 2021 21:05:38 GMT"
],
"age": [
"0"
],
"strict-transport-security": [
"max-age=15552000"
],
"server": [
"ATS"
],
"public-key-pins-report-only": [
"max-age=2592000; pin-sha256=\"2fRAUXyxl4A1/XHrKNBmc8bTkzA7y4FB/GLJuNAzCqY=\"; pin-sha256=\"I/Lt/z7ekCWanjD0Cvj5EqXls2lOaThEA0H2Bg4BT/o=\"; pin-sha256=\"K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q=\"; pin-sha256=\"Wd8xe/qfTwq3ylFNd3IpaqLHZbh2ZNCLluVzmeNkcpw=\"; pin-sha256=\"WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=\"; pin-sha256=\"cGuxAXyFXFkWm61cF4HPWX8S0srS9j0aSqN0k4AP+4A=\"; pin-sha256=\"dolnbtzEBnELx/9lOEQ22e6OZO/QNb6VSSX2XHA3E7A=\"; pin-sha256=\"i7WTqTvh0OioIruIfFR4kMPnBqrS2rdiVPl/s2uC/CY=\"; pin-sha256=\"r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=\"; pin-sha256=\"uUwZgwDOxcBXrQcntwu+kYFpkiVkOaezL0WYEZ3anJc=\"; includeSubdomains; report-uri=\"http://csp.yahoo.com/beacon/csp?src=yahoocom-hpkp-report-only\""
],
"x-frame-options": [
"SAMEORIGIN"
],
"referrer-policy": [
"no-referrer-when-downgrade"
],
"connection": [
"close"
],
"expect-ct": [
"max-age=31536000, report-uri=\"http://csp.yahoo.com/beacon/csp?src=yahoocom-expect-ct-report-only\""
],
"x-xss-protection": [
"1; mode=block"
],
"x-content-type-options": [
"nosniff"
]
},
"body": "{\"finance\":{\"result\":[{\"symbol\":\"0P000071W8.TO\",\"recommendedSymbols\":[{\"symbol\":\"0P000071WA.TO\",\"score\":0.027705},{\"symbol\":\"0P000071AX.TO\",\"score\":0.025959},{\"symbol\":\"0P000071B1.TO\",\"score\":0.018005},{\"symbol\":\"0P000071W5.TO\",\"score\":0.00679},{\"symbol\":\"0P000071WU.TO\",\"score\":0.004543}]}],\"error\":null}}"
}
}
64 changes: 64 additions & 0 deletions tests/http/recommendationsBySymbol-AAPL-BMW.DE.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"request": {
"url": "https://query2.finance.yahoo.com/v6/finance/recommendationsbysymbol/AAPL,BMW.DE?"
},
"response": {
"ok": true,
"status": 200,
"statusText": "OK",
"headers": {
"x-yahoo-request-id": [
"3hmisslg23b5s"
],
"cache-control": [
"max-age=60, stale-while-revalidate=15, stale-if-error=3600"
],
"content-encoding": [
"gzip"
],
"content-type": [
"application/json;charset=utf-8"
],
"vary": [
"Origin"
],
"content-length": [
"216"
],
"date": [
"Mon, 08 Feb 2021 21:27:25 GMT"
],
"age": [
"3"
],
"strict-transport-security": [
"max-age=15552000"
],
"server": [
"ATS"
],
"public-key-pins-report-only": [
"max-age=2592000; pin-sha256=\"2fRAUXyxl4A1/XHrKNBmc8bTkzA7y4FB/GLJuNAzCqY=\"; pin-sha256=\"I/Lt/z7ekCWanjD0Cvj5EqXls2lOaThEA0H2Bg4BT/o=\"; pin-sha256=\"K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q=\"; pin-sha256=\"Wd8xe/qfTwq3ylFNd3IpaqLHZbh2ZNCLluVzmeNkcpw=\"; pin-sha256=\"WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=\"; pin-sha256=\"cGuxAXyFXFkWm61cF4HPWX8S0srS9j0aSqN0k4AP+4A=\"; pin-sha256=\"dolnbtzEBnELx/9lOEQ22e6OZO/QNb6VSSX2XHA3E7A=\"; pin-sha256=\"i7WTqTvh0OioIruIfFR4kMPnBqrS2rdiVPl/s2uC/CY=\"; pin-sha256=\"r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=\"; pin-sha256=\"uUwZgwDOxcBXrQcntwu+kYFpkiVkOaezL0WYEZ3anJc=\"; includeSubdomains; report-uri=\"http://csp.yahoo.com/beacon/csp?src=yahoocom-hpkp-report-only\""
],
"x-frame-options": [
"SAMEORIGIN"
],
"referrer-policy": [
"no-referrer-when-downgrade"
],
"connection": [
"close"
],
"expect-ct": [
"max-age=31536000, report-uri=\"http://csp.yahoo.com/beacon/csp?src=yahoocom-expect-ct-report-only\""
],
"x-xss-protection": [
"1; mode=block"
],
"x-content-type-options": [
"nosniff"
]
},
"body": "{\"finance\":{\"result\":[{\"symbol\":\"AAPL\",\"recommendedSymbols\":[{\"symbol\":\"AMZN\",\"score\":0.292276},{\"symbol\":\"FB\",\"score\":0.274045},{\"symbol\":\"GOOG\",\"score\":0.272778},{\"symbol\":\"TSLA\",\"score\":0.270931},{\"symbol\":\"NFLX\",\"score\":0.209186}]},{\"symbol\":\"BMW.DE\",\"recommendedSymbols\":[{\"symbol\":\"DAI.DE\",\"score\":0.1927},{\"symbol\":\"VOW.DE\",\"score\":0.105787},{\"symbol\":\"SIE.DE\",\"score\":0.102734},{\"symbol\":\"VOW3.DE\",\"score\":0.098733},{\"symbol\":\"BAS.DE\",\"score\":0.098715}]}],\"error\":null}}"
}
}
Loading