Public
Edited
May 8, 2023
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
ETH-USD@3.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
// Uncomment to activate

data_forAroundOneYear = aq.from(data_initial)
.filter( aq.escape(d => d["Date"].getFullYear() > 2022 ) )
.objects()
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.ruleX(data_forAroundOneYear, {
x:"Date",
y1: "High",
y2: "Low"
}),

Plot.ruleX(data_forAroundOneYear, {
x: "Date",
y1: "Open",
y2:"Close",
strokeWidth: 5,
stroke: "black"
}),
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.ruleX(data_forAroundOneYear, {
x:"Date",
y1: "High",
y2: "Low"
}),

Plot.ruleX(data_forAroundOneYear, {
x: "Date",
y1: "Open",
y2:"Close",
strokeWidth: 5,
stroke: d => d["Open"]< d["Close"]? "green": "red"
}),
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.ruleX(data_forAroundOneYear, {
x:"Date",
y1: "High",
y2: "Low",
stroke: d => d["Open"]< d["Close"]? "green": "red"
}),

Plot.ruleX(data_forAroundOneYear, {
x: "Date",
y1: "Open",
y2:"Close",
strokeWidth: 4,
stroke: d => d["Open"]< d["Close"]? "green": "red"
}),
]
})
Insert cell
Insert cell
Insert cell
Insert cell
year_slider
Insert cell
Insert cell
// Uncomment to enable
data_filtered = aq.from(data_initial)
.filter(aq.escape((d) => d["Date"].getFullYear() === year_slider))
.objects()
Insert cell
Insert cell
viewof year_slider = Inputs.range([2017, 2023], {label: "Amount", step: 1, value: 2023})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
numberOfDaysInFilteredData = data_filtered.length
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {Plot} from "@mkfreeman/plot-tooltip"
Insert cell
Plot.plot({

width: 1100,
marks: [

// Wicks
Plot.ruleX(data_filtered, {
x: "Date",
y1: "High",
y2: "Low",
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
title: d =>
`${ d["Date"].toLocaleString('default', { month: 'long' }) } ${ d["Date"].getDate() }
Close: ${ d3.format('.3s')(d["Close"]) }
Open: ${ d3.format('.3s')(d["Open"]) }
High: ${ d3.format('.3s')(d["High"]) }
Low: ${ d3.format('.3s')(d["Low"]) }`
}),
// Candle Body
Plot.ruleX(data_filtered, {
x: "Date",
y1: "Close",
y2: "Open",
strokeWidth: 1000 / numberOfDaysInFilteredData,
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
title: d =>
`${ d["Date"].toLocaleString('default', { month: 'long' }) } ${ d["Date"].getDate() }
Close: ${ d3.format('.3s')(d["Close"]) }
Open: ${ d3.format('.3s')(d["Open"]) }
High: ${ d3.format('.3s')(d["High"]) }
Low: ${ d3.format('.3s')(d["Low"]) }`
})
]
})
Insert cell
Insert cell
Insert cell
Insert cell
// Uncomment the first block to enable

createTooltipContent = (d) =>
`${ d["Date"].toLocaleString('default', { month: 'long' }) } ${d["Date"].getDate()}
Close: ${ d3.format('.3s')(d["Close"]) }
High: ${ d3.format('.3s')(d["High"]) }
Open: ${ d3.format('.3s')(d["Open"]) }
Low: ${ d3.format('.3s')(d["Low"]) }`


// The same function created with classic fuction syntax:

// createTooltipContent = function (d) {
// `${ d["Date"].toLocaleString('default', { month: 'long' }) } ${d["Date"].getDate()}
// Close: ${ d3.format('.3s')(d["Close"]) }
// High: ${ d3.format('.3s')(d["High"]) }
// Open: ${ d3.format('.3s')(d["Open"]) }
// Low: ${ d3.format('.3s')(d["Low"]) }`
// }
Insert cell
Insert cell
Plot.plot({
tooltip:{
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
},
width: 1100,
marks: [

// Wicks
Plot.ruleX(data_filtered, {
x: "Date",
y1: "High",
y2: "Low",
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
title: d => createTooltipContent( d )
}),
// Candle Body
Plot.ruleX(data_filtered, {
x: "Date",
y1: "Close",
y2: "Open",
strokeWidth: 1000 / numberOfDaysInFilteredData,
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
title: d => createTooltipContent( d )
})
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
fc = require('d3fc')
Insert cell
Insert cell
Insert cell
Insert cell
// Uncoment to enable

emaColumn = fc.indicatorExponentialMovingAverage()
.period( 9 )
.value(d => d["Close"])
( data_filtered )
Insert cell
Insert cell
Insert cell
// Uncoment to enable

bollingerColumn = fc.indicatorBollingerBands()
.value( d => d["Close"] )
.period( bollingerPeriod_slider )
.multiplier( 2 )
( data_filtered )
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Uncoment to enable

macdColumn = fc.indicatorMacd()
.value( d => d["Close"] )
.signalPeriod( 9 )
.fastPeriod( 12 )
.slowPeriod( 26 )
( data_filtered )
Insert cell
Insert cell
Insert cell
Insert cell
// Uncoment to enable

data_filtered_withIndicators = data_filtered.map( (d, i) => ({
ema: emaColumn[i],
macd: macdColumn[i].macd,
macdSignal: macdColumn[i].signal,
macdDivergence: macdColumn[i].divergence,
bollingerUpper: bollingerColumn[i].upper,
bollingerAverage: bollingerColumn[i].average,
bollingerLower: bollingerColumn[i].lower,
...d
}))
Insert cell
Insert cell
Inputs.table(data_filtered_withIndicators)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
tooltip:{
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
},
width: 1100,
marks: [
// Bollinger cloud
Plot.areaY(data_filtered_withIndicators, {
x: "Date",
y1: "bollingerUpper",
y2: "bollingerLower",
fill: "dodgerblue",
fillOpacity: 0.35,
stroke: "dodgerblue",
strokeOpacity: 1
}),


// Wicks
Plot.ruleX(data_filtered_withIndicators, {
x: "Date",
y1: "High",
y2: "Low",
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
title: d => createTooltipContent( d )
}),
// Candle Body
Plot.ruleX(data_filtered_withIndicators, {
x: "Date",
y1: "Close",
y2: "Open",
strokeWidth: 1000 / numberOfDaysInFilteredData,
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
title: d => createTooltipContent( d )
})
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
tooltip:{
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
},
width: 1100,
marks: [
// Bollinger cloud
Plot.areaY(data_filtered_withIndicators, {
x: "Date",
y1: "bollingerUpper",
y2: "bollingerLower",
fill: "dodgerblue",
fillOpacity: 0.35,
stroke: "dodgerblue",
strokeOpacity: 1
}),


// Wicks
Plot.ruleX(data_filtered_withIndicators, {
x: "Date",
y1: "High",
y2: "Low",
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
title: d => createTooltipContent( d )
}),
// Candle Body
Plot.ruleX(data_filtered_withIndicators, {
x: "Date",
y1: "Close",
y2: "Open",
strokeWidth: 1000 / numberOfDaysInFilteredData,
stroke: d => d['Open'] < d['Close'] ? "green" : "red",
title: d => createTooltipContent( d )
})
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Complete the code

data_fearGreedIndex_raw = d3.json("https://api.alternative.me/fng/?limit=0&format=json")
Insert cell
Insert cell
// Uncomment to activate

data_fearGreedIndex = aq.from(data_fearGreedIndex_raw.data)
.derive({ date: aq.escape(d => new Date(+d["timestamp"] * 1000)) })
.derive({ valueAsNumber: d => +d["value"] })
.select('value_classification','date','valueAsNumber')
.rename({valueAsNumber: "FearGreedValue"})
.rename({value_classification: "FearGreedClass"})
.rename({date: "FearGreedDate"})
.objects()
Insert cell
// Uncomment to activate

data_filtered_withIndicators_withFearGreedIndex = aq.from(data_filtered_withIndicators)
.join(aq.from(data_fearGreedIndex), ["Date", "FearGreedDate"])
.objects()
Insert cell
// Uncomment to activate

Inputs.table(data_filtered_withIndicators_withFearGreedIndex)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {toc} from "@nebrius/indented-toc"
Insert cell
import {Wrangler, op} from "@observablehq/data-wrangler"
Insert cell
import {howTo} from "@clokman/howto"
Insert cell
import {imageToDo} from "@clokman/student-blocks"
Insert cell
imageToDo
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more