use common williams market structure calcs

This commit is contained in:
Dobromir Popov
2025-10-24 12:30:17 +03:00
parent bd95ff610c
commit 42bf91b735
3 changed files with 260 additions and 162 deletions

View File

@@ -149,87 +149,117 @@ class ChartManager {
// Prepare chart data with pivot bounds
const chartData = [candlestickTrace, volumeTrace];
// Add pivot markers from chart data (last high/low for each level L1-L5)
// Add pivot markers from chart data
const shapes = [];
const annotations = [];
const pivotDots = { x: [], y: [], text: [], marker: { color: [], size: [], symbol: [] }, mode: 'markers', hoverinfo: 'text', showlegend: false };
if (data.pivot_markers && Object.keys(data.pivot_markers).length > 0) {
const xMin = data.timestamps[0];
const xMax = data.timestamps[data.timestamps.length - 1];
// Process each timestamp that has pivot markers
Object.entries(data.pivot_markers).forEach(([timestamp, pivots]) => {
// Draw horizontal lines for last high pivots (resistance)
// Process high pivots
if (pivots.highs && pivots.highs.length > 0) {
pivots.highs.forEach(pivot => {
const color = this._getPivotColor(pivot.level, 'high');
shapes.push({
type: 'line',
x0: xMin,
y0: pivot.price,
x1: xMax,
y1: pivot.price,
line: {
color: color,
width: 1,
dash: 'dash'
},
layer: 'below'
});
// Add label for the level
annotations.push({
x: xMax,
y: pivot.price,
text: `L${pivot.level}H`,
showarrow: false,
xanchor: 'left',
font: {
size: 9,
color: color
},
bgcolor: '#1f2937',
borderpad: 2
});
// Draw dot on the pivot candle (above the high)
pivotDots.x.push(timestamp);
pivotDots.y.push(pivot.price);
pivotDots.text.push(`L${pivot.level} High Pivot<br>Price: $${pivot.price.toFixed(2)}<br>Strength: ${(pivot.strength * 100).toFixed(0)}%`);
pivotDots.marker.color.push(color);
pivotDots.marker.size.push(8);
pivotDots.marker.symbol.push('triangle-down');
// Draw horizontal line ONLY for last pivot of this level
if (pivot.is_last) {
shapes.push({
type: 'line',
x0: xMin,
y0: pivot.price,
x1: xMax,
y1: pivot.price,
line: {
color: color,
width: 1,
dash: 'dash'
},
layer: 'below'
});
// Add label for the level
annotations.push({
x: xMax,
y: pivot.price,
text: `L${pivot.level}H`,
showarrow: false,
xanchor: 'left',
font: {
size: 9,
color: color
},
bgcolor: '#1f2937',
borderpad: 2
});
}
});
}
// Draw horizontal lines for last low pivots (support)
// Process low pivots
if (pivots.lows && pivots.lows.length > 0) {
pivots.lows.forEach(pivot => {
const color = this._getPivotColor(pivot.level, 'low');
shapes.push({
type: 'line',
x0: xMin,
y0: pivot.price,
x1: xMax,
y1: pivot.price,
line: {
color: color,
width: 1,
dash: 'dash'
},
layer: 'below'
});
// Add label for the level
annotations.push({
x: xMax,
y: pivot.price,
text: `L${pivot.level}L`,
showarrow: false,
xanchor: 'left',
font: {
size: 9,
color: color
},
bgcolor: '#1f2937',
borderpad: 2
});
// Draw dot on the pivot candle (below the low)
pivotDots.x.push(timestamp);
pivotDots.y.push(pivot.price);
pivotDots.text.push(`L${pivot.level} Low Pivot<br>Price: $${pivot.price.toFixed(2)}<br>Strength: ${(pivot.strength * 100).toFixed(0)}%`);
pivotDots.marker.color.push(color);
pivotDots.marker.size.push(8);
pivotDots.marker.symbol.push('triangle-up');
// Draw horizontal line ONLY for last pivot of this level
if (pivot.is_last) {
shapes.push({
type: 'line',
x0: xMin,
y0: pivot.price,
x1: xMax,
y1: pivot.price,
line: {
color: color,
width: 1,
dash: 'dash'
},
layer: 'below'
});
// Add label for the level
annotations.push({
x: xMax,
y: pivot.price,
text: `L${pivot.level}L`,
showarrow: false,
xanchor: 'left',
font: {
size: 9,
color: color
},
bgcolor: '#1f2937',
borderpad: 2
});
}
});
}
});
// Add pivot dots trace if we have any
if (pivotDots.x.length > 0) {
chartData.push(pivotDots);
}
console.log(`Added ${shapes.length} pivot levels to ${timeframe} chart`);
}
@@ -370,85 +400,115 @@ class ChartManager {
// Add pivot markers from chart data
const shapes = [];
const annotations = [];
const pivotDots = { x: [], y: [], text: [], marker: { color: [], size: [], symbol: [] }, mode: 'markers', hoverinfo: 'text', showlegend: false };
if (data.pivot_markers && Object.keys(data.pivot_markers).length > 0) {
const xMin = data.timestamps[0];
const xMax = data.timestamps[data.timestamps.length - 1];
// Process each timestamp that has pivot markers
Object.entries(data.pivot_markers).forEach(([timestamp, pivots]) => {
// Draw horizontal lines for last high pivots
// Process high pivots
if (pivots.highs && pivots.highs.length > 0) {
pivots.highs.forEach(pivot => {
const color = this._getPivotColor(pivot.level, 'high');
shapes.push({
type: 'line',
x0: xMin,
y0: pivot.price,
x1: xMax,
y1: pivot.price,
line: {
color: color,
width: 1,
dash: 'dash'
},
layer: 'below'
});
annotations.push({
x: xMax,
y: pivot.price,
text: `L${pivot.level}H`,
showarrow: false,
xanchor: 'left',
font: {
size: 9,
color: color
},
bgcolor: '#1f2937',
borderpad: 2
});
// Draw dot on the pivot candle
pivotDots.x.push(timestamp);
pivotDots.y.push(pivot.price);
pivotDots.text.push(`L${pivot.level} High Pivot<br>Price: $${pivot.price.toFixed(2)}<br>Strength: ${(pivot.strength * 100).toFixed(0)}%`);
pivotDots.marker.color.push(color);
pivotDots.marker.size.push(8);
pivotDots.marker.symbol.push('triangle-down');
// Draw horizontal line ONLY for last pivot
if (pivot.is_last) {
shapes.push({
type: 'line',
x0: xMin,
y0: pivot.price,
x1: xMax,
y1: pivot.price,
line: {
color: color,
width: 1,
dash: 'dash'
},
layer: 'below'
});
annotations.push({
x: xMax,
y: pivot.price,
text: `L${pivot.level}H`,
showarrow: false,
xanchor: 'left',
font: {
size: 9,
color: color
},
bgcolor: '#1f2937',
borderpad: 2
});
}
});
}
// Draw horizontal lines for last low pivots
// Process low pivots
if (pivots.lows && pivots.lows.length > 0) {
pivots.lows.forEach(pivot => {
const color = this._getPivotColor(pivot.level, 'low');
shapes.push({
type: 'line',
x0: xMin,
y0: pivot.price,
x1: xMax,
y1: pivot.price,
line: {
color: color,
width: 1,
dash: 'dash'
},
layer: 'below'
});
annotations.push({
x: xMax,
y: pivot.price,
text: `L${pivot.level}L`,
showarrow: false,
xanchor: 'left',
font: {
size: 9,
color: color
},
bgcolor: '#1f2937',
borderpad: 2
});
// Draw dot on the pivot candle
pivotDots.x.push(timestamp);
pivotDots.y.push(pivot.price);
pivotDots.text.push(`L${pivot.level} Low Pivot<br>Price: $${pivot.price.toFixed(2)}<br>Strength: ${(pivot.strength * 100).toFixed(0)}%`);
pivotDots.marker.color.push(color);
pivotDots.marker.size.push(8);
pivotDots.marker.symbol.push('triangle-up');
// Draw horizontal line ONLY for last pivot
if (pivot.is_last) {
shapes.push({
type: 'line',
x0: xMin,
y0: pivot.price,
x1: xMax,
y1: pivot.price,
line: {
color: color,
width: 1,
dash: 'dash'
},
layer: 'below'
});
annotations.push({
x: xMax,
y: pivot.price,
text: `L${pivot.level}L`,
showarrow: false,
xanchor: 'left',
font: {
size: 9,
color: color
},
bgcolor: '#1f2937',
borderpad: 2
});
}
});
}
});
// Add pivot dots trace if we have any
if (pivotDots.x.length > 0) {
chartData.push(pivotDots);
}
}
// Use Plotly.react for efficient updates
const update = {
const update = {
shapes: shapes,
annotations: annotations
};
@@ -739,11 +799,11 @@ class ChartManager {
// Different colors for different levels
const highColors = ['#dc3545', '#ff6b6b', '#ff8787', '#ffa8a8', '#ffc9c9'];
const lowColors = ['#28a745', '#51cf66', '#69db7c', '#8ce99a', '#b2f2bb'];
const colors = type === 'high' ? highColors : lowColors;
return colors[Math.min(level - 1, colors.length - 1)];
}
/**
* Enable crosshair cursor
*/