Skip to content

Normalized Stock Prices

What is the return on investment for different days? Hover over the chart to normalize the stock prices for the percentage return on a given day. A nearestX interactor selects the nearest date, and parameterized expressions reactively update in response.

Loading Example...

Specification

js
import * as vg from "@uwdata/vgplot";

await vg.coordinator().exec([
  vg.loadParquet("stocks", "data/stocks.parquet"),
  `CREATE TEMP TABLE IF NOT EXISTS labels AS SELECT MAX(Date) as Date, ARGMAX(Close, Date) AS Close, Symbol FROM stocks GROUP BY Symbol`
]);

const $point = vg.Param.value(new Date("2013-05-13"));

export default vg.plot(
  vg.ruleX({x: $point}),
  vg.textX({x: $point, text: $point, frameAnchor: "top", lineAnchor: "bottom", dy: -7}),
  vg.text(
    vg.from("labels"),
    {
      x: "Date",
      y: vg.sql`Close / (SELECT MAX(Close) FROM stocks WHERE Symbol = source.Symbol AND Date = ${$point})`,
      dx: 2,
      text: "Symbol",
      fill: "Symbol",
      textAnchor: "start"
    }
  ),
  vg.lineY(
    vg.from("stocks"),
    {
      x: "Date",
      y: vg.sql`Close / (SELECT MAX(Close) FROM stocks WHERE Symbol = source.Symbol AND Date = ${$point})`,
      stroke: "Symbol"
    }
  ),
  vg.nearestX({as: $point}),
  vg.yScale("log"),
  vg.yDomain([0.2, 6]),
  vg.yGrid(true),
  vg.xLabel(null),
  vg.yLabel(null),
  vg.yTickFormat("%"),
  vg.width(680),
  vg.height(400),
  vg.marginRight(35)
);
yaml
meta:
  title: Normalized Stock Prices
  description: >
    What is the return on investment for different days?
    Hover over the chart to normalize the stock prices for the percentage
    return on a given day.
    A `nearestX` interactor selects the nearest date, and parameterized
    expressions reactively update in response.
data:
  stocks: { file: data/stocks.parquet }
  labels: SELECT MAX(Date) as Date, ARGMAX(Close, Date) AS Close, Symbol
          FROM stocks GROUP BY Symbol
params:
  point: { date: '2013-05-13' }
plot:
- mark: ruleX
  x: $point
- mark: textX
  x: $point
  text: $point
  frameAnchor: top
  lineAnchor: bottom
  dy: -7
- mark: text
  data: { from: labels }
  x: Date
  y: { sql: Close / (SELECT MAX(Close) FROM stocks WHERE Symbol = source.Symbol AND Date = $point) }
  dx: 2
  text: Symbol
  fill: Symbol
  textAnchor: start
- mark: lineY
  data: { from: stocks }
  x: Date
  y: { sql: Close / (SELECT MAX(Close) FROM stocks WHERE Symbol = source.Symbol AND Date = $point) }
  stroke: Symbol
- select: nearestX
  as: $point
yScale: log
yDomain: [0.2, 6]
yGrid: true
xLabel: null
yLabel: null
yTickFormat: '%'
width: 680
height: 400
marginRight: 35
json
{
  "meta": {
    "title": "Normalized Stock Prices",
    "description": "What is the return on investment for different days? Hover over the chart to normalize the stock prices for the percentage return on a given day. A `nearestX` interactor selects the nearest date, and parameterized expressions reactively update in response.\n"
  },
  "data": {
    "stocks": {
      "file": "data/stocks.parquet"
    },
    "labels": "SELECT MAX(Date) as Date, ARGMAX(Close, Date) AS Close, Symbol FROM stocks GROUP BY Symbol"
  },
  "params": {
    "point": {
      "date": "2013-05-13"
    }
  },
  "plot": [
    {
      "mark": "ruleX",
      "x": "$point"
    },
    {
      "mark": "textX",
      "x": "$point",
      "text": "$point",
      "frameAnchor": "top",
      "lineAnchor": "bottom",
      "dy": -7
    },
    {
      "mark": "text",
      "data": {
        "from": "labels"
      },
      "x": "Date",
      "y": {
        "sql": "Close / (SELECT MAX(Close) FROM stocks WHERE Symbol = source.Symbol AND Date = $point)"
      },
      "dx": 2,
      "text": "Symbol",
      "fill": "Symbol",
      "textAnchor": "start"
    },
    {
      "mark": "lineY",
      "data": {
        "from": "stocks"
      },
      "x": "Date",
      "y": {
        "sql": "Close / (SELECT MAX(Close) FROM stocks WHERE Symbol = source.Symbol AND Date = $point)"
      },
      "stroke": "Symbol"
    },
    {
      "select": "nearestX",
      "as": "$point"
    }
  ],
  "yScale": "log",
  "yDomain": [
    0.2,
    6
  ],
  "yGrid": true,
  "xLabel": null,
  "yLabel": null,
  "yTickFormat": "%",
  "width": 680,
  "height": 400,
  "marginRight": 35
}