Description
This is a pseudo point anf figure indicator which can be plotted on normal time charts. The box size can either be a fix number in pips or fluctuate based on volatility (ATR). The reversal amount is typically three times the box size but can also be set to any other number. It is also possible to use high and lows prices for calculating the movement while using only closing prices there will be less movement.
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class PseudoPointandFigure : Indicator
{
[Parameter("Source", Group = "Source", DefaultValue = PriceType.OHLC4)]
public PriceType Source { get; set; }
[Parameter("Use High/Low", Group = "Source", DefaultValue = false)]
public bool UseHL { get; set; }
[Parameter("Use ATR", Group = "Box", DefaultValue = false)]
public bool UseAtr { get; set; }
[Parameter("ATR Period", Group = "Box", DefaultValue = 14)]
public int AtrPeriod { get; set; }
[Parameter("ATR Multi", Group = "Box", DefaultValue = 1.0)]
public double AtrMulti { get; set; }
[Parameter("Box Size (Pips) without ATR", Group = "Box", DefaultValue = 10.0)]
public double BoxSize { get; set; }
[Parameter("Reversal Size (# Boxes)", Group = "Box", DefaultValue = 3.0, Step = 1.0)]
public double Reversal { get; set; }
[Output("Main", LineColor = "LightBlue", Thickness = 1)]
public IndicatorDataSeries Result { get; set; }
[Output("Rising", LineColor = "FF0FFF00", PlotType = PlotType.Points, Thickness = 8)]
public IndicatorDataSeries Rising { get; set; }
[Output("Falling", LineColor = "FFFF006B", PlotType = PlotType.Points, Thickness = 8)]
public IndicatorDataSeries Falling { get; set; }
private AverageTrueRange ATR;
private int direction;
private double nextLevel, reverse;
private DataSeries priceSource;
public enum PriceType
{
Close,
Weighted,
Typical,
Median,
OHLC4
}
protected override void Initialize()
{
if (UseAtr)
{
ATR = Indicators.AverageTrueRange(AtrPeriod, MovingAverageType.Simple);
}
switch (Source)
{
default:
case PriceType.Close:
priceSource = Bars.ClosePrices;
break;
case PriceType.Weighted:
priceSource = Bars.WeightedPrices;
break;
case PriceType.Typical:
priceSource = Bars.TypicalPrices;
break;
case PriceType.Median:
priceSource = Bars.MedianPrices;
break;
case PriceType.OHLC4:
priceSource = null;
break;
}
}
public override void Calculate(int index)
{
if (index < (UseAtr ? AtrPeriod : 1))
{
Result[index] = Bars.ClosePrices[index];
direction = 1;
nextLevel = Bars.ClosePrices[index] + BoxSize * Symbol.PipSize;
reverse = Bars.ClosePrices[index] - BoxSize * Symbol.PipSize * Reversal;
}
else
{
double price = priceSource != null ? priceSource[index] : (Bars.OpenPrices[index] + Bars.HighPrices[index] + Bars.LowPrices[index] + Bars.ClosePrices[index]) / 4.0;
double high = UseHL ? Bars.HighPrices[index] : price;
double low = UseHL ? Bars.LowPrices[index] : price;
double box = UseAtr ? AtrMulti * ATR.Result[index] : BoxSize * Symbol.PipSize;
if (direction > 0)
{
if (high >= nextLevel)
{
while (high >= nextLevel)
{
Result[index] = nextLevel;
nextLevel += box;
reverse += box;
}
}
else if (low <= reverse)
{
Result[index] = reverse;
direction = -1;
nextLevel -= (Reversal + 2.0) * box;
reverse += box * Reversal;
while (low <= nextLevel)
{
Result[index] = nextLevel;
nextLevel -= box;
reverse -= box;
}
}
else
{
Result[index] = !double.IsNaN(Result[index]) ? Result[index] : Result[index - 1];
}
}
else
{
if (low <= nextLevel)
{
while (low <= nextLevel)
{
Result[index] = nextLevel;
nextLevel -= box;
reverse -= box;
}
}
else if (high >= reverse)
{
Result[index] = reverse;
direction = 1;
nextLevel += (Reversal + 2.0) * box;
reverse -= box * Reversal;
while (high >= nextLevel)
{
Result[index] = nextLevel;
nextLevel += box;
reverse += box;
}
}
else
{
Result[index] = !double.IsNaN(Result[index]) ? Result[index] : Result[index - 1];
}
}
Rising[index] = double.NaN;
Falling[index] = double.NaN;
if (direction > 0)
{
Rising[index] = Result[index];
}
else
{
Falling[index] = Result[index];
}
}
}
}
}
CW
cW22Trader
Joined on 16.03.2021
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: Pseudo Point and Figure.algo
- Rating: 0
- Installs: 1547
- Modified: 13/10/2021 09:54
Note that publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section, please use the Copyright Infringement Notification form to submit a claim.
Comments
Log in to add a comment.
CW
Improved version with some bug-fixes and calculaton method more like point & figure or Renk.
Nice work. Please improve it to have a alert function when the color dotes changes.