Skip to content

Commit 4cb06c8

Browse files
committed
FractalDimension indicator.
1 parent f046670 commit 4cb06c8

2 files changed

Lines changed: 1755 additions & 0 deletions

File tree

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
namespace StockSharp.Algo.Indicators;
2+
3+
/// <summary>
4+
/// Fractal Dimension Index.
5+
/// </summary>
6+
/// <remarks>
7+
/// https://doc.stocksharp.com/topics/api/indicators/list_of_indicators/fractal_dimension.html
8+
/// </remarks>
9+
[Display(
10+
ResourceType = typeof(LocalizedStrings),
11+
Name = LocalizedStrings.FractalDimensionKey,
12+
Description = LocalizedStrings.FractalDimensionDescKey)]
13+
[Doc("topics/api/indicators/list_of_indicators/fractal_dimension.html")]
14+
public class FractalDimension : LengthIndicator<decimal>
15+
{
16+
/// <summary>
17+
/// Initializes a new instance of the <see cref="FractalDimension"/>.
18+
/// </summary>
19+
public FractalDimension()
20+
{
21+
Length = 30;
22+
23+
Buffer.MinComparer = new DecimalOperator();
24+
Buffer.MaxComparer = new DecimalOperator();
25+
}
26+
27+
/// <inheritdoc />
28+
public override IndicatorMeasures Measure => IndicatorMeasures.MinusOnePlusOne;
29+
30+
/// <inheritdoc />
31+
protected override IIndicatorValue OnProcess(IIndicatorValue input)
32+
{
33+
var price = input.GetValue<decimal>();
34+
35+
var buffer = Buffer;
36+
37+
if (input.IsFinal)
38+
buffer.PushBack(price);
39+
40+
if (buffer.Count < 2)
41+
return new DecimalIndicatorValue(this, 1.5m, input.Time);
42+
43+
var maxHigh = buffer.Max.Value;
44+
var minLow = buffer.Min.Value;
45+
46+
var startIdx = input.IsFinal ? 1 : 2;
47+
48+
// Calculate the length of the price path
49+
var pathLength = 0m;
50+
for (var i = startIdx; i < buffer.Count; i++)
51+
{
52+
var prev = buffer[i - 1];
53+
var curr = buffer[i];
54+
pathLength += (curr - prev).Abs();
55+
}
56+
57+
if (!input.IsFinal)
58+
{
59+
maxHigh = maxHigh.Max(price);
60+
minLow = minLow.Max(price);
61+
62+
pathLength += (price - buffer.Last()).Abs();
63+
}
64+
65+
// Calculate FDI
66+
decimal fractalDimension;
67+
68+
var range = maxHigh - minLow;
69+
70+
if (pathLength == 0 || range == 0)
71+
{
72+
fractalDimension = 1.5m;
73+
}
74+
else
75+
{
76+
// FDI formula: 1 + (log(pathLength) - log(range)) / log(2 * (Length-1))
77+
var logPathLength = pathLength.Log();
78+
var logRange = range.Log();
79+
var logDenominator = (2m * (Length - 1)).Log();
80+
81+
if (logDenominator == 0)
82+
{
83+
fractalDimension = 1.5m;
84+
}
85+
else
86+
{
87+
fractalDimension = 1m + (logPathLength - logRange) / logDenominator;
88+
}
89+
}
90+
91+
// Clamp between 1.0 and 2.0
92+
fractalDimension = 1.0m.Max(2.0m.Min(fractalDimension));
93+
94+
return new DecimalIndicatorValue(this, fractalDimension, input.Time);
95+
}
96+
}

0 commit comments

Comments
 (0)