{"id":23749424,"url":"https://github.com/data-forge/data-forge-indicators","last_synced_at":"2026-03-16T12:32:24.815Z","repository":{"id":42361419,"uuid":"133890193","full_name":"data-forge/data-forge-indicators","owner":"data-forge","description":"Financial indicators for use with Data-Forge","archived":false,"fork":false,"pushed_at":"2023-03-01T22:55:44.000Z","size":5175,"stargazers_count":40,"open_issues_count":10,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-31T22:57:06.653Z","etag":null,"topics":["algorithmic-trading","bollinger-bands","data-forge","financial-indicators","gaps","indicator","indicators","momentum","moving-average","quantitative-trading","rate-of-change","relative-strength-index","trading","visualization"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/data-forge.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":"ashleydavis"}},"created_at":"2018-05-18T02:03:22.000Z","updated_at":"2025-05-07T07:18:51.000Z","dependencies_parsed_at":"2023-11-27T16:01:34.464Z","dependency_job_id":"7e617073-5e94-465c-8c2d-9352c8416d99","html_url":"https://github.com/data-forge/data-forge-indicators","commit_stats":{"total_commits":92,"total_committers":4,"mean_commits":23.0,"dds":"0.15217391304347827","last_synced_commit":"8ddf416f4eebf84a55982ddc50602b36eac4dbe2"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/data-forge/data-forge-indicators","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/data-forge%2Fdata-forge-indicators","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/data-forge%2Fdata-forge-indicators/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/data-forge%2Fdata-forge-indicators/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/data-forge%2Fdata-forge-indicators/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/data-forge","download_url":"https://codeload.github.com/data-forge/data-forge-indicators/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/data-forge%2Fdata-forge-indicators/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261012873,"owners_count":23096928,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithmic-trading","bollinger-bands","data-forge","financial-indicators","gaps","indicator","indicators","momentum","moving-average","quantitative-trading","rate-of-change","relative-strength-index","trading","visualization"],"created_at":"2024-12-31T15:18:50.201Z","updated_at":"2026-03-16T12:32:19.778Z","avatar_url":"https://github.com/data-forge.png","language":"TypeScript","funding_links":["https://github.com/sponsors/ashleydavis"],"categories":[],"sub_categories":[],"readme":"# data-forge-indicators\n\nFinancial and quantitative trading indicators for use with [Data-Forge](http://www.data-forge-js.com/).\n\n[Please click here for a graphical example of all indicators](https://data-forge.github.io/data-forge-indicators/).\n\nNeed to learn data wrangling? See my book [Data Wrangling with JavaScript](http://bit.ly/2t2cJu2) or blog [The Data Wrangler](http://www.the-data-wrangler.com/).\n\nDo prototyping and data analysis in JavaScript with [Data-Forge Notebook](http://www.data-forge-notebook.com/).\n\n[Click here to support my work](https://www.codecapers.com.au/about#support-my-work)\n\n## Indicators supported\n\n- Simple moving average (`sma`)\n- Exponential moving average (`ema`)\n- Bollinger bands (`bollinger`) (including `percentB` and `bandwidth`)\n- Gaps (`gaps`)\n- Market direction (`direction`)\n- Market extrema (`extrema`)\n- Market trends (`trends`)\n- Momentum (`momentum`)\n- Rate of change (`roc`)\n- Relative strength index (`rsi`)\n- Streaks (`streaks`)\n- Connor's RSI (`crsi`)\n- Stochastic (`stochasticSlow` and `stochasticFast`)\n\nMORE INDICATORS COMING SOON\n\n## Setup\n\nInstall Data-Forge, Data-Forge Indicators and auxilary modules via npm:\n\n    npm install --save data-forge data-forge-fs data-forge-plot data-forge-indicators \n\nImport into your script (JavaScript):\n\n```javascript\nconst dataForge = require('data-forge');\nrequire('data-forge-fs'); // Add file system functions to Data-Forge.\nrequire('data-forge-plot'); // Add chart plotting functions to Data-Forge.\nrequire('data-forge-indicators'); // Add financial indicator functions to Data-Forge.\n```\n\nImport into your script (TypeScript):\n\n```typescript\nimport * as dataForge from 'data-forge';\nimport 'data-forge-fs'; // Add file system functions to Data-Forge.\nimport 'data-forge-plot'; // Add chart plotting functions to Data-Forge.\nimport 'data-forge-indicators'; // Add financial indicator functions to Data-Forge.\n```\n\n## Loading some data\n\nTo compute some indicators you'll need to load some data. You can load your data from whatever source you want, you might load it from a database or a REST API. For this example we'll load our data from a [CSV](https://en.wikipedia.org/wiki/Comma-separated_values) data file:\n\n```javascript\nlet inputSeries = dataForge.readFileSync(\"STW.csv\")\n    .parseCSV()\n    .parseDates(\"date\", \"DD/MM/YYYY\")\n    .parseFloats([\"open\", \"high\", \"low\", \"close\", \"volume\"])\n    .setIndex(\"date\") // Index so we can later merge on date.\n    .bake();\n```\n\n## Moving average \n\nUse the `sma` function to compute a simple moving average of a data series:\n\n```javascript\nconst movingAverage = inputSeries\n    .deflate(bar =\u003e bar.close)  // Extract closing price series from input data.\n    .sma(30)                    // 30 day moving average.\n    .bake();                    // Force lazy evaluation to complete.\n```\n\nTo compare the moving average against your input data you'll need to merge it back into your source data:\n\n```javascript\nconst withMovingAverage = inputSeries\n    .skip(30)                           // Skip blank sma entries.\n    .withSeries(\"sma\", movingAverage)   // Integrate moving average into data, indexed on date.\n    .bake();\n```\n\nYou can preview your data in [Data-Forge Notebook](http://www.data-forge-notebook.com/) using the `display` function:\n\n```javascript\ndisplay(withMovingAverage.tail(5));\n```\n\n![Input data merged with moving average](https://raw.githubusercontent.com/data-forge/data-forge-indicators/master/images/sma-preview.png)\n\nYou can plot the moving average and compare to the source data using Data-Forge Plot:\n\n```javascript\nconst plot = withMovingAverage.plot({}, { y: [\"close\", \"sma\"] }));\nplot.renderImage(\"sma.png\");\n```\n\nOr plot with the [Data-Forge Notebook](http://www.data-forge-notebook.com/) `display` function:\n\n```javascript\ndisplay(plot);\n```\n\nThe rendered chart looks like this: \n\n![Simple moving average chart](https://raw.githubusercontent.com/data-forge/data-forge-indicators/master/images/sma.png)\n\nAlso available is an `ema` function that works in the same way as `sma`.\n\n## Bollinger bands\n\nUse the `bollinger` function to compute [Bollinger Bands](https://en.wikipedia.org/wiki/Bollinger_Bands) from a data series:\n\n```javascript\nconst bollingerBands = inputSeries\n    .deflate(bar =\u003e bar.close)  // Extract closing price series from input data.\n    .bollinger(20, 2, 2)        // 20 days with bands at 2 standard deviations.\n    .bake();\n```\n\nYou can preview your data in [Data-Forge Notebook](http://www.data-forge-notebook.com/) using the `display` function:\n\n```javascript\ndisplay(bollingerBands.tail(5));\n```\n\n![Bollinger bands table preview](https://raw.githubusercontent.com/data-forge/data-forge-indicators/master/images/bollinger-preview.png)\n\nTo compare Bollinger Bands to the closing price, merge the closing price data series into the bollinger bands dataframe:\n\n```javascript\nconst withBollingerBands = bollingerBands\n    .withSeries(\"close\",\n        inputSeries.deflate(row =\u003e row.close)\n    );\n```\n\nYou can render a chart using Data-Forge Plot or [Data-Forge Notebook](http://www.data-forge-notebook.com/).\n\nThe chart looks like this:\n\n![Bollinger bands chart](https://raw.githubusercontent.com/data-forge/data-forge-indicators/master/images/bollinger-chart.png)\n\n## Percent b and bandwidth\n\nPercent b (%b) and bandwidth are indicators [derived from Bollinger Bands](https://en.wikipedia.org/wiki/Bollinger_Bands#Indicators_derived_from_Bollinger_Bands). \n\n%b shows where price is in relation to the bands with values at 1 for the upper band and 0 for the lower band:\n\n```javascript\nconst percentB = = inputSeries\n    .deflate(bar =\u003e bar.close)\n    .bollinger(20, 2, 2)        // Need Bollinger Bands first.\n    .percentB();\n```\n\nBandwidth shows the normalised width of the bands:\n\n```javascript\nconst bandwidth = = inputSeries\n    .deflate(bar =\u003e bar.close)\n    .bollinger(20, 2, 2)        // Need Bollinger Bands first.\n    .bandwidth();\n```\n\n## Gaps\n\nUse the gaps function to compute percentage gap between close and open of subsequent days/bars.\n\nTo use this functon your input dataframe must have open, high, low and close (OHLC) fields.\n\n```javascript\nconst gaps = inputSeries.gaps();\nconsole.log(gaps.toArray());\n```\n\n## Market direction\n\nThe `direction` function allows you test the direction of a series.\n\n```javascript\nconst dailyDirection = inputSeries\n    .deflate(row =\u003e row.close)\n    .direction(2);\n```\n\n```javascript\nconst monthlyDirection = inputSeries\n    .deflate(row =\u003e row.close)\n    .direction(30);\n```\n\nThe result is a series of -1, 0 and 1 values that indicate the direction of the value (down, flat or up) for the particular time period.\n\n## Market extrema\n\nThe `extrema` function builds on the `direction` function to pick out minima (troughs) and maxima (peaks) in the series.\n\n```javascript\nconst extrema = inputSeries\n    .deflate(row =\u003e row.close)\n    .extrema();\n```\n\n## Market trends\n\nThe `trends` function builds on the `extrema` function to detect trends in the market. It returns a series of -1 and 1 values to tell you when the series is in downtrend or uptrend.\n\n```javascript\nconst trends = inputSeries\n    .deflate(row =\u003e row.close)\n    .trends();\n```\n\nAn uptrend is defined as a series of higher troughs.\n\nA downtrend is defined as a series of lower peaks.\n\n## Momentum\n\nCompute [momentum](https://en.wikipedia.org/wiki/Momentum_(technical_analysis)) using the `momentum` function.\n\n```javascript\nconst momentum = inputSeries.deflate(row =\u003e row.close).momentum(30);\n```\n\n## Rate of change\n\nCompute [rate of change](https://en.wikipedia.org/wiki/Momentum_(technical_analysis)) using the `rateOfChange` function.\n\n```javascript\nconst rateOfChange = inputSeries.deflate(row =\u003e row.close).roc(30);\n```\n\n## Relative strength index\n\nUse the `rsi` function to compute relative strength.\n\n```javascript\nconst rsi = inputSeries.deflate(row =\u003e row.close).rsi(14);\n```\n\n## Streaks\n\nUse the `streaks` function to count streaks of up days and down days.\n\nUp day streaks are counted with positive numbers, down day streaks with negative numbers.\n\nThis function is used by Connor's RSI (`csri`).\n\n```javascript\nconst streaks = inputSeries.deflate(row =\u003e row.close).streaks();\ndisplay(streaks.plot());\n```\n\n## Connor's RSI\n\nUse the `csri` function for Connor's updated RSI indicator.\n\n```javascript\nconst crsi = inputSeries.deflate(row =\u003e row.close).crsi(3, 2, 100);\ndisplay(crsi.plot({ y: { min: 0, max: 99 } }));\n```\n\n## MACD\n\nUse the `macd` function to compute *moving average convergence divergence*:\n\n```javascript\nconst macd = inputSeries.deflate(row =\u003e row.close).macd(12, 26, 9); // Inputs are short ema period, long ema period and signal line period.\ndisplay(macd.plot({}, { y: \"histogram\" }));\n```\n\n## Stochastic\n\nCompute Stochastic using the `stochasticSlow`  or `stochasticFast`  function.\n\n```javascript\nconst stochasticSlow = inputSeries.stochasticSlow(20, 12, 12)\n    .withSeries('stoch slow', stochasticSlow)\n\nconst stochasticFast = inputSeries.stochasticSlow(20, 12)\n    .withSeries('stoch fast', stochasticFast)\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdata-forge%2Fdata-forge-indicators","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdata-forge%2Fdata-forge-indicators","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdata-forge%2Fdata-forge-indicators/lists"}