Public
Edited
Nov 12, 2023
Insert cell
Insert cell
Insert cell
len = 5
Insert cell
testData = [348.10, 337.34, 334.29, 331.85, 326.81, 325.26, 323.38, 333.68, 335.94, 335.4, 332.58, 328.39].slice(0)
Insert cell
x = ra.rolling(
{window: len * 2, partial: false},
arr => {
const emaVals = R.take(len, arr)
const sma = arr.slice(len)

return {data: emaVals, sma: R.mean(sma)}
},
R.take(len * 2 + 2, testData)
)
.filter(val => val)
Insert cell
Insert cell
nj.arange(5).reshape(5, 1).toString()
Insert cell
Shape = daggy.taggedSum('Shape', {
// Square :: (Coord, Coord) -> Shape
Square: ['topLeft', 'bottomRight'],

// Circle :: (Coord, Number) -> Shape
Circle: ['centre', 'radius']
})
Insert cell
List = daggy.taggedSum('List', {
Cons: ['head', 'tail'], Nil: []
})
Insert cell
List.from = function (xs) {
return xs.reduceRight(
(acc, x) => List.Cons(x, acc),
List.Nil
)
}
Insert cell
List.prototype.toArray = function () {
return this.cata({
Cons: (x, acc) => [
x, ... acc.toArray()
],

Nil: () => []
})
}
Insert cell
rsi('close', 14, bars)
Insert cell
ema('close', 21, bars.slice(3))
Insert cell
Insert cell
rsi = (source, len, data) => {
const values = R.take(len, ra.getCol(source, data)).reverse()
let gain = [];
let loss = []
for (let i = 1; i < len; i++) {
gain.push(Math.max(0, values[i] - values[i - 1]))
loss.push(Math.abs(Math.min(0, values[i] - values[i - 1])))
}

const avgGain = ema(null, len, gain.reverse())
const avgLoss = ema(null, len, loss.reverse())

const relativeStrength = avgGain / avgLoss;
return 100.0 - (100.0 / (1 + relativeStrength))
}
Insert cell
ema = (source, len, data) => {
const values = source ? R.take(len, ra.getCol(source, data)).reverse() : data.reverse()
const alpha = 2 / (len + 1)
console.log(values)

let ema = values[0]
for (let i = 1; i < len; i++) {
ema = alpha * values[i] + ((1 - alpha) * ema)
}

return ema
}
Insert cell
mm = (source = 'close', len = 20, data) => {
const mult = 1.5
// Calculate BB
const basis = sma(source, len, data)
const dev = mult * stdev(source, len, data)
const upperBB = basis + dev
const lowerBB = basis - dev

// Calculate KC
const ma = sma(source, len, data)
const range = tr(data)
const rangema = sma(null, len, range)
const upperKC = ma + rangema * mult
const lowerKC = ma - rangema * mult

const sqzOn = (lowerBB > lowerKC) && (upperBB < upperKC)
const sqzOff = (lowerBB < lowerKC) && (upperBB > upperKC)
const noSqz = (sqzOn == false) && (sqzOff == false)

const avgValue = avg('close', len, data)
const val = linreg(null, len, data.map((b, idx) => b.close - avgValue[idx]))
return { val }
}
Insert cell
sma = (source, len, data) => {
if (data.length < len) {
throw new Error(`data.length must be bigger then ${len}`)
}
const values = source ? R.pluck(source)(data) : data
return R.mean(R.take(len, values))
}
Insert cell
stdev = (source, len, data) => {
if (data.length < len) {
throw new Error(`data.length must be at least ${len + 1}`)
}

const values = R.take(len, R.pluck(source)(data))
return ss.standardDeviation(values)
}
Insert cell
tr = (data) => {
const res = ra.rolling(
{ window: 2, partial: false },
([yesterday, today]) => ra.max([
today.high - today.low,
Math.abs(today.high - yesterday.close),
Math.abs(today.low - yesterday.close)
]),
[...data].reverse()
)
return res.reverse()
}
Insert cell
avg = (source, len, data) => {
const res = ra.rolling(
{ window: len, partial: false },
(arr) => {
const h = highest('high', len, arr)
const l = lowest('low', len, arr)
return R.mean([R.mean([h, l]), sma(source,len, arr)])
},
[...data].reverse()
)
return R.take(len, res.reverse())
}
Insert cell
highest = (source = 'close', len = 5, data) => {
if (data.length < len) {
throw new Error(`data.length must be bigger then ${len}`)
}

const arr = R.take(len, ra.getCol(source, data))
return Math.max(...arr)
}
Insert cell
lowest = (source = 'close', len = 5, data) => {
if (data.length < len) {
throw new Error(`data.length must be bigger then ${len}`)
}

const arr = R.take(len, ra.getCol(source, data))
return Math.min(...arr)
}
Insert cell
linreg = (source, len = 5, data) => {
const newData = source ? ra.getCol(source, data) : data
const values = R.take(len, newData)
.reverse()
.map((val, idx) => {
return [idx, val]
})

const { m, b } = ss.linearRegression(values)
return b + m * (len - 1)
}
Insert cell
Insert cell
R = import("https://cdn.skypack.dev/ramda@0.28.0")
Insert cell
ss = import("https://cdn.skypack.dev/simple-statistics@7.8.3")
Insert cell
ra = import("https://cdn.skypack.dev/ramda-analytics@0.2.1")
Insert cell
nj = import("https://cdn.skypack.dev/numjs@0.16.1").then(x => x.default)
Insert cell
daggy = import("https://cdn.skypack.dev/daggy@1.5.0").then(x => x.default)
Insert cell
dayjs = import("https://cdn.skypack.dev/dayjs@1.11.8").then(x => x.default)
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