Public
Edited
May 14, 2023
4 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Inputs.table(data_final)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
imageToDo // <- comment out or remove this to prevent this notebook from drawing dashed lines around all images.
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
data_final = data_withFearGreedIndex
Insert cell
Inputs.table(data_final)
Insert cell
Insert cell
data_yahooRaw = FileAttachment("ETH-USD-3.csv").csv({typed: true})
Insert cell
Insert cell
Insert cell
Inputs.table(data_yahooRaw)
Insert cell
Insert cell
data_yahooWithRenamedColumns = aq.from(data_yahooRaw)
.rename({Date: "date"})
.rename({Open: "open"})
.rename({High: "high"})
.rename({Low: "low"})
.rename({Close: "close"})
.rename({"Adj Close": "adjClose"})
.rename({Volume: "volume"})
.objects()
Insert cell
Insert cell
data_yahooFiltered = aq.from(data_yahooWithRenamedColumns)
.params({
yearStart: new Date(+control_timeRange[0], 0, 1).getTime(),
yearEnd: new Date(+control_timeRange[1], 0, 0).getTime()
})
.filter ( (d, params) => d["date"] > params.yearStart)
.filter ( (d, params) => d["date"] < params.yearEnd)
.derive ({color: d => d.close < d.open ? "crimson" : "oliveDrab"})
.objects()
Insert cell
Inputs.table(data_yahooFiltered)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof control_bollingerPeriod = Inputs.range([2, 200], {
value: 7,
step: 1,
label: "Bollinger Period"
})
Insert cell
viewof control_bollingerSD = Inputs.range([0.5, 4], {
value: 2,
label: "Bollinger SD",
step: 0.1
})
Insert cell
viewof control_maLookbackPeriod = Inputs.range([1, 200], {label: "MA Period", value: 9, step: 1})
Insert cell
viewof control_macdSignalPeriod = Inputs.range([1, 200], {label: "MACD Signal Period", value: 9, step: 1, width: 300})
Insert cell
viewof control_macdFastPeriod = Inputs.range([1, 200], {label: "MACD Fast Period", value: 12, step: 1})
Insert cell
viewof control_macdSlowPeriod = Inputs.range([1, 200], {label: "MACD Slow Period", value: 26, step: 1})
Insert cell
viewof control_rsiPeriod = Inputs.range([1, 200], {label: "RSI Period", value: 14, step: 1})
Insert cell
viewof control_stochasticOscillatorKPeriod = Inputs.range([1, 200], {label: "Stochastic Oscillator K Period", value: 5, step: 1})
Insert cell
viewof control_stochasticOscillatorDPeriod = Inputs.range([1, 200], {label: "Stochastic Oscillator D Period", value: 3, step: 1})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
showMe(`maColumn = fc.indicatorMovingAverage()
.period(control_maLookbackPeriod)
.value(d => d.close)
(data_yahooFiltered)`,{

label: 'How do I calculate an indicator?',
dependencies: {fc, data_yahooFiltered, control_maLookbackPeriod}
}
)
Insert cell
maColumn = fc.indicatorMovingAverage()
.period(control_maLookbackPeriod)
.value(d => d.close)
(data_yahooFiltered)
Insert cell
Insert cell
emaColumn = fc.indicatorExponentialMovingAverage()
.period(9)
.value(d => d.close)
(data_yahooFiltered)
Insert cell
Insert cell
rsiColumn = fc.indicatorRelativeStrengthIndex()
.value(d => d.close)
.period(control_rsiPeriod)
(data_yahooFiltered)
Insert cell
Insert cell
bollingerColumn = fc.indicatorBollingerBands()
.value(d => d.close)
.period(control_bollingerPeriod)
.multiplier(control_bollingerSD)
(data_yahooFiltered)
Insert cell
Insert cell
macdColumn = fc.indicatorMacd()
.value(d => d.close)
.fastPeriod(d => control_macdFastPeriod)
.slowPeriod(d => control_macdSlowPeriod)
.signalPeriod(d => control_macdSignalPeriod)
(data_yahooFiltered)
Insert cell
Insert cell
stochasticOscillatorColumn = fc.indicatorStochasticOscillator()
.lowValue(d => d.low)
.highValue(d => d.high)
.closeValue(d => d.close)
.kPeriod( control_stochasticOscillatorKPeriod )
.dPeriod( control_stochasticOscillatorDPeriod )
(data_yahooFiltered)
Insert cell
Insert cell
data_withFcIndicators = data_yahooFiltered.map( (d, i) => ({
ma: maColumn[i],
ema: emaColumn[i],
macd: macdColumn[i].macd,
macdSignal: macdColumn[i].signal,
macdDivergence: macdColumn[i].divergence,
rsi: rsiColumn[i],
stochasticOscillatorK: stochasticOscillatorColumn[i].k,
stochasticOscillatorD: stochasticOscillatorColumn[i].d,
bollingerUpper: bollingerColumn[i].upper,
bollingerAverage: bollingerColumn[i].average,
bollingerLower: bollingerColumn[i].lower,
...d
}))
Insert cell
Insert cell
Insert cell
Insert cell
currentEthereumPrice = d3.json( "https://www.binance.com/api/v3/ticker/price?symbol=ETHUSDT").then( response => {
return +response.price
} )
Insert cell
Insert cell
Insert cell
Insert cell
data_fearGreedIndex_raw = d3.json("https://api.alternative.me/fng/?limit=0&format=json")
Insert cell
data_fearGreedIndex = aq.from(data_fearGreedIndex_raw.data)
.derive({date: aq.escape(d => new Date(+d.timestamp * 1000))})
.filter ( aq.escape( d =>
d["date"].getFullYear() >= control_timeRange[0] &&
d["date"].getFullYear() <= control_timeRange[1]
))
.derive({value: d => +d.value}) // make numeric
.select('value_classification','date','value')
.rename({value: "fearGreedIndex"})
.rename({value_classification: "fearGreedIndexClassification"})
.objects()
Insert cell
Insert cell
data_withFearGreedIndex = aq.from(data_withFcIndicators)
.join_left(aq.from(data_fearGreedIndex), ["date", "date"])
.objects()
Insert cell
Insert cell
Insert cell
Insert cell
viewof table = Inputs.table(data_withFearGreedIndex)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {Wrangler, op} from "@observablehq/data-wrangler"
Insert cell
import {rangeSlider} from '@mootari/range-slider'
Insert cell
import { SummaryTable } from "@observablehq/summary-table"
Insert cell
fc = require('d3fc')
Insert cell
import {Plot} from "@mkfreeman/plot-tooltip"
Insert cell
Insert cell
Insert cell
<!-- Style tells the cell to put any elements side by side. -->
<!-- You don't need to modify the style. -->
<style>
.controlPanel form{
display: inline-block;
vertical-align: top;
padding: 10px;
max-width: 140px;
}

</style>
Insert cell
import {toc} from "@nebrius/indented-toc"
Insert cell
import {showMe} from "@observablehq/show-me"
Insert cell
import {howTo} from "@clokman/howto"
Insert cell
import { displayCaution } from "@mkfreeman/utilities"
Insert cell
import {imageToDo} from "@clokman/student-blocks"
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