Files
QuanTAlib/quantower/Momentum/AmatIndicator.cs
T
Miha Kralj 11f4ec2497 Add Ultimate Oscillator implementation and documentation
- Introduced the Ultimate Oscillator (UltOsc) indicator with detailed mathematical foundation and performance profile.
- Added historical context and common pitfalls for better user understanding.
- Implemented Bilateral filter with enhanced update methods and batch calculations.
- Updated Blackman Moving Average (BLMA) with improved handling of NaN values and batch processing capabilities.
- Created unit tests for AmatIndicator to ensure proper functionality and signal generation.
- Integrated AmatIndicator into the Quantower platform with appropriate line series for trend and strength visualization.
- Updated project file to include new indicator implementations.
2025-12-31 23:30:54 -08:00

99 lines
3.3 KiB
C#

using System.Drawing;
using TradingPlatform.BusinessLayer;
using static QuanTAlib.IndicatorExtensions;
namespace QuanTAlib;
/// <summary>
/// AMAT (Archer Moving Averages Trends) Quantower indicator.
/// Uses dual EMAs to identify trend direction and strength.
/// </summary>
public class AmatIndicator : Indicator, IWatchlistIndicator
{
[InputParameter("Fast Period", sortIndex: 10, minimum: 1, maximum: 500, increment: 1, decimalPlaces: 0)]
public int FastPeriod { get; set; } = 10;
[InputParameter("Slow Period", sortIndex: 11, minimum: 2, maximum: 1000, increment: 1, decimalPlaces: 0)]
public int SlowPeriod { get; set; } = 50;
[DataSourceInput]
public SourceType Source { get; set; } = SourceType.Close;
[InputParameter("Show Cold Values", sortIndex: 100)]
public bool ShowColdValues { get; set; } = true;
private Amat? _amat;
private Func<IHistoryItem, double>? _selector;
public int MinHistoryDepths => SlowPeriod;
public override string ShortName => $"AMAT({FastPeriod},{SlowPeriod})";
public AmatIndicator()
{
Name = "AMAT - Archer Moving Averages Trends";
Description = "Identifies trend direction using dual EMA alignment";
SeparateWindow = true;
OnBackGround = false;
}
protected override void OnInit()
{
_amat = new Amat(FastPeriod, SlowPeriod);
_selector = Source.GetPriceSelector();
// Trend line: +1 = bullish, -1 = bearish, 0 = neutral
AddLineSeries(new LineSeries("Trend", Momentum, 2, LineStyle.Histogramm));
// Strength line: percentage separation
AddLineSeries(new LineSeries("Strength", Color.FromArgb(255, 200, 128), 1, LineStyle.Solid));
// Fast EMA line
AddLineSeries(new LineSeries("Fast EMA", Color.FromArgb(100, 200, 100), 1, LineStyle.Solid));
// Slow EMA line
AddLineSeries(new LineSeries("Slow EMA", Color.FromArgb(200, 100, 100), 1, LineStyle.Solid));
// Zero line reference
AddLineSeries(new LineSeries("Zero", Color.Gray, 1, LineStyle.Dot));
}
protected override void OnUpdate(UpdateArgs args)
{
if (_amat == null || _selector == null) return;
var item = HistoricalData[0, SeekOriginHistory.End];
double value = _selector(item);
bool isNew = args.IsNewBar();
TValue input = new(item.TimeLeft, value);
_amat.Update(input, isNew);
bool isHot = _amat.IsHot;
// Trend line
LinesSeries[0].SetValue(_amat.Last.Value, isHot, ShowColdValues);
// Strength line
LinesSeries[1].SetValue(_amat.Strength.Value, isHot, ShowColdValues);
// Fast EMA line
LinesSeries[2].SetValue(_amat.FastEma.Value, isHot, ShowColdValues);
// Slow EMA line
LinesSeries[3].SetValue(_amat.SlowEma.Value, isHot, ShowColdValues);
// Zero reference line
LinesSeries[4].SetValue(0);
// Color the trend histogram based on direction
if (isHot || ShowColdValues)
{
double trend = _amat.Last.Value;
Color trendColor = trend > 0 ? Color.Green :
trend < 0 ? Color.Red :
Color.Gray;
LinesSeries[0].SetMarker(0, new IndicatorLineMarker(trendColor));
}
}
}