Last active
April 2, 2023 10:12
-
-
Save dacr/07562724c8e277c96408221e2aef9d6b to your computer and use it in GitHub Desktop.
Visualize DJI historical data - The (mis) behavior of markets : A fractal view of Risk, Ruin and Reward - Benoît Mandelbrot / published by https://github.com/dacr/code-examples-manager #fde7d2a2-d081-4199-8284-1f2474743040/bdefbb9e69906be11ae75dae99fd761b9ff11634
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// summary : Visualize DJI historical data - The (mis) behavior of markets : A fractal view of Risk, Ruin and Reward - Benoît Mandelbrot | |
// keywords : scala, stocks, data, dji, visualize, graph, plotly, mandelbroot, fractal | |
// publish : gist | |
// authors : David Crosson | |
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2) | |
// id : fde7d2a2-d081-4199-8284-1f2474743040 | |
// created-on : 2021-01-30T21:19:17Z | |
// managed-by : https://github.com/dacr/code-examples-manager | |
// execution : scala ammonite script (http://ammonite.io/) - run as follow 'amm scriptname.sc' | |
import $ivy.`com.github.pathikrit::better-files:3.9.1` | |
import $ivy.`org.json4s::json4s-jackson:3.6.10` | |
import $ivy.`org.json4s::json4s-ext:3.6.10` | |
import $ivy.`org.plotly-scala::plotly-render:0.8.2` | |
import better.files._ | |
import org.json4s._ | |
import org.json4s.ext.{JavaTimeSerializers, JavaTypesSerializers} | |
import org.json4s.jackson.JsonMethods.parse | |
import plotly._ | |
import element._ | |
import layout._ | |
import Plotly._ | |
import scala.math._ | |
import java.time.LocalDate | |
import java.time.format.DateTimeFormatter | |
import scala.util.Properties.envOrNone | |
implicit val chosenFormats = DefaultFormats.lossless ++ JavaTimeSerializers.all ++ JavaTypesSerializers.all | |
val djiFile = envOrNone("TMBOM_DJI_JSON").getOrElse("tmbom_dji.json").toFile | |
val dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd") | |
case class Entry(date: LocalDate, open: Double, high: Double, low: Double, close: Double, volume: Option[Long]) { | |
val fdate = dateFormat.format(date) | |
} | |
case class Cell(date: String, value: Double) | |
val entries = { | |
djiFile | |
.lineIterator | |
.to(LazyList) | |
.map(line => parse(line).extract[Entry]) | |
} | |
// ------------------------------------------------------------------------------------ | |
def sign(x: Double) = if (x < 0) -1d else 1d | |
//def symLog(x:Double) = sign(x)*(log10(1+abs(x) / 0.3d)) | |
def symLog(x: Double) = sign(x) * (log10(1 + abs(x)/10)) | |
// https://www.mathworks.com/matlabcentral/fileexchange/57902-symlog | |
// http://blog.originlab.com/visualizing-the-negative-log | |
def variation(a:Entry, b:Entry) = b.close - a.close | |
def variationPercent(a:Entry, b:Entry) = (b.close - a.close)/b.close*100d | |
val closings = entries.map(e => Cell(e.fdate, e.close)) | |
//val deltas = entries.sliding(2, 1).map { case LazyList(a, b) => Cell(b.fdate, variation(a,b)) }.to(LazyList) | |
val deltas = entries.sliding(2, 1).map { case LazyList(a, b) => Cell(b.fdate, variationPercent(a,b)) }.to(LazyList) | |
// Trying a symlog compute as plotly Log scale doesn't support "negatives" values | |
val symLogDeltas = entries.sliding(2, 1).map { case LazyList(a, b) => Cell(b.fdate, symLog(variationPercent(a,b))) }.to(LazyList) | |
val data = Seq( | |
Scatter(closings.map(_.date), closings.map(_.value)) | |
.withName("DJI"), | |
Scatter(deltas.map(_.date), deltas.map(_.value)) | |
.withName("day to day variations") | |
.withLine(Line().withColor(Color.RGBA(50, 50, 50, 0.25))) | |
.withYaxis(AxisReference.Y2), | |
) | |
val dataSymLog = Seq( | |
Scatter(closings.map(_.date), closings.map(_.value)) | |
.withName("DJI"), | |
Scatter(symLogDeltas.map(_.date), symLogDeltas.map(_.value)) | |
.withName("day to day variations") | |
.withLine(Line().withColor(Color.RGBA(50, 50, 50, 0.25))) | |
.withYaxis(AxisReference.Y2), | |
) | |
val classicLayout = | |
Layout() | |
.withHeight(800) | |
.withWidth(1600) | |
.withYaxis( | |
Axis() | |
.withTitle("DJI closing") | |
.withAutorange(true) | |
.withSide(Side.Left)) | |
.withTitle("Dow Jones Historical Analysis") | |
.withYaxis2( | |
Axis() | |
.withTitle("DJI day to day variation") | |
.withAutorange(true) | |
.withOverlaying(AxisAnchor.Y) | |
.withSide(Side.Right) | |
) | |
val logLayout = | |
Layout() | |
.withHeight(800) | |
.withWidth(1600) | |
.withYaxis( | |
Axis() | |
.withTitle("DJI closing") | |
.withAutorange(true) | |
.withSide(Side.Left) | |
.withType(AxisType.Log) | |
) | |
.withTitle("Dow Jones Historical Analysis (logarithmic)") | |
.withYaxis2( | |
Axis() | |
.withTitle("DJI day to day variation") | |
.withAutorange(true) | |
.withSide(Side.Right) | |
.withOverlaying(AxisAnchor.Y) | |
//.withType(AxisType.Log) // SHIT PLOTLY DOESN'T SUPPORT SYMLOG !!!! :( | |
) | |
plot("plot-classic.html", data, classicLayout, openInBrowser = true, addSuffixIfExists = true) | |
plot("plot-logarithmic.html", dataSymLog, logLayout, openInBrowser = true, addSuffixIfExists = true) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment