Skip to main content

Elliott Patterns

info

In similar fashion to the XABCD pattern (See XABCD doc page), every Elliott tool such as: impulse / motive / wave, Single / Double / Triple Corrections (ABC/WXYXZ) patterns CAN be represented with a PolyLineAnnotation instance with user defined point counts and labels: ["0", "1", "2", "3", "4", "5"].

Optionally - the 1st point can be left without a label "" or labeled with "0" to keep the wave start unmarked.

For example, an Elliott impulse wave can be drawn as a simple 6-point PolyLineAnnotation📘.

const {
AnnotationHoverModifier,
ECursorStyle,
EVerticalTextPosition,
NumberRange,
NumericAxis,
SciChartSurface
} = SciChart; // or import from "scichart"
const {
EAnnotationVisibilityMode,
EMultiPointLabelAnchorMode,
PolyLineAnnotation,
SciTraderLightTheme
} = SciChartFinancialTools; // if using npm, import from "scichart-financial-tools";

const { wasmContext, sciChartSurface } = await SciChartSurface.create(divElementId, {
theme: new SciTraderLightTheme()
});

sciChartSurface.xAxes.add(new NumericAxis(wasmContext, { visibleRange: new NumberRange(0, 70) }));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext, { visibleRange: new NumberRange(90, 140) }));

sciChartSurface.annotations.add(
new PolyLineAnnotation({
points: [
{ x: 6, y: 98 },
{ x: 18, y: 118 },
{ x: 28, y: 108 },
{ x: 42, y: 132 },
{ x: 52, y: 114 },
{ x: 64, y: 136 }
],
stroke: "#7C3AED",
strokeThickness: 3,
// fill: "#7C3AED22", // no need for "fill"
isEditable: true,

// Loop over an array of labels and assign each to a point index:
labels: ["0", "1", "2", "3", "4", "5"].map((text, pointIndex) => ({
anchorMode: EMultiPointLabelAnchorMode.Point,
pointIndex,
text: `${text}`,

// all labels not changed in the "formatLabelStyle" will have this "below" style
verticalTextPosition: EVerticalTextPosition.Below,
yOffset: 5,
})),

pointLabelVisibility: EAnnotationVisibilityMode.Always,
gripVisibility: EAnnotationVisibilityMode.Always,

// optional but recommended -> Makes the label positions dynamic based on the slope of the lines between points:
formatLabelStyle: ({ annotation, labelIndex }) => {
const points = annotation.points;

const currentPoint = points[labelIndex];
const previousPoint = points[labelIndex - 1];
const nextPoint = points[labelIndex + 1];

if (previousPoint && nextPoint) {
const previousSlope = (currentPoint.y - previousPoint.y) / (currentPoint.x - previousPoint.x);
const nextSlope = (nextPoint.y - currentPoint.y) / (nextPoint.x - currentPoint.x);
if (previousSlope > nextSlope) {
return {
verticalTextPosition: EVerticalTextPosition.Above,
yOffset: -5,
};
}
} else {
if (labelIndex === 0 && nextPoint.y < currentPoint.y
|| previousPoint.y < currentPoint.y
) {
return {
verticalTextPosition: EVerticalTextPosition.Above,
yOffset: -5,
};
}
}
return {}; // keep using the "Below" style defined in constructor
},
})
);

sciChartSurface.chartModifiers.add(
new AnnotationHoverModifier({ // for better default cursor styles
enableHover: true,
enableCursor: true,
idleCursor: ECursorStyle.Crosshair
})
);

Keep the annotation editable so traders can adjust the vertices after placement.

Other Elliott patterns:

This shows 2 more variants:

  • An Elliott Motive Wave with labels: ["", "A", "B", "C", "D", "E"]
  • An Elliott Triple correction with labels: ["(0)", "(W)", "(X)", "(Y)", "(X)", "(Z)"]

The important part is to keep in mind that ANY pattern can be drawn with a PolyLineAnnotation and the labels can be assigned to any point index. The rest is just a styling choice.

sciChartSurface.annotations.add(
new PolyLineAnnotation({
points: [
{ x: 6, y: 148 },
{ x: 18, y: 178 },
{ x: 28, y: 164 },
{ x: 42, y: 192 },
{ x: 52, y: 159 },
{ x: 64, y: 196 }
],
stroke: "#38F",
strokeThickness: 2,
fill: "#38F2",
isEditable: true,

// Loop over an array of labels and assign each to a point index:
labels: ["", "A", "B", "C", "D", "E"].map((text, pointIndex) => ({
anchorMode: EMultiPointLabelAnchorMode.Point,
pointIndex,
text: `${text}`,

// cheap trick to alternate label positions above and below points:
verticalTextPosition: pointIndex % 2 === 0 ? EVerticalTextPosition.Below : EVerticalTextPosition.Above,
// for a smarter solution, see the "formatLabelStyle" callback from the first annotation example on this page
})),
}),
new PolyLineAnnotation({
points: [
{ x: 6, y: 108 },
{ x: 18, y: 128 },
{ x: 28, y: 118 },
{ x: 42, y: 142 },
{ x: 52, y: 109 },
{ x: 64, y: 146 }
],
stroke: "#F83",
strokeThickness: 2,
// fill: "#F832",
isEditable: true,

// Loop over an array of labels and assign each to a point index:
labels: ["(0)", "(W)", "(X)", "(Y)", "(X)", "(Z)"].map((text, pointIndex) => ({
anchorMode: EMultiPointLabelAnchorMode.Point,
pointIndex,
text: `${text}`,

// cheap trick to alternate label positions above and below points:
verticalTextPosition: pointIndex % 2 === 0 ? EVerticalTextPosition.Below : EVerticalTextPosition.Above,
// for a smarter solution, see the "formatLabelStyle" callback from the first annotation example on this page
})),
})
);

See Also​