Search code examples
vega-litevega

colorize a candlestick chart using vega-lite


I'm using vega-lite and I'm following this code

https://vega.github.io/vega-lite/examples/layer_candlestick.html

the problem happens when I add new curves, as some moving averages, with the original code I can't colorize my MA's....so I move the color condition (to draw green and red candles) to inside the mark/bar object, now my MA's are colored correctly but my bars looks terrible


{
  "data": {
    "name": "source",
    "values": [
      {
        "Volume BTC": "356.11",
        "ma80": 11964.9857421875,
        "Volume USD": "4419589.41",
        "Low": "12371",
        "High": "12432",
        "ma200": 11767.991997070312,
        "Date": "2020-08-17T17:00:00.000Z",
        "ma60": 12009.80966796875,
        "Date2": "2020-08-17 05-PM",
        "Close": "12395",
        "Symbol": "BTCUSD",
        "Open": "12393.07"
      },
      {
        "Volume BTC": "626.08",
        "ma80": 11971.631115722656,
        "Volume USD": "7767650.77",
        "Low": "12360",
        "High": "12490",
        "ma200": 11773.517348632813,
        "Date": "2020-08-17T16:00:00.000Z",
        "ma60": 12020.977506510417,
        "Date2": "2020-08-17 04-PM",
        "Close": "12393.07",
        "Symbol": "BTCUSD",
        "Open": "12441"
      },
      {
        "Volume BTC": "2014.02",
        "ma80": 11978.585119628906,
        "Volume USD": "24858783.37",
        "Low": "12148",
        "High": "12490",
        "ma200": 11779.015346679687,
        "Date": "2020-08-17T15:00:00.000Z",
        "ma60": 12033.11083984375,
        "Date2": "2020-08-17 03-PM",
        "Close": "12441",
        "Symbol": "BTCUSD",
        "Open": "12182"
      },
      {
        "Volume BTC": "606.31",
        "ma80": 11982.885119628907,
        "Volume USD": "7384157.12",
        "Low": "12110",
        "High": "12218",
        "ma200": 11783.055346679688,
        "Date": "2020-08-17T14:00:00.000Z",
        "ma60": 12040.26083984375,
        "Date2": "2020-08-17 02-PM",
        "Close": "12182",
        "Symbol": "BTCUSD",
        "Open": "12141"
      },
      {
        "Volume BTC": "3616.55",
        "ma80": 11986.589624023438,
        "Volume USD": "43475507.61",
        "Low": "11675",
        "High": "12222",
        "ma200": 11787.180346679688,
        "Date": "2020-08-17T13:00:00.000Z",
        "ma60": 12046.394173177083,
        "Date2": "2020-08-17 01-PM",
        "Close": "12141",
        "Symbol": "BTCUSD",
        "Open": "11913.52"
      },
      {
        "Volume BTC": "170.68",
        "ma80": 11987.083618164062,
        "Volume USD": "2034739.24",
        "Low": "11889.8",
        "High": "11938",
        "ma200": 11790.362944335937,
        "Date": "2020-08-17T12:00:00.000Z",
        "ma60": 12048.219498697918,
        "Date2": "2020-08-17 12-PM",
        "Close": "11913.52",
        "Symbol": "BTCUSD",
        "Open": "11937"
      },
      {
        "Volume BTC": "150.11",
        "ma80": 11988.058618164063,
        "Volume USD": "1788458.22",
        "Low": "11878",
        "High": "11939.35",
        "ma200": 11793.532944335937,
        "Date": "2020-08-17T11:00:00.000Z",
        "ma60": 12050.869498697917,
        "Date2": "2020-08-17 11-AM",
        "Close": "11937",
        "Symbol": "BTCUSD",
        "Open": "11878"
      },
      {
        "Volume BTC": "63.25",
        "ma80": 11988.063623046875,
        "Volume USD": "752225.85",
        "Low": "11875.82",
        "High": "11920",
        "ma200": 11796.366845703125,
        "Date": "2020-08-17T10:00:00.000Z",
        "ma60": 12052.536165364583,
        "Date2": "2020-08-17 10-AM",
        "Close": "11878",
        "Symbol": "BTCUSD",
        "Open": "11878"
      },
      {
        "Volume BTC": "67.36",
        "ma80": 11988.501123046875,
        "Volume USD": "801273.13",
        "Low": "11877.24",
        "High": "11915",
        "ma200": 11799.541845703125,
        "Date": "2020-08-17T09:00:00.000Z",
        "ma60": 12054.919498697916,
        "Date2": "2020-08-17 09-AM",
        "Close": "11878",
        "Symbol": "BTCUSD",
        "Open": "11891.61"
      },
      {
        "Volume BTC": "154.6",
        "ma80": 11988.8548828125,
        "Volume USD": "1838105.41",
        "Low": "11829",
        "High": "11907",
        "ma200": 11802.309897460938,
        "Date": "2020-08-17T08:00:00.000Z",
        "ma60": 12057.496337890625,
        "Date2": "2020-08-17 08-AM",
        "Close": "11891.61",
        "Symbol": "BTCUSD",
        "Open": "11829"
      }
    ]
  },
  "height": 200,
  "width": 300,
  "scales": [
    {
      "name": "volume",
      "type": "linear",
      "round": true,
      "nice": false,
      "domain": {"data": "source", "field": "Volume"},
      "range": [4, 800]
    }
  ],
  "encoding": {
    "x": {
      "field": "Date",
      "type": "temporal",
      "axis": {"format": "%m/&d", "labelAngle": -45}
    },
    "y": {
      "type": "quantitative",
      "scale": {"zero": false},
      "axis": {"title": "price"}
    }
  },
  "layer": [
    {
      "mark": "rule",
      "encoding": {"y": {"field": "Low"}, "y2": {"field": "High"}}
    },
    {
      "mark": {"type": "line", "color": "red", "size": 2},
      "encoding": {"y": {"field": "ma200", "title": "ma200"}}
    },
    {
      "mark": {"type": "line", "color": "blue", "size": 2},
      "encoding": {"y": {"field": "ma60", "title": "ma60"}}
    },
    {
      "mark": {"type": "line", "color": "yellow", "size": 2},
      "encoding": {"y": {"field": "ma80", "title": "ma80"}}
    },
    {
      "mark": {
        "type": "bar",
        "color": {
          "condition": {"test": "datum.Open < datum.Close", "value": "#06982d"},
          "value": "#ae1325"
        }
      },
      "encoding": {"y": {"field": "Open"}, "y2": {"field": "Close"}}
    }
  ]
}

here is a minimal sample, what would the best way to colorize my candles and moving averages? thanks!


Solution

  • The issue is that you put your color condition in the mark properties, while it should be within the encodings. Mark properties are intended for constant values that are shared between all marks in the layer.

    Your bar layer should look like this:

        {
          "mark": "bar",
          "encoding": {
            "y": {"field": "Open"},
            "y2": {"field": "Close"},
            "color": {
              "condition": {"test": "datum.Open < datum.Close", "value": "#06982d"},
              "value": "#ae1325"
            }
          }
        }
    

    The result looks like this (view in editor):

    enter image description here

    Side-note, you have a top-level "scales" entry, which is not valid Vega-Lite (it is a specification used in Vega); it should probably be removed.