Skip to content

Commit bf20a0b

Browse files
authored
Merge pull request #8 from QuantForgeOrg/dev
v0.6.4
2 parents 81259d5 + 08d56c9 commit bf20a0b

File tree

15 files changed

+1531
-20553
lines changed

15 files changed

+1531
-20553
lines changed

.pidTmp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
40856
2+
--port

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ 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.6.4] - 2026-01-13
9+
10+
### Added
11+
12+
- **Plot Fill Method**: Implemented `plot.fill()` method to fill the area between two plot lines with customizable colors and transparency, matching Pine Script's `fill()` functionality.
13+
- **Per-Plot Overlay Option**: Added support for overlay option per plot, allowing individual plots to be configured as overlay or separate pane indicators.
14+
- **Default Color Support**: Added default color handling for plots when color is not explicitly specified.
15+
16+
### Fixed
17+
18+
- **Plot Shape Y-Axis Alignment**: Fixed y-axis alignment issues with `plotshape` plots to ensure proper positioning relative to price bars.
19+
- **Plot Styles Compatibility**: Hotfix for plot styles compatibility issues to ensure consistent rendering across different plot types.
20+
821
## [0.6.1] - 2025-01-03
922

1023
### Added

docs/data/bb.pine

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@version=6
2+
indicator(shorttitle="BB", title="Simple Bollinger Bands", overlay=true, timeframe="", timeframe_gaps=true)
3+
length = 20
4+
src = close
5+
mult = 2.0
6+
basis = ta.sma(src, length)
7+
dev = mult * ta.stdev(src, length)
8+
upper = basis + dev
9+
lower = basis - dev
10+
offset = input.int(0, "Offset", minval = -500, maxval = 500, display = display.data_window)
11+
plot(basis, "_plot", color=#2962FF, offset = offset)
12+
plot1 = plot(upper, "Upper", color=#F23645, offset = offset)
13+
plot2 = plot(lower, "Lower", color=#089981, offset = offset)
14+
fill(plot1, plot2, title = "Background", color=color.rgb(33, 150, 243, 85))

docs/demos/bb.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.dev.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+
31+
<p>
32+
This demo loads and execute native pine script from this file
33+
<a href="../data/cross-signal.pine" target="_blank">cross-signal.pine</a>, then uses
34+
<a href="https://github.com/QuantForgeOrg/PineTS" target="_blank">PineTS</a> to execute it and get the results.<br />
35+
The results are then used by QFChart to render the chart.
36+
</p>
37+
<hr />
38+
<div id="main-chart"><p class="loading">Loading Data ...</p></div>
39+
</div>
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 bbSource = await loadPineScript('../data/bb.pine');
60+
61+
const result = await getIndicatorData(bbSource, 'BTCUSDT', 'W', DATA_LENGTH);
62+
63+
const { marketData, plots: bbPlots } = result;
64+
console.log(bbPlots);
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: '600px',
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', bbPlots, {
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/examples/fill-plot-example.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Fill Plot Style Example
2+
3+
The `fill` plot style allows you to fill the area between two existing plots with a color.
4+
5+
## Usage
6+
7+
```javascript
8+
// Example: Bollinger Bands with filled area
9+
const bbIndicator = {
10+
id: 'BB',
11+
plots: {
12+
upper: {
13+
data: upperBandData,
14+
options: {
15+
style: 'line',
16+
color: '#2196F3',
17+
linewidth: 1,
18+
},
19+
},
20+
basis: {
21+
data: basisData,
22+
options: {
23+
style: 'line',
24+
color: '#FFC107',
25+
linewidth: 2,
26+
},
27+
},
28+
lower: {
29+
data: lowerBandData,
30+
options: {
31+
style: 'line',
32+
color: '#2196F3',
33+
linewidth: 1,
34+
},
35+
},
36+
// Fill between upper and lower bands
37+
fill: {
38+
plot1: 'upper', // Reference to upper plot
39+
plot2: 'lower', // Reference to lower plot
40+
options: {
41+
style: 'fill',
42+
color: 'rgba(33, 150, 243, 0.2)', // Semi-transparent blue
43+
},
44+
},
45+
},
46+
};
47+
48+
chart.addIndicator('BB', bbIndicator.plots, {
49+
overlay: true,
50+
titleColor: '#2196F3',
51+
});
52+
```
53+
54+
## Color Formats
55+
56+
The fill color supports multiple formats:
57+
58+
### 1. Hex Color
59+
60+
```javascript
61+
options: {
62+
style: 'fill',
63+
color: '#FF5722'
64+
}
65+
```
66+
67+
### 2. Color Name
68+
69+
```javascript
70+
options: {
71+
style: 'fill',
72+
color: 'green'
73+
}
74+
```
75+
76+
### 3. RGBA (with transparency)
77+
78+
```javascript
79+
options: {
80+
style: 'fill',
81+
color: 'rgba(255, 87, 34, 0.3)' // 30% opacity
82+
}
83+
```
84+
85+
## Requirements
86+
87+
- Both `plot1` and `plot2` must reference existing plot IDs within the same indicator
88+
- The referenced plots must be processed before the fill plot (non-fill plots are always processed first)
89+
- Both plots must be on the same pane for the fill to render correctly
90+
- If either plot has a `null` value at any point, the fill will not render for that segment
91+
92+
## Notes
93+
94+
- Fill plots render at `z: -5`, meaning they appear **behind** lines but **above** background plots
95+
- Fill plots do NOT have a `data` array - they derive their data from the referenced plots
96+
- The fill is rendered as smooth polygons connecting consecutive points (like TradingView's Bollinger Bands)
97+
- Gaps in either line are automatically handled - no fill is rendered for those segments
98+
- **Opacity Handling:**
99+
- If using `rgba()` format, the alpha value is extracted and used as opacity
100+
- For hex or named colors, default opacity is `0.3` (30% transparent)
101+
- Example: `rgba(33, 150, 243, 0.95)` uses 95% opacity
102+
- Example: `#2196F3` uses 30% opacity by default

0 commit comments

Comments
 (0)