Tucan.Finance (tucan v0.7.0)

Copy Markdown View Source

Financial plots.

This module provides specialized financial plots like candlestick/7.

Summary

Functions

candlestick(plotdata, timestamp, open, high, low, close, opts \\ [])

@spec candlestick(
  plotdata :: Tucan.plotdata(),
  timestamp :: String.t(),
  open :: String.t(),
  high :: String.t(),
  low :: String.t(),
  close :: String.t(),
  opts :: keyword()
) :: VegaLite.t()

Plots a candlestick chart from OHLC data.

timestamp is expected to correspond to the beginning of the chart's period.

Options

  • :volume (String.t/0) - A field with the traded volume of each period. If set the volume is drawn as a bar chart below the prices, colored by the direction of the price.

Data Options

  • :only - A subset of fields to pick from the data. Applicable only if tabular data are provided.

Styling Options

  • :clip (boolean/0) - Whether a mark will be clipped to the enclosing group’s width and height.
  • :fill_opacity (number/0) - The fill opacity of the plotted elements. The default value is 1.
  • :height (pos_integer/0 or :container) - Height of the plot. Can either be the height in pixels or :container to indicate that the height of the plot should be the same as its surrounding container.
  • :title (String.t/0) - The title of the graph
  • :volume_height (pos_integer/0) - The height of the volume chart in pixels, if :volume is set. The default value is 60.
  • :width (pos_integer/0 or :container) - Width of the plot. Can either be the width in pixels or :container to indicate that the width of the plot should be the same as its surrounding container.

Interactivity Options

  • :tooltip (boolean() | :data | :encoding) - The tooltip text string to show upon mouse hover or an object defining which fields should the tooltip be derived from. Can be one of the following:

    • :encoding - all fields from encoding are used
    • :data - all fields of the highlighted data point are used
    • true - same as :encoding
    • false, nil - no tooltip is used
  • :zoomable (boolean/0) - Whether the plot will be zoomable or not. If set to true you will be able to pan and zoom the plot with your mouse. You can reset to the original view with a double click. The default value is false.

Examples

Tucan.Finance.candlestick(:ohlc, "date", "open", "high", "low", "close",
  width: 400,
  tooltip: true
)
|> Tucan.Axes.set_y_title("Price")
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","data":{"url":"https://vega.github.io/editor/data/ohlc.json"},"layer":[{"encoding":{"x":{"field":"date","type":"temporal"},"y":{"axis":{"title":"Price"},"field":"low","scale":{"zero":false},"type":"quantitative"},"y2":{"field":"high","type":"quantitative"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"rule"}},{"encoding":{"color":{"condition":{"test":"datum.open < datum.close","value":"#06982d"},"value":"#ae1325"},"x":{"field":"date","type":"temporal"},"y":{"axis":{"title":"Price"},"field":"open","scale":{"zero":false},"type":"quantitative"},"y2":{"field":"close","type":"quantitative"}},"mark":{"fillOpacity":1,"tooltip":true,"type":"bar"}}],"width":400}

With the traded volume below the prices, here for generated data:

:rand.seed(:exsss, {1, 2, 3})

{data, _close} =
  Enum.map_reduce(Date.range(~D[2024-03-01], ~D[2024-05-31]), 100.0, fn date, previous ->
    open = previous + :rand.normal()
    close = open + 2 * :rand.normal()
    high = max(open, close) + abs(:rand.normal())
    low = min(open, close) - abs(:rand.normal())
    volume = round(1_000_000 * (1 + abs(close - open)) * (0.5 + :rand.uniform()))

    {%{date: date, open: open, high: high, low: low, close: close, volume: volume}, close}
  end)

Tucan.Finance.candlestick(data, "date", "open", "high", "low", "close",
  volume: "volume",
  width: 450,
  height: 200
)
{"$schema":"https://vega.github.io/schema/vega-lite/v5.json","__tucan__":{"types":{"close":"quantitative","date":"temporal","high":"quantitative","low":"quantitative","open":"quantitative","volume":"quantitative"}},"data":{"values":[{"close":100.41191758843303,"date":"2024-03-01","high":102.00767093329348,"low":100.16172954800305,"open":101.37019792251294,"volume":2088223},{"close":101.31868677817555,"date":"2024-03-02","high":101.43049098131448,"low":100.74590019737886,"open":100.87101867118353,"volume":1905009},{"close":100.30660005236946,"date":"2024-03-03","high":101.51840755562667,"low":100.26003768772361,"open":101.1887374150286,"volume":1027856},{"close":101.55691068973559,"date":"2024-03-04","high":104.02728675738797,"low":98.86723254832181,"open":99.5106971327722,"volume":1716922},{"close":102.12817334597233,"date":"2024-03-05","high":104.10470770879883,"low":101.09684552406195,"open":102.59918940643146,"volume":1221328},{"close":100.74957783727719,"date":"2024-03-06","high":102.28579759790779,"low":98.55496167625363,"open":101.67267496080684,"volume":2551611},{"close":109.08128132136359,"date":"2024-03-07","high":110.45322197557574,"low":101.38840258713485,"open":102.05178503668606,"volume":7449972},{"close":104.78042255895869,"date":"2024-03-08","high":110.65532175961087,"low":103.86494993647514,"open":108.88517248280694,"volume":7287803},{"close":104.19792283404846,"date":"2024-03-09","high":105.64136535899348,"low":102.78258370915106,"open":103.46422991072765,"volume":1077229},{"close":103.28209341835498,"date":"2024-03-10","high":107.25584435011152,"low":101.5907940741659,"open":106.7487892477185,"volume":4143503},{"close":106.65527007894197,"date":"2024-03-11","high":107.10884666558987,"low":104.3916297636729,"open":104.5720730924887,"volume":3196195},{"close":104.102624281526,"date":"2024-03-12","high":108.76081930017082,"low":102.65601872571206,"open":107.51997987317047,"volume":4056413},{"close":102.69307428828542,"date":"2024-03-13","high":104.07092273714612,"low":102.01385833503194,"open":103.07490854842376,"volume":1322480},{"close":103.21650399916784,"date":"2024-03-14","high":103.40331490556083,"low":101.18752663092317,"open":101.24354961823427,"volume":2304506},{"close":101.88165362161124,"date":"2024-03-15","high":102.89113350270533,"low":101.8227468905519,"open":102.05532211729852,"volume":766947},{"close":102.64594081210981,"date":"2024-03-16","high":104.23047501203023,"low":99.85502402658274,"open":100.98757206579215,"volume":3792177},{"close":100.74298124914885,"date":"2024-03-17","high":102.05153432606136,"low":99.65085060979354,"open":101.88874434286113,"volume":2526124},{"close":102.42114693349086,"date":"2024-03-18","high":103.98518259716366,"low":101.1255241887103,"open":101.43016622753235,"volume":1623367},{"close":101.36230717453174,"date":"2024-03-19","high":103.39388388832388,"low":100.75848948408931,"open":102.92093236374522,"volume":2249345},{"close":97.38543116343472,"date":"2024-03-20","high":102.73575128113768,"low":96.9013305134508,"open":100.91806177780192,"volume":2803791},{"close":95.40089752521547,"date":"2024-03-21","high":100.05430753891852,"low":93.87160122118517,"open":98.26874179732124,"volume":5090450},{"close":96.33513250871529,"date":"2024-03-22","high":97.3215860475867,"low":95.16817155666737,"open":95.44100658514172,"volume":1753826},{"close":99.00711112111732,"date":"2024-03-23","high":99.01014304313527,"low":97.35294925301497,"open":98.7175941894305,"volume":1534988},{"close":96.22404756360686,"date":"2024-03-24","high":98.75385253932082,"low":95.88358714948698,"open":98.30429455586251,"volume":2948041},{"close":91.89328540554592,"date":"2024-03-25","high":95.0006085735332,"low":91.38172934178698,"open":94.93053104247815,"volume":3406112},{"close":93.07407461704018,"date":"2024-03-26","high":94.3052190246679,"low":89.71231385767263,"open":90.37107317492458,"volume":4515466},{"close":91.2632774663032,"date":"2024-03-27","high":94.01943417107788,"low":90.98137877922441,"open":92.35106458883149,"volume":2144944},{"close":89.63879010847741,"date":"2024-03-28","high":91.66406805869136,"low":88.49473816029533,"open":91.27678463036624,"volume":1875384},{"close":93.4057989033577,"date":"2024-03-29","high":93.5094288070698,"low":90.32974857691657,"open":90.44153108162436,"volume":3757257},{"close":94.9931050802931,"date":"2024-03-30","high":95.74068492365399,"low":93.27806486573854,"open":94.08134028729657,"volume":1385639},{"close":97.11610199530739,"date":"2024-03-31","high":98.48634001755902,"low":95.3724684436332,"open":96.24050911863988,"volume":1948441},{"close":98.71373745615597,"date":"2024-04-01","high":99.63558116632812,"low":95.52532841657693,"open":97.90020541647584,"volume":1379610},{"close":97.86487300879199,"date":"2024-04-02","high":98.48061368461744,"low":96.0587661008047,"open":98.25005955531867,"volume":1083910},{"close":95.92825744794146,"date":"2024-04-03","high":97.84103511061774,"low":95.14103518650167,"open":97.0642761419046,"volume":2394576},{"close":96.51509624221127,"date":"2024-04-04","high":97.13715280340281,"low":95.35842583407874,"open":95.96161855293141,"volume":1634238},{"close":95.58583710607319,"date":"2024-04-05","high":97.84997664800703,"low":95.2586382044234,"open":97.24676529303166,"volume":3527513},{"close":94.73577419352189,"date":"2024-04-06","high":95.70389817673595,"low":93.8018130601899,"open":95.52238229725695,"volume":1953392},{"close":91.20503319654716,"date":"2024-04-07","high":95.0640439583998,"low":90.90230536335864,"open":94.48222404313766,"volume":4159931},{"close":93.21949464399928,"date":"2024-04-08","high":94.52288346271754,"low":90.44843743293555,"open":91.55533814182098,"volume":2506435},{"close":95.10547746344857,"date":"2024-04-09","high":95.69113255877075,"low":93.24153985583288,"open":93.35026570280286,"volume":2691887},{"close":94.87585129921469,"date":"2024-04-10","high":95.66082509358888,"low":93.47152898602283,"open":94.55330417960839,"volume":1722747},{"close":93.52730511148643,"date":"2024-04-11","high":94.78850500635289,"low":91.67453746166814,"open":94.48229816310504,"volume":1430369},{"close":95.88216973424235,"date":"2024-04-12","high":97.6631359389528,"low":93.34512837986391,"open":95.73961607886262,"volume":1414787},{"close":91.82372833370367,"date":"2024-04-13","high":95.26349422194876,"low":91.05107278420363,"open":94.86924455936575,"volume":2374014},{"close":93.72324249275911,"date":"2024-04-14","high":93.7771086393412,"low":91.61945154381112,"open":93.25968872794132,"volume":815446},{"close":93.60494823683325,"date":"2024-04-15","high":95.97227017095807,"low":92.38846272195374,"open":94.99685811683321,"volume":2957054},{"close":94.25444518249819,"date":"2024-04-16","high":94.376514943645,"low":91.23606745336836,"open":93.80525484784883,"volume":1426913},{"close":96.1020590251555,"date":"2024-04-17","high":96.19140167569687,"low":93.62780955394128,"open":94.37261156456503,"volume":2587953},{"close":98.09763900598212,"date":"2024-04-18","high":98.60143421494806,"low":94.3025574935657,"open":95.9881513140957,"volume":1909728},{"close":95.48187635540573,"date":"2024-04-19","high":99.60395393102337,"low":94.80895272186264,"open":96.84566569265525,"volume":2296667},{"close":96.89700026348112,"date":"2024-04-20","high":97.88581142508554,"low":95.60141666162113,"open":96.26823187592005,"volume":1831679},{"close":97.99034424140002,"date":"2024-04-21","high":98.11658962216669,"low":95.73795008471733,"open":96.67933198847149,"volume":1310347},{"close":98.13242106959784,"date":"2024-04-22","high":100.35827007887738,"low":95.80480547519298,"open":95.82366797426614,"volume":2878478},{"close":98.8782189516727,"date":"2024-04-23","high":99.29432961526607,"low":98.08028410622914,"open":98.68733648288612,"volume":1164724},{"close":97.49361944019876,"date":"2024-04-24","high":97.81506710558973,"low":96.42625077508792,"open":97.65713037722833,"volume":1275308},{"close":95.36475286880098,"date":"2024-04-25","high":96.626591957825,"low":93.60685350648022,"open":96.55454361653184,"volume":2451029},{"close":96.75997857547134,"date":"2024-04-26","high":98.40867804222316,"low":96.2586428665286,"open":97.86255726260187,"volume":1301022},{"close":99.29885461752987,"date":"2024-04-27","high":99.61315835121657,"low":95.75170059907511,"open":96.85952401724897,"volume":5049404},{"close":99.33510811272092,"date":"2024-04-28","high":99.71309551358205,"low":98.39284741447729,"open":98.6600615262197,"volume":1472216},{"close":100.90855076550937,"date":"2024-04-29","high":101.62415454153533,"low":100.1339104416178,"open":100.2415969935354,"volume":2134594},{"close":100.04403316130875,"date":"2024-04-30","high":101.01860682488577,"low":99.34697459911985,"open":99.47601335930443,"volume":1034040},{"close":98.73300815284425,"date":"2024-05-01","high":100.78918325649765,"low":97.83975144875674,"open":100.51659220584217,"volume":2834203},{"close":98.93218385836464,"date":"2024-05-02","high":101.01631256729362,"low":97.07593563652262,"open":100.13710828261156,"volume":1547566},{"close":99.26033719503747,"date":"2024-05-03","high":99.58547813227703,"low":98.09551019199272,"open":99.01785372627175,"volume":1723308},{"close":96.97424091652528,"date":"2024-05-04","high":99.41420061556687,"low":96.62352652343992,"open":98.62562029909824,"volume":3552185},{"close":96.22577646085384,"date":"2024-05-05","high":96.42691186121324,"low":95.16634494014816,"open":95.97634771846342,"volume":1758832},{"close":97.47690226064364,"date":"2024-05-06","high":98.24360710565153,"low":95.63126629374962,"open":96.97526212789953,"volume":1410674},{"close":95.08110214805272,"date":"2024-05-07","high":97.17250527807455,"low":94.42097992600571,"open":96.63741805739859,"volume":3124530},{"close":94.03916582657709,"date":"2024-05-08","high":96.04734093578746,"low":92.8564359468603,"open":95.12480138215315,"volume":1883922},{"close":94.04178855091851,"date":"2024-05-09","high":95.10642427457148,"low":93.28665514607263,"open":94.48872924898133,"volume":915589},{"close":89.35682146114955,"date":"2024-05-10","high":94.29914053534527,"low":88.51990924477745,"open":93.87642336016391,"volume":5519283},{"close":86.97170774953184,"date":"2024-05-11","high":91.79773312508328,"low":86.95521779095702,"open":90.98118435813758,"volume":6741553},{"close":86.73229038072404,"date":"2024-05-12","high":88.18679890552312,"low":85.73213722662564,"open":88.11400989590652,"volume":1778728},{"close":84.69690700768845,"date":"2024-05-13","high":86.55382993992434,"low":83.9416108567436,"open":85.93167934171109,"volume":1889155},{"close":87.65053305395516,"date":"2024-05-14","high":88.05566950527108,"low":82.28088238150318,"open":85.58298532265125,"volume":2479862},{"close":85.7205391753754,"date":"2024-05-15","high":88.57382416265945,"low":84.5763120288561,"open":87.71670894431061,"volume":3028761},{"close":85.01464743754548,"date":"2024-05-16","high":86.06794509890308,"low":84.89556885918378,"open":85.78180035808771,"volume":1751262},{"close":83.55201588076208,"date":"2024-05-17","high":87.1839358170998,"low":83.239928535478,"open":86.79891602663794,"volume":4442609},{"close":82.12591552498014,"date":"2024-05-18","high":85.0031699353728,"low":82.06080011358783,"open":84.40370776681438,"volume":4757941},{"close":78.99156519273161,"date":"2024-05-19","high":81.97423954550946,"low":78.75521885740129,"open":81.04234359360935,"volume":3904258},{"close":79.70407031736218,"date":"2024-05-20","high":81.80360738559965,"low":78.32513931423593,"open":79.3495031794355,"volume":1209330},{"close":81.18471262677005,"date":"2024-05-21","high":81.46545206613823,"low":78.0141752734873,"open":79.0514981432559,"volume":4541268},{"close":83.13165347757688,"date":"2024-05-22","high":83.25719921196722,"low":80.88098085567839,"open":80.92041117201452,"volume":3677677},{"close":81.99290831754212,"date":"2024-05-23","high":82.02909049877873,"low":81.2142509444858,"open":81.5554940953196,"volume":1646559},{"close":81.1336072034189,"date":"2024-05-24","high":83.6331234800375,"low":80.2387201624976,"open":82.1740527006906,"volume":1943438},{"close":85.79694778161887,"date":"2024-05-25","high":85.80314466637056,"low":79.06361628311048,"open":80.3098536973688,"volume":9322635},{"close":86.3069080377975,"date":"2024-05-26","high":86.31327323252302,"low":84.98716139917111,"open":85.00827935347537,"volume":2405305},{"close":86.3727570056788,"date":"2024-05-27","high":86.81579705188369,"low":85.42835689195786,"open":86.63228576493455,"volume":1837675},{"close":87.78546611716605,"date":"2024-05-28","high":90.44100185552541,"low":85.0129247846527,"open":86.28009497561078,"volume":2102699},{"close":90.43850604127249,"date":"2024-05-29","high":91.31003350498192,"low":86.4224255471217,"open":87.41821788219958,"volume":3953122},{"close":92.3112637927879,"date":"2024-05-30","high":92.83422350592942,"low":89.59900134904332,"open":89.94450221221021,"volume":2482032},{"close":93.21851353834343,"date":"2024-05-31","high":93.59338281358589,"low":91.30284551563192,"open":91.47632236529188,"volume":3171211}]},"resolve":{"scale":{"x":"shared"}},"vconcat":[{"height":200,"layer":[{"encoding":{"x":{"axis":{"labels":false,"title":null},"field":"date","type":"temporal"},"y":{"axis":{"title":"Price"},"field":"low","scale":{"zero":false},"type":"quantitative"},"y2":{"field":"high","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"rule"}},{"encoding":{"color":{"condition":{"test":"datum.open < datum.close","value":"#06982d"},"value":"#ae1325"},"x":{"axis":{"labels":false,"title":null},"field":"date","type":"temporal"},"y":{"axis":{"title":"Price"},"field":"open","scale":{"zero":false},"type":"quantitative"},"y2":{"field":"close","type":"quantitative"}},"mark":{"fillOpacity":1,"type":"bar"}}],"width":450},{"encoding":{"color":{"condition":{"test":"datum.open < datum.close","value":"#06982d"},"value":"#ae1325"},"x":{"field":"date","type":"temporal"},"y":{"field":"volume","title":"Volume","type":"quantitative"}},"height":60,"mark":"bar","width":450}]}

With :volume set the plot is a vertical concatenation of the prices and the volume, sharing the time axis. The price axis is titled "Price", and functions that expect a single or layered view, e.g. Tucan.Axes.set_y_title/2, cannot be applied to it.