forked from AlexWan/OsEngine
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
1,424 additions
and
0 deletions.
There are no files selected for viewing
288 changes: 288 additions & 0 deletions
288
project/OsEngine/bin/Debug/Custom/Indicators/Scripts/ZigZagMFI.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,288 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Drawing; | ||
using OsEngine.Entity; | ||
|
||
namespace OsEngine.Indicators.ind | ||
{ | ||
internal class ZigZagMFI : Aindicator | ||
{ | ||
private Aindicator _MFI; | ||
|
||
private IndicatorDataSeries _seriesMFI; | ||
|
||
private IndicatorParameterInt _lenghtMFI; | ||
private IndicatorParameterInt _lengthZigZag; | ||
|
||
private IndicatorDataSeries _seriesZigZag; | ||
private IndicatorDataSeries _seriesToLine; | ||
private IndicatorDataSeries _seriesZigZagHighs; | ||
private IndicatorDataSeries _seriesZigZagLows; | ||
|
||
private IndicatorDataSeries _seriesZigZagUpChannel; | ||
private IndicatorDataSeries _seriesZigZagDownChannel; | ||
|
||
public override void OnStateChange(IndicatorState state) | ||
{ | ||
if (state == IndicatorState.Configure) | ||
{ | ||
_lenghtMFI = CreateParameterInt("Length", 3); | ||
_lengthZigZag = CreateParameterInt("Length ZigZag", 14); | ||
|
||
_seriesMFI = CreateSeries("MFI", Color.Aqua, IndicatorChartPaintType.Line, true); | ||
|
||
_seriesZigZag = CreateSeries("ZigZag", Color.CornflowerBlue, IndicatorChartPaintType.Point, false); | ||
_seriesZigZag.CanReBuildHistoricalValues = true; | ||
|
||
_seriesToLine = CreateSeries("ZigZagLine", Color.CornflowerBlue, IndicatorChartPaintType.Point, true); | ||
_seriesToLine.CanReBuildHistoricalValues = true; | ||
|
||
_seriesZigZagHighs = CreateSeries("_seriesZigZagHighs", Color.GreenYellow, IndicatorChartPaintType.Point, false); | ||
_seriesZigZagHighs.CanReBuildHistoricalValues = true; | ||
|
||
_seriesZigZagLows = CreateSeries("_seriesZigZagLows", Color.Red, IndicatorChartPaintType.Point, false); | ||
_seriesZigZagLows.CanReBuildHistoricalValues = true; | ||
|
||
_seriesZigZagUpChannel = CreateSeries("_seriesZigZagUpChannel", Color.DarkRed, IndicatorChartPaintType.Point, true); | ||
_seriesZigZagUpChannel.CanReBuildHistoricalValues = true; | ||
|
||
_seriesZigZagDownChannel = CreateSeries("_seriesZigZagDownChannel", Color.DarkGreen, IndicatorChartPaintType.Point, true); | ||
_seriesZigZagDownChannel.CanReBuildHistoricalValues = true; | ||
|
||
_MFI = IndicatorsFactory.CreateIndicatorByName("MFI", Name + "MFI", false); | ||
((IndicatorParameterInt)_MFI.Parameters[0]).Bind(_lenghtMFI); | ||
ProcessIndicator("MFI", _MFI); | ||
|
||
} | ||
} | ||
|
||
public override void OnProcess(List<Candle> candles, int index) | ||
{ | ||
_seriesMFI.Values[index] = _MFI.DataSeries[0].Values[index]; | ||
|
||
List<decimal> values = _MFI.DataSeries[0].Values; | ||
|
||
if (index < _lengthZigZag.ValueInt * 2) | ||
{ | ||
currentZigZagHigh = 0; | ||
currentZigZagLow = 0; | ||
lastSwingIndex = -1; | ||
lastSwingPrice = 0; | ||
trendDir = 0; | ||
return; | ||
} | ||
|
||
List<decimal> valuesMFI = new List<decimal>(); | ||
|
||
for (int i = 0; i < index + 1; i++) | ||
{ | ||
valuesMFI.Add(values[i]); | ||
} | ||
|
||
decimal High = 0; | ||
decimal Low = 0; | ||
|
||
High = valuesMFI[valuesMFI.Count - 1]; | ||
Low = valuesMFI[valuesMFI.Count - 1]; | ||
|
||
|
||
if (lastSwingPrice == 0) | ||
lastSwingPrice = Low + (High - Low) / 2; | ||
|
||
bool isSwingHigh = High == GetExtremum(values, _lengthZigZag.ValueInt, "High", index); | ||
bool isSwingLow = Low == GetExtremum(values, _lengthZigZag.ValueInt, "Low", index); | ||
decimal saveValue = 0; | ||
bool addHigh = false; | ||
bool addLow = false; | ||
bool updateHigh = false; | ||
bool updateLow = false; | ||
|
||
if (!isSwingHigh && !isSwingLow) | ||
{ | ||
ReBuildChannel(_seriesZigZagUpChannel, _seriesZigZagDownChannel, _seriesZigZagHighs.Values, _seriesZigZagLows.Values, index); | ||
return; | ||
} | ||
|
||
if (trendDir == 1 && isSwingHigh && High >= lastSwingPrice) | ||
{ | ||
saveValue = High; | ||
updateHigh = true; | ||
} | ||
else if (trendDir == -1 && isSwingLow && Low <= lastSwingPrice) | ||
{ | ||
saveValue = Low; | ||
updateLow = true; | ||
} | ||
else if (trendDir <= 0 && isSwingHigh) | ||
{ | ||
saveValue = High; | ||
addHigh = true; | ||
trendDir = 1; | ||
} | ||
else if (trendDir >= 0 && isSwingLow) | ||
{ | ||
saveValue = Low; | ||
addLow = true; | ||
trendDir = -1; | ||
} | ||
|
||
if (addHigh || addLow || updateHigh || updateLow) | ||
{ | ||
if (updateHigh && lastSwingIndex >= 0) | ||
{ | ||
_seriesZigZag.Values[lastSwingIndex] = 0; | ||
_seriesZigZagHighs.Values[lastSwingIndex] = 0; | ||
} | ||
else if (updateLow && lastSwingIndex >= 0) | ||
{ | ||
_seriesZigZag.Values[lastSwingIndex] = 0; | ||
_seriesZigZagLows.Values[lastSwingIndex] = 0; | ||
} | ||
|
||
if (addHigh || updateHigh) | ||
{ | ||
currentZigZagHigh = saveValue; | ||
_seriesZigZag.Values[index] = currentZigZagHigh; | ||
_seriesZigZagHighs.Values[index] = currentZigZagHigh; | ||
|
||
} | ||
else if (addLow || updateLow) | ||
{ | ||
currentZigZagLow = saveValue; | ||
_seriesZigZag.Values[index] = currentZigZagLow; | ||
_seriesZigZagLows.Values[index] = currentZigZagLow; | ||
|
||
} | ||
|
||
lastSwingIndex = index; | ||
lastSwingPrice = saveValue; | ||
|
||
if (updateHigh || updateLow) | ||
{ | ||
ReBuildLine(_seriesZigZag.Values, _seriesToLine.Values); | ||
} | ||
} | ||
ReBuildChannel(_seriesZigZagUpChannel, _seriesZigZagDownChannel, _seriesZigZagHighs.Values, _seriesZigZagLows.Values, index); | ||
} | ||
|
||
private decimal currentZigZagHigh = 0; | ||
private decimal currentZigZagLow = 0; | ||
private int lastSwingIndex = -1; | ||
private decimal lastSwingPrice = 0; | ||
private int trendDir = 0; | ||
|
||
|
||
private decimal GetExtremum(List<decimal> values, int period, string points, int index) | ||
{ | ||
try | ||
{ | ||
List<decimal> values1 = new List<decimal>(); | ||
for (int i = index; i >= index - period; i--) | ||
values1.Add(values[i]); | ||
|
||
if (points == "High") | ||
return values1.Max(); | ||
if (points == "Low") | ||
return values1.Min(); | ||
|
||
} | ||
catch (Exception e) | ||
{ | ||
|
||
} | ||
|
||
return 0; | ||
} | ||
|
||
|
||
private void ReBuildLine(List<decimal> zigZag, List<decimal> line) | ||
{ | ||
decimal curPoint = 0; | ||
int lastPointIndex = 0; | ||
|
||
for (int i = 0; i < zigZag.Count; i++) | ||
{ | ||
if (zigZag[i] == 0) | ||
{ | ||
continue; | ||
} | ||
|
||
if (curPoint == 0) | ||
{ | ||
curPoint = zigZag[i]; | ||
lastPointIndex = i; | ||
continue; | ||
} | ||
|
||
decimal mult = Math.Abs(curPoint - zigZag[i]) / (i - lastPointIndex); | ||
|
||
if (zigZag[i] < curPoint) | ||
{ | ||
mult = mult * -1; | ||
} | ||
|
||
decimal curValue = curPoint; | ||
|
||
for (int i2 = lastPointIndex; i2 < i; i2++) | ||
{ | ||
line[i2] = curValue; | ||
curValue += mult; | ||
} | ||
|
||
curPoint = zigZag[i]; | ||
lastPointIndex = i; | ||
} | ||
} | ||
|
||
|
||
private void ReBuildChannel(IndicatorDataSeries _seriesZigZagUpChannel, IndicatorDataSeries _seriesZigZagDownChannel, | ||
List<decimal> _seriesZigZagHighs, List<decimal> _seriesZigZagLows, int index) | ||
{ | ||
|
||
List<int> _ZigZagHighs = new List<int>(); | ||
|
||
for (int i = index; i >= 0; i--) | ||
{ | ||
if (_ZigZagHighs.Count == 3) { break; } | ||
if (_seriesZigZagHighs[i] == 0) { continue; } | ||
_ZigZagHighs.Add(i); | ||
} | ||
|
||
|
||
List<int> _ZigZagLows = new List<int>(); | ||
|
||
for (int i = index; i >= 0; i--) | ||
{ | ||
if (_ZigZagLows.Count == 3) { break; } | ||
if (_seriesZigZagLows[i] == 0) { continue; } | ||
_ZigZagLows.Add(i); | ||
} | ||
if (_ZigZagHighs.Count < 3 || _ZigZagLows.Count < 3) { return; } | ||
|
||
if (_ZigZagHighs[0] > _ZigZagLows[0]) | ||
{ | ||
|
||
RedRawVectorLine(_seriesZigZagUpChannel, _seriesZigZagHighs, _ZigZagHighs[2], _ZigZagHighs[1], index); | ||
|
||
RedRawVectorLine(_seriesZigZagDownChannel, _seriesZigZagLows, _ZigZagLows[1], _ZigZagLows[0], index); | ||
} | ||
else | ||
{ | ||
RedRawVectorLine(_seriesZigZagUpChannel, _seriesZigZagHighs, _ZigZagHighs[1], _ZigZagHighs[0], index); | ||
|
||
RedRawVectorLine(_seriesZigZagDownChannel, _seriesZigZagLows, _ZigZagLows[2], _ZigZagLows[1], index); | ||
} | ||
} | ||
|
||
private void RedRawVectorLine(IndicatorDataSeries _targetSeries, List<decimal> _sourceSeries, int _startVectorIndex, int _directionVectorIndex, int _endPointIndex) | ||
{ | ||
decimal _increment = (_sourceSeries[_directionVectorIndex] - _sourceSeries[_startVectorIndex]) / (_directionVectorIndex - _startVectorIndex); | ||
_targetSeries.Values[_startVectorIndex] = _sourceSeries[_startVectorIndex]; | ||
for (int i = _startVectorIndex + 1; i <= _endPointIndex; i++) | ||
{ | ||
_targetSeries.Values[i] = _targetSeries.Values[i - 1] + _increment; | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.