Skip to content

Commit 1be67f9

Browse files
authored
noneish check for bollinger marks (#1791)
1 parent c73fa05 commit 1be67f9

File tree

3 files changed

+2674
-26
lines changed

3 files changed

+2674
-26
lines changed

src/marks/bollinger.js

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import {deviation, mean} from "d3";
22
import {marks} from "../mark.js";
3+
import {identity, isNoneish} from "../options.js";
34
import {map} from "../transforms/map.js";
45
import {window} from "../transforms/window.js";
56
import {areaX, areaY} from "./area.js";
67
import {lineX, lineY} from "./line.js";
7-
import {identity} from "../options.js";
88

99
const defaults = {
1010
n: 20,
@@ -32,14 +32,18 @@ export function bollingerX(
3232
} = {}
3333
) {
3434
return marks(
35-
areaX(
36-
data,
37-
map(
38-
{x1: bollinger({k: -k, ...options}), x2: bollinger({k, ...options})},
39-
{x1: x, x2: x, y, fill, fillOpacity, ...options}
40-
)
41-
),
42-
lineX(data, map({x: bollinger(options)}, {x, y, stroke, strokeOpacity, strokeWidth, ...options}))
35+
isNoneish(fill)
36+
? null
37+
: areaX(
38+
data,
39+
map(
40+
{x1: bollinger({k: -k, ...options}), x2: bollinger({k, ...options})},
41+
{x1: x, x2: x, y, fill, fillOpacity, ...options}
42+
)
43+
),
44+
isNoneish(stroke)
45+
? null
46+
: lineX(data, map({x: bollinger(options)}, {x, y, stroke, strokeOpacity, strokeWidth, ...options}))
4347
);
4448
}
4549

@@ -60,14 +64,18 @@ export function bollingerY(
6064
} = {}
6165
) {
6266
return marks(
63-
areaY(
64-
data,
65-
map(
66-
{y1: bollinger({k: -k, ...options}), y2: bollinger({k, ...options})},
67-
{x, y1: y, y2: y, fill, fillOpacity, ...options}
68-
)
69-
),
70-
lineY(data, map({y: bollinger(options)}, {x, y, stroke, strokeOpacity, strokeWidth, ...options}))
67+
isNoneish(fill)
68+
? null
69+
: areaY(
70+
data,
71+
map(
72+
{y1: bollinger({k: -k, ...options}), y2: bollinger({k, ...options})},
73+
{x, y1: y, y2: y, fill, fillOpacity, ...options}
74+
)
75+
),
76+
isNoneish(stroke)
77+
? null
78+
: lineY(data, map({y: bollinger(options)}, {x, y, stroke, strokeOpacity, strokeWidth, ...options}))
7179
);
7280
}
7381

test/output/aaplBollingerCandlestick.svg

Lines changed: 2619 additions & 0 deletions
Loading

test/plots/aapl-bollinger.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@ import * as Plot from "@observablehq/plot";
22
import * as d3 from "d3";
33

44
export async function aaplBollinger() {
5-
const AAPL = await d3.csv<any>("data/aapl.csv", d3.autoType);
5+
const aapl = await d3.csv<any>("data/aapl.csv", d3.autoType);
66
return Plot.plot({
77
y: {
88
grid: true
99
},
1010
marks: [
11-
Plot.bollingerY(AAPL, {x: "Date", y: "Close", stroke: "blue"}),
12-
Plot.line(AAPL, {x: "Date", y: "Close", strokeWidth: 1})
11+
Plot.bollingerY(aapl, {x: "Date", y: "Close", stroke: "blue"}),
12+
Plot.line(aapl, {x: "Date", y: "Close", strokeWidth: 1})
1313
]
1414
});
1515
}
1616

1717
export async function aaplBollingerGridInterval() {
18-
const AAPL = await d3.csv<any>("data/aapl.csv", d3.autoType);
18+
const aapl = await d3.csv<any>("data/aapl.csv", d3.autoType);
1919
return Plot.plot({
2020
marks: [
2121
Plot.frame({fill: "#eaeaea"}),
@@ -25,14 +25,14 @@ export async function aaplBollingerGridInterval() {
2525
Plot.gridX({tickSpacing: 40, stroke: "#fff", strokeOpacity: 1, strokeWidth: 0.5}),
2626
Plot.gridX({tickSpacing: 80, stroke: "#fff", strokeOpacity: 1}),
2727
Plot.axisX({tickSpacing: 80}),
28-
Plot.bollingerY(AAPL, {x: "Date", y: "Close", stroke: "blue"}),
29-
Plot.line(AAPL, {x: "Date", y: "Close", strokeWidth: 1})
28+
Plot.bollingerY(aapl, {x: "Date", y: "Close", stroke: "blue"}),
29+
Plot.line(aapl, {x: "Date", y: "Close", strokeWidth: 1})
3030
]
3131
});
3232
}
3333

3434
export async function aaplBollingerGridSpacing() {
35-
const AAPL = await d3.csv<any>("data/aapl.csv", d3.autoType);
35+
const aapl = await d3.csv<any>("data/aapl.csv", d3.autoType);
3636
return Plot.plot({
3737
marks: [
3838
Plot.frame({fill: "#eaeaea"}),
@@ -42,8 +42,29 @@ export async function aaplBollingerGridSpacing() {
4242
Plot.gridX({interval: "3 months", stroke: "#fff", strokeOpacity: 1, strokeWidth: 0.5}),
4343
Plot.gridX({interval: "1 year", stroke: "#fff", strokeOpacity: 1}),
4444
Plot.axisX({interval: "1 year"}),
45-
Plot.bollingerY(AAPL, {x: "Date", y: "Close", stroke: "blue"}),
46-
Plot.line(AAPL, {x: "Date", y: "Close", strokeWidth: 1})
45+
Plot.bollingerY(aapl, {x: "Date", y: "Close", stroke: "blue"}),
46+
Plot.line(aapl, {x: "Date", y: "Close", strokeWidth: 1})
47+
]
48+
});
49+
}
50+
51+
export async function aaplBollingerCandlestick() {
52+
const aapl = await d3.csv<any>("data/aapl.csv", d3.autoType);
53+
return Plot.plot({
54+
x: {domain: [new Date("2014-01-01"), new Date("2014-06-01")]},
55+
y: {domain: [68, 92], grid: true},
56+
color: {domain: [-1, 0, 1], range: ["red", "black", "green"]},
57+
marks: [
58+
Plot.bollingerY(aapl, {x: "Date", y: "Close", stroke: "none", clip: true}),
59+
Plot.ruleX(aapl, {x: "Date", y1: "Low", y2: "High", strokeWidth: 1, clip: true}),
60+
Plot.ruleX(aapl, {
61+
x: "Date",
62+
y1: "Open",
63+
y2: "Close",
64+
strokeWidth: 3,
65+
stroke: (d) => Math.sign(d.Close - d.Open),
66+
clip: true
67+
})
4768
]
4869
});
4970
}

0 commit comments

Comments
 (0)