A candlestick chart image generator (TradingView style) for Delphi and Free Pascal. It takes plain data arrays and produces a PNG / JPEG / BMP picture of the chart. There is no visual component and no mouse interaction, and it does not depend on any graphics framework (VCL / LCL / FMX / GDI). It works in console programs, services and bots (for example, sending a chart to Telegram).
- Candles, hollow candles, OHLC bars, line, area and Heikin-Ashi
- Volume histogram drawn at the bottom of the main pane
- Any number of separate panes below the chart (RSI, MACD, Stochastic, ...) fed with your own arrays
- Series types: line, step line, histogram, area, dots; horizontal levels (such as 30/70 on RSI), colored bands, and fills between two series (such as Bollinger Bands)
- Drawing tools anchored by time and price, not by candle index: trend line, ray, extended line, horizontal line, horizontal ray, vertical line, rectangle, ellipse, parallel channel, Fibonacci retracement, arrow, text, markers (arrow up/down, circle, square, diamond) and polylines/polygons
- Linear or logarithmic price scale, last-price tag, TradingView-style OHLC legend
- Weighted time axis labels (year > month > day > hour > minute) and a time zone offset
- Dark and light themes, HiDPI output with
Scale := 2 - Fully anti-aliased drawing through a built-in software rasterizer and an embedded vector font (Inter), so output does not depend on fonts installed on the machine
| File | Purpose |
|---|---|
source/ChartForge4D.Types.pas |
Types, colors, themes, date/time and number helpers |
source/ChartForge4D.Raster.pas |
Software canvas and anti-aliased drawing primitives |
source/ChartForge4D.FontData.pas |
Embedded vector font data (generated) |
source/ChartForge4D.Text.pas |
Text renderer (replaceable) |
source/ChartForge4D.Image.pas |
PNG, JPEG and BMP encoders (no VCL needed) |
source/ChartForge4D.Scales.pas |
Scale math, price ticks and time ticks |
source/ChartForge4D.Model.pas |
Data model: candles, series, panes, drawings |
source/ChartForge4D.Chart.pas |
The main class, TCFChart |
source/ChartForge4D.Indicators.pas |
Optional helpers: SMA, EMA, RSI, MACD, Bollinger, ATR, Stochastic |
examples/Delphi/ |
Self-contained example for Delphi (CFDemo.dpr) |
examples/FreePascal/ |
Self-contained example for Free Pascal / Lazarus (CFDemo.lpr) |
LICENSE, NOTICE |
Apache License 2.0 and third-party notice |
- Delphi XE2 or newer: open
examples/Delphi/CFDemo.dpr, or add thesourcefolder to your project's search path. - Free Pascal 3.0 or newer: run
fpc -Mdelphi -Fu../../source CFDemo.lprinsideexamples/FreePascal(or open the file in Lazarus and add../../sourceto the unit search path). - To avoid the ZLib dependency, define
CF_NO_ZLIBin the conditional defines (PNG files are then written without compression).
uses ChartForge4D.Types, ChartForge4D.Model, ChartForge4D.Chart, ChartForge4D.Indicators;
var
Chart: TCFChart;
Rsi: TCFDoubleArray;
PRsi: TCFPane;
begin
Chart := TCFChart.Create(1600, 900);
try
Chart.Title := 'BTCUSDT 1h';
Chart.SetVisibleBars(150); // show the last 150 candles
// Arrays: unix time (seconds) + Open/High/Low/Close/Volume
Chart.SetData(Times, Opens, Highs, Lows, Closes, Volumes);
// Overlay on the price pane (nil = main pane)
Chart.AddLineSeries(nil, 'MA 20', CFSMA(Closes, 20), CFRGB(255, 152, 0));
// A separate pane for RSI
Rsi := CFRSI(Closes, 14); // or an array you calculated yourself
PRsi := Chart.AddPane('RSI (14)', 1.0);
PRsi.SetFixedRange(0, 100);
PRsi.AddLevel(70, CFARGB(150, 120, 123, 134));
PRsi.AddLevel(30, CFARGB(150, 120, 123, 134));
Chart.AddLineSeries(PRsi, '', Rsi, CFRGB(126, 87, 194)).ShowLastValue := True;
// Drawings: start and end are (time, price) pairs
Chart.AddTrendLine(T1, P1, T2, P2, CFRGB(41, 98, 255), 2.0);
Chart.SaveToFile('chart.png'); // or .jpg (optional quality) or .bmp
finally
Chart.Free;
end;
end;- Time is an Int64 unix timestamp. The default unit is seconds; for milliseconds (for example
Binance data) set
Chart.TimeUnit := tuMillisecondsbefore any other call. Candle times must be strictly increasing. - If you have
TDateTimevalues, useSetDataDateTime(assumed to be UTC) orCFDateTimeToUnix. - Volume is optional (there is a
SetDataoverload without it). - Indicator series are arrays with one value per candle. Use
CFNaNfor missing values (for example the warm-up period). If your array starts at candlek, setSeries.IndexOffset := k. - If indicator points have their own timestamps, use
AddTimedSeries(Pane, Kind, Name, Times, Values, Color). - A candle whose Open, High, Low or Close is NaN is skipped (it leaves a gap).
Every Add... method returns a TCFDrawing so you can change its color, width, Style, Text and
so on afterwards. The last parameter of each method is APane: nil means the main pane, or pass an
indicator pane (for example a trend line on RSI, where the "price" is the RSI value).
| Method | Anchors |
|---|---|
AddTrendLine, AddRay, AddExtendedLine |
2 points (time, price) |
AddHorizontalLine, AddHorizontalRay |
price (plus a start time for the ray) |
AddVerticalLine |
time (across all panes or a single pane) |
AddRectangle, AddEllipse |
two opposite corners |
AddParallelChannel |
base line (points 1 and 2) plus one point on the parallel line |
AddFibRetracement |
2 points (level 0 at point 2, level 1 at point 1) |
AddArrow, AddText, AddMarker, AddPolyline |
see the method declarations |
Times that fall between two candles, or after the last candle (the future), are handled: the library interpolates between candles and extrapolates beyond the last one using the typical candle interval.
| Property | Description |
|---|---|
Theme |
Colors: CFDarkTheme / CFLightTheme, or change individual fields |
ChartStyle |
chCandles, chHollowCandles, chOHLC, chLine, chArea, chHeikinAshi |
ShowVolume, VolumeHeight |
Volume histogram |
SetVisibleBars / SetVisibleIndexRange / SetVisibleTimeRange |
Visible range |
RightPadBars |
Empty space on the right (room for drawings in the future) |
TimeZoneOffsetMinutes |
Time zone used for the time axis labels |
LogScale |
Logarithmic scale for the price pane |
PricePrecision |
Number of decimals (default: detected from the data) |
Scale, FontSize |
Size of all elements; for HiDPI output use Scale := 2 and double Width/Height |
Watermark, Title |
Background text and legend title |
Panes (TCFPane): HeightWeight, SetFixedRange, LogScale, AddLevel, AddBand,
AddFill (fill between two series), Decimals.
- The built-in font supports ASCII only. For other scripts, derive from
TCFTextRendererand assign your own renderer toChart.TextRenderer. - JPEG is written as baseline 4:4:4; PNG is always RGB without transparency.
- "Fill between two series" requires both series to be aligned to candle indexes (not timed series).
Created by Shaahin Ashayeri - https://github.com/DelphiMan68
ChartForge4D is released under the Apache License, Version 2.0. See LICENSE and NOTICE.
The embedded vector font is derived from Inter (SIL Open Font License 1.1).
The license text is in docs/Inter-OFL-LICENSE.txt.
