From 2b1a6941158ab0a14f4cc9b1edc3deb7ecc2ad26 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Wed, 1 Nov 2023 19:07:24 -0700 Subject: [PATCH] update bollinger docs --- docs/marks/bollinger.md | 2 +- docs/transforms/map.md | 43 ++++++++++++----------------------------- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/docs/marks/bollinger.md b/docs/marks/bollinger.md index 949ba8cb44..e390ff5b4f 100644 --- a/docs/marks/bollinger.md +++ b/docs/marks/bollinger.md @@ -12,7 +12,7 @@ const k = ref(2); # Bollinger mark -The **bollinger mark** is a [composite mark](../features/marks.md#marks) consisting of a [line](./line.md) representing a moving average and an [area](./area.md) representing volatility as a band; the band thickness is proportional to the deviation of nearby values. The bollinger mark is often used to analyze the price of financial instruments such as stocks. +The **bollinger mark** is a [composite mark](../features/marks.md#marks) consisting of a [line](./line.md) representing a moving average and an [area](./area.md) representing volatility as a band; the band thickness is proportional to the deviation of nearby values. The bollinger mark is often used to [analyze the price](https://en.wikipedia.org/wiki/Bollinger_Bands) of financial instruments such as stocks. For example, the chart below shows the price of Apple stock from 2013 to 2018, with a window size *n* of {{n}} days and radius *k* of {{k}} standard deviations. diff --git a/docs/transforms/map.md b/docs/transforms/map.md index 79201cc86b..b76e1c07e8 100644 --- a/docs/transforms/map.md +++ b/docs/transforms/map.md @@ -5,16 +5,8 @@ import * as d3 from "d3"; import {ref} from "vue"; import aapl from "../data/aapl.ts"; -const N = ref(20); -const K = ref(2); - -function bollingerBandY(N, K, options) { - return Plot.map({y1: bollinger(N, -K), y2: bollinger(N, K)}, options); -} - -function bollinger(N, K) { - return Plot.window({k: N, reduce: (Y) => d3.mean(Y) + K * d3.deviation(Y), strict: true, anchor: "end"}); -} +const n = ref(20); +const k = ref(2); @@ -61,18 +53,18 @@ Is shorthand for this: Plot.map({y: "cumsum"}, {y: d3.randomNormal()}) ``` -As a more practical example, we can use the map transform to construct [Bollinger bands](https://en.wikipedia.org/wiki/Bollinger_Bands), showing both the price and volatility of Apple stock. +As a more practical example, we can use the map transform to construct [Bollinger bands](../marks/bollinger.md), showing both the price and volatility of Apple stock.

@@ -83,26 +75,15 @@ Plot.plot({ grid: true }, marks: [ - Plot.areaY(aapl, Plot.map({y1: bollinger(N, -K), y2: bollinger(N, K)}, {x: "Date", y: "Close", fillOpacity: 0.2})), - Plot.lineY(aapl, Plot.map({y: bollinger(N, 0)}, {x: "Date", y: "Close", stroke: "blue"})), + Plot.areaY(aapl, Plot.map({y1: Plot.bollinger({n, k: -k}), y2: Plot.bollinger({n, k})}, {x: "Date", y: "Close", fillOpacity: 0.2})), + Plot.lineY(aapl, Plot.map({y: Plot.bollinger({n})}, {x: "Date", y: "Close", stroke: "blue"})), Plot.lineY(aapl, {x: "Date", y: "Close", strokeWidth: 1}) ] }) ``` ::: -```js -function bollinger(N, K) { - return Plot.window({ - k: N, - reduce: (V) => d3.mean(V) + K * d3.deviation(V), - strict: true, - anchor: "end" - }); -} -``` - -The `bollinger` map method above is implemented atop the [window transform](./window.md), computing the mean of values within the rolling window, and then offsetting the mean by a multiple of the rolling deviation. +The [bollinger map method](../marks/bollinger.md#bollinger) is implemented atop the [window map method](./window.md#window), computing the mean of values within the rolling window, and then offsetting the mean by a multiple of the rolling deviation. The map transform is akin to running [*array*.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) on the input channel’s values with the given map method. However, the map transform is series-aware: the data are first grouped into series using the **z**, **fill**, or **stroke** channel in the same fashion as the [area](../marks/area.md) and [line](../marks/line.md) marks so that series are processed independently.