Skip to content

Commit d200ace

Browse files
authored
Merge pull request #3 from QuantForgeOrg/improvement/plots
v0.5.7
2 parents 2dded48 + 52ffffc commit d200ace

19 files changed

+21069
-95
lines changed

CHANGELOG.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,38 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.5.7] - 2025-12-24
9+
10+
### Added
11+
12+
- **Shape Plot Style**
13+
- New `shape` plot style with extensive customization options for technical indicator signals.
14+
- Support for 12 shape types: `circle`, `square`, `diamond`, `triangleup`, `triangledown`, `arrowup`, `arrowdown`, `flag`, `cross`, `xcross`, `labelup`, `labeldown`.
15+
- 6 size presets: `tiny`, `small`, `normal`, `large`, `huge`, `auto`.
16+
- Custom dimensions support with `width` and `height` attributes for non-uniform shapes.
17+
- 5 location modes: `absolute`, `abovebar`, `belowbar`, `top`, `bottom` for flexible positioning.
18+
- Text label support with configurable color and automatic positioning based on location.
19+
- Per-point overrides for all shape attributes (shape, size, color, text, location, dimensions).
20+
- **Documentation**
21+
- Comprehensive plotting system documentation (`/plots`) covering all 7 plot styles.
22+
- Detailed shape plot examples and configuration guide.
23+
- PineScript demo page showing runtime transpilation with PineTS.
24+
- Cross-signal indicator example demonstrating shape plots with EMA crossover signals.
25+
26+
### Changed
27+
28+
- **Build Pipeline Modernization**
29+
- Migrated from UMD-only to hybrid ESM/CJS/UMD build system.
30+
- Added `exports` field in `package.json` for modern bundler support.
31+
- Externalized ECharts dependency - now required as peer dependency.
32+
- Separate ESM (`qfchart.min.es.js`) and UMD (`qfchart.min.browser.js`) bundles.
33+
- Updated all demo pages to include ECharts script tag.
34+
- Improved Rollup configuration for better tree-shaking and bundle optimization.
35+
36+
### Fixed
37+
38+
- Binance provider hotfix for USA users connectivity issues.
39+
840
## [0.5.2] - 2025-12-20
941

1042
### Added

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,23 @@ Currently available plugins :
4949
### Browser (UMD)
5050

5151
```html
52+
<!-- 1. Include ECharts (Required) -->
53+
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
54+
55+
<!-- 2. Include QFChart -->
5256
<script src="https://cdn.jsdelivr.net/npm/@qfo/qfchart/dist/qfchart.min.browser.js"></script>
5357
```
5458

5559
### NPM
5660

5761
```bash
58-
npm install @qfo/qfchart
62+
npm install @qfo/qfchart echarts
5963
```
6064

6165
### Yarn
6266

6367
```bash
64-
yarn add @qfo/qfchart
68+
yarn add @qfo/qfchart echarts
6569
```
6670

6771
## 🚀 Quick Start

docs/data/cross-signal.pine

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@version=6
2+
indicator("EMA Crossover Signals", overlay=true)
3+
4+
// Input parameters
5+
fastLength = input.int(9, "Fast EMA Length", minval=1)
6+
slowLength = input.int(13, "Slow EMA Length", minval=1)
7+
8+
// Calculate EMAs
9+
fastEMA = ta.ema(close, fastLength)
10+
slowEMA = ta.ema(close, slowLength)
11+
12+
// Plot EMAs
13+
plot(fastEMA, "Fast EMA", color=color.blue, linewidth=2)
14+
plot(slowEMA, "Slow EMA", color=color.red, linewidth=2)
15+
16+
// Detect crossovers
17+
bullishCross = ta.crossover(fastEMA, slowEMA)
18+
bearishCross = ta.crossunder(fastEMA, slowEMA)
19+
20+
// Plot buy signals (bullish cross)
21+
plotshape(bullishCross, "Buy Signal", shape.arrowup, location.belowbar,
22+
color=color.green, size=size.normal, text="Buy", textcolor=color.green)
23+
// Plot sell signals (bearish cross)
24+
plotshape(bearishCross, "Sell Signal", shape.arrowdown, location.abovebar,
25+
color=color.red, size=size.small, text="Sell", textcolor=color.red)
26+

docs/demos.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
layout: default
33
title: Demos
4-
nav_order: 5
4+
nav_order: 6
55
permalink: /demos/
66
has_children: false
77
---

docs/demos/basic-01.html

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>QFChart - Demo</title>
77

8-
<!-- QFChart Library (Bundled with ECharts) -->
9-
<script src="https://cdn.jsdelivr.net/npm/@qfo/qfchart/dist/qfchart.min.browser.js"></script>
8+
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
9+
<!-- QFChart Library -->
10+
<script src="../js/qfchart.min.browser.js"></script>
11+
12+
<!-- Dependencies for Data Loading -->
13+
<script src="../js/pinets.dev.browser.js"></script>
1014

1115
<link rel="stylesheet" href="styles.css" />
1216
</head>
@@ -27,9 +31,6 @@ <h1>Basic Demo</h1>
2731
<div id="main-chart"></div>
2832
</div>
2933

30-
<!-- Dependencies for Data Loading -->
31-
<script src="https://cdn.jsdelivr.net/npm/pinets/dist/pinets.min.browser.js"></script>
32-
3334
<script>
3435
// Initialize QFChart
3536
document.addEventListener('DOMContentLoaded', async () => {

docs/demos/full.html

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>QFChart - Demo</title>
77

8+
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
9+
<!-- QFChart Library -->
10+
<script src="../js/qfchart.min.browser.js"></script>
11+
12+
<!-- Dependencies for Data Loading -->
13+
<script src="../js/pinets.dev.browser.js"></script>
814
<link rel="stylesheet" href="styles.css" />
915
</head>
1016

@@ -30,11 +36,6 @@ <h1>Full featured Demo</h1>
3036
<div id="main-chart"><center>Loading...</center></div>
3137
</div>
3238

33-
<!-- QFChart Library (Bundled with ECharts) -->
34-
<script src="https://cdn.jsdelivr.net/npm/@qfo/qfchart/dist/qfchart.min.browser.js"></script>
35-
36-
<!-- Dependencies for Data Loading -->
37-
<script src="https://cdn.jsdelivr.net/npm/pinets/dist/pinets.min.browser.js"></script>
3839
<script src="../js/indicators/sqzmom.js"></script>
3940
<script src="../js/indicators/macd.js"></script>
4041
<script src="../js/indicators/instit-bias.js"></script>

docs/demos/pinescript.html

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>QFChart - PineScript Demo</title>
7+
8+
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
9+
<!-- QFChart Library -->
10+
<script src="../js/qfchart.min.browser.js"></script>
11+
12+
<!-- Dependencies for Data Loading -->
13+
<script src="../js/pinets.dev.browser.js"></script>
14+
<link rel="stylesheet" href="styles.css" />
15+
</head>
16+
17+
<body>
18+
<nav>
19+
<a href="https://github.com/QuantForgeOrg/QFChart" target="_blank">
20+
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
21+
<path
22+
d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"
23+
/>
24+
</svg>
25+
QFChart on GitHub
26+
</a>
27+
</nav>
28+
<div id="container">
29+
<h1>PineScript Demo</h1>
30+
<p>
31+
This demo uses the
32+
<a href="https://github.com/QuantForgeOrg/PineTS" target="_blank">PineTS</a> library to load the market data and calculate multiple
33+
indicators.
34+
</p>
35+
<hr />
36+
<div id="main-chart"><center>Loading...</center></div>
37+
</div>
38+
39+
<script src="../js/indicators/macd.js"></script>
40+
41+
<script>
42+
// Data Loading Helper (Simulating what was in chart.js)
43+
const DATA_LENGTH = 500;
44+
async function getIndicatorData(inficatorCode, tickerId, timeframe = '1w', periods = 500, stime, etime) {
45+
const pineTS = new PineTS(PineTS.Provider.Binance, tickerId, timeframe, periods, stime, etime);
46+
const { result, plots, marketData } = await pineTS.run(inficatorCode);
47+
return { result, plots, marketData };
48+
}
49+
50+
// Load Pine Script source code from file
51+
async function loadPineScript(url) {
52+
const response = await fetch(url);
53+
return await response.text();
54+
}
55+
56+
// Initialize QFChart
57+
document.addEventListener('DOMContentLoaded', async () => {
58+
// Load the Pine Script source code
59+
const crossSignalSource = await loadPineScript('../data/cross-signal.pine');
60+
61+
const promises = [getIndicatorData(crossSignalSource, 'BTCUSDT', 'W', DATA_LENGTH)];
62+
const results = await Promise.all(promises);
63+
64+
const { marketData, plots: crossSignalPlots } = results[1];
65+
66+
// Map Market Data to QFChart OHLCV format
67+
// marketData is array of objects: { openTime, open, high, low, close, volume }
68+
const ohlcvData = marketData.map((k) => ({
69+
time: k.openTime,
70+
open: k.open,
71+
high: k.high,
72+
low: k.low,
73+
close: k.close,
74+
volume: k.volume,
75+
}));
76+
77+
const isMobileDevice = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
78+
79+
// Initialize Chart
80+
const chartContainer = document.getElementById('main-chart');
81+
window.chart = new QFChart.QFChart(chartContainer, {
82+
title: 'BTC/USDT', // Custom title
83+
height: '700px',
84+
padding: 0.2,
85+
databox: {
86+
position: isMobileDevice ? 'floating' : 'right',
87+
},
88+
dataZoom: {
89+
visible: true,
90+
position: 'top',
91+
height: 6,
92+
start: 50,
93+
end: 100,
94+
},
95+
layout: {
96+
mainPaneHeight: '60%',
97+
gap: 5,
98+
},
99+
controls: {
100+
collapse: true,
101+
maximize: true,
102+
fullscreen: true,
103+
},
104+
});
105+
106+
// Set Market Data
107+
chart.setMarketData(ohlcvData);
108+
109+
// Set Indicators
110+
111+
chart.addIndicator('Cross Signal', crossSignalPlots, {
112+
isOverlay: true,
113+
titleColor: '#2962FF',
114+
});
115+
116+
// Register Measure Tool Plugin
117+
const measureTool = new QFChart.MeasureTool();
118+
chart.registerPlugin(measureTool);
119+
120+
// Register Line Tool Plugin
121+
const lineTool = new QFChart.LineTool();
122+
chart.registerPlugin(lineTool);
123+
124+
// Register Fibonacci Tool Plugin
125+
const fibTool = new QFChart.FibonacciTool();
126+
chart.registerPlugin(fibTool);
127+
});
128+
</script>
129+
</body>
130+
</html>

docs/index.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ permalink: /
3232
<div id="main-chart"></div>
3333
</div>
3434

35-
<!-- QFChart Library (Bundled with ECharts) -->
35+
<!-- QFChart Library and Dependencies -->
36+
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
3637
<script src="https://cdn.jsdelivr.net/npm/@qfo/qfchart/dist/qfchart.min.browser.js"></script>
3738

3839
<!-- Dependencies for Data Loading -->
@@ -48,16 +49,20 @@ permalink: /
4849

4950
### Browser (UMD)
5051

51-
Include the bundled script in your HTML file:
52+
Include the ECharts library and QFChart in your HTML file:
5253

5354
```html
55+
<!-- 1. Include ECharts (Required) -->
56+
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
57+
58+
<!-- 2. Include QFChart -->
5459
<script src="https://cdn.jsdelivr.net/npm/@qfo/qfchart/dist/qfchart.min.browser.js"></script>
5560
```
5661

5762
### NPM
5863

5964
```bash
60-
npm install @qfo/qfchart
65+
npm install @qfo/qfchart echarts
6166
```
6267

6368
## Quick Start
@@ -132,6 +137,12 @@ const plots = {
132137
chart.addIndicator('SMA_14', plots, { isOverlay: true });
133138
```
134139

140+
#### Plotting System
141+
142+
QFChart supports multiple plot styles for rendering technical indicators: `line`, `step`, `histogram`, `columns`, `circles`, `cross`, `background`, and `shape`. Each style offers different visualization options and per-point styling capabilities. The `shape` style is particularly powerful, with support for various shapes (arrows, triangles, labels), custom sizes, text labels, and flexible positioning modes.
143+
144+
For detailed information about plot styles, options, and examples, see the [Plotting System Documentation](/plots).
145+
135146
### 5. Real-time Updates (Optional)
136147

137148
For real-time data feeds (e.g., WebSocket), use `updateData()` for optimal performance:
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const crossSignalIndicator = `
2+
//@version=6
3+
indicator("EMA Crossover Signals", overlay=true)
4+
5+
// Input parameters
6+
fastLength = input.int(9, "Fast EMA Length", minval=1)
7+
slowLength = input.int(13, "Slow EMA Length", minval=1)
8+
9+
// Calculate EMAs
10+
fastEMA = ta.ema(close, fastLength)
11+
slowEMA = ta.ema(close, slowLength)
12+
13+
// Plot EMAs
14+
plot(fastEMA, "Fast EMA", color=color.blue, linewidth=2)
15+
plot(slowEMA, "Slow EMA", color=color.red, linewidth=2)
16+
17+
// Detect crossovers
18+
bullishCross = ta.crossover(fastEMA, slowEMA)
19+
bearishCross = ta.crossunder(fastEMA, slowEMA)
20+
21+
// Plot buy signals (bullish cross)
22+
plotshape(bullishCross, "Buy Signal", shape.arrowup, location.belowbar,
23+
color=color.green, size=size.normal, text="Buy", textcolor=color.green)
24+
// Plot sell signals (bearish cross)
25+
plotshape(bearishCross, "Sell Signal", shape.arrowdown, location.abovebar,
26+
color=color.red, size=size.small, text="Sell", textcolor=color.red)
27+
28+
`;

0 commit comments

Comments
 (0)