private static void CalcIchimokuSenkouB <TQuote>( int i, List <TQuote> quotesList, IchimokuResult result, int senkouOffset, int senkouBPeriods) where TQuote : IQuote { if (i >= senkouOffset + senkouBPeriods - 1) { decimal max = 0; decimal min = decimal.MaxValue; for (int p = i - senkouOffset - senkouBPeriods + 1; p <= i - senkouOffset; p++) { TQuote d = quotesList[p]; if (d.High > max) { max = d.High; } if (d.Low < min) { min = d.Low; } } result.SenkouSpanB = (min + max) / 2; } }
private static void CalcIchimokuKijunSen <TQuote>( int i, List <TQuote> quotesList, IchimokuResult result, int kijunPeriods) where TQuote : IQuote { if (i >= kijunPeriods - 1) { decimal max = 0; decimal min = decimal.MaxValue; for (int p = i - kijunPeriods + 1; p <= i; p++) { TQuote d = quotesList[p]; if (d.High > max) { max = d.High; } if (d.Low < min) { min = d.Low; } } result.KijunSen = (min + max) / 2; } }
public void Standard() { int signalPeriod = 9; int shortSpanPeriod = 26; int longSpanPeriod = 52; List <IchimokuResult> results = Indicator.GetIchimoku( history, signalPeriod, shortSpanPeriod, longSpanPeriod) .ToList(); // assertions // proper quantities // should always be the same number of results as there is history Assert.AreEqual(502, results.Count); Assert.AreEqual(494, results.Where(x => x.TenkanSen != null).Count()); Assert.AreEqual(477, results.Where(x => x.KijunSen != null).Count()); Assert.AreEqual(451, results.Where(x => x.SenkouSpanA != null).Count()); Assert.AreEqual(425, results.Where(x => x.SenkouSpanB != null).Count()); Assert.AreEqual(476, results.Where(x => x.ChikouSpan != null).Count()); // sample values IchimokuResult r1 = results[51]; Assert.AreEqual(224.465m, r1.TenkanSen); Assert.AreEqual(221.94m, r1.KijunSen); Assert.AreEqual(214.8325m, r1.SenkouSpanA); Assert.AreEqual(null, r1.SenkouSpanB); Assert.AreEqual(226.35m, r1.ChikouSpan); IchimokuResult r2 = results[249]; Assert.AreEqual(257.15m, r2.TenkanSen); Assert.AreEqual(253.085m, r2.KijunSen); Assert.AreEqual(246.3125m, r2.SenkouSpanA); Assert.AreEqual(241.685m, r2.SenkouSpanB); Assert.AreEqual(259.21m, r2.ChikouSpan); IchimokuResult r3 = results[475]; Assert.AreEqual(265.575m, r3.TenkanSen); Assert.AreEqual(263.965m, r3.KijunSen); Assert.AreEqual(274.9475m, r3.SenkouSpanA); Assert.AreEqual(274.95m, r3.SenkouSpanB); Assert.AreEqual(245.28m, r3.ChikouSpan); IchimokuResult r4 = results[501]; Assert.AreEqual(241.26m, r4.TenkanSen); Assert.AreEqual(251.505m, r4.KijunSen); Assert.AreEqual(264.77m, r4.SenkouSpanA); Assert.AreEqual(269.82m, r4.SenkouSpanB); Assert.AreEqual(null, r4.ChikouSpan); }
public void GetIchimokuTest() { int signalPeriod = 9; int shortSpanPeriod = 26; int longSpanPeriod = 52; IEnumerable <IchimokuResult> results = Indicator.GetIchimoku( history, signalPeriod, shortSpanPeriod, longSpanPeriod); // assertions // proper quantities // should always be the same number of results as there is history Assert.AreEqual(502, results.Count()); Assert.AreEqual(494, results.Where(x => x.TenkanSen != null).Count()); Assert.AreEqual(477, results.Where(x => x.KijunSen != null).Count()); Assert.AreEqual(451, results.Where(x => x.SenkouSpanA != null).Count()); Assert.AreEqual(425, results.Where(x => x.SenkauSpanB != null).Count()); Assert.AreEqual(476, results.Where(x => x.ChikouSpan != null).Count()); // sample values IchimokuResult r1 = results.Where(x => x.Index == 476).FirstOrDefault(); Assert.AreEqual(265.575m, r1.TenkanSen); Assert.AreEqual(263.965m, r1.KijunSen); Assert.AreEqual(274.9475m, r1.SenkouSpanA); Assert.AreEqual(274.95m, r1.SenkauSpanB); Assert.AreEqual(245.28m, r1.ChikouSpan); IchimokuResult r2 = results.Where(x => x.Index == 502).FirstOrDefault(); Assert.AreEqual(241.26m, r2.TenkanSen); Assert.AreEqual(251.505m, r2.KijunSen); Assert.AreEqual(264.77m, r2.SenkouSpanA); Assert.AreEqual(269.82m, r2.SenkauSpanB); Assert.AreEqual(null, r2.ChikouSpan); }
/// <include file='./info.xml' path='indicator/type[@name="Full"]/*' /> /// public static IEnumerable <IchimokuResult> GetIchimoku <TQuote>( this IEnumerable <TQuote> quotes, int tenkanPeriods, int kijunPeriods, int senkouBPeriods, int senkouOffset, int chikouOffset) where TQuote : IQuote { // sort quotes List <TQuote> quotesList = quotes.SortToList(); // check parameter arguments ValidateIchimoku( tenkanPeriods, kijunPeriods, senkouBPeriods, senkouOffset, chikouOffset); // initialize List <IchimokuResult> results = new(quotesList.Count); int senkouStartPeriod = Math.Max( 2 * senkouOffset, Math.Max(tenkanPeriods, kijunPeriods)) - 1; // roll through quotes for (int i = 0; i < quotesList.Count; i++) { TQuote q = quotesList[i]; IchimokuResult result = new() { Date = q.Date }; results.Add(result); // tenkan-sen conversion line CalcIchimokuTenkanSen(i, quotesList, result, tenkanPeriods); // kijun-sen base line CalcIchimokuKijunSen(i, quotesList, result, kijunPeriods); // senkou span A if (i >= senkouStartPeriod) { IchimokuResult skq = results[i - senkouOffset]; if (skq != null && skq.TenkanSen != null && skq.KijunSen != null) { result.SenkouSpanA = (skq.TenkanSen + skq.KijunSen) / 2; } } // senkou span B CalcIchimokuSenkouB(i, quotesList, result, senkouOffset, senkouBPeriods); // chikou line if (i + chikouOffset < quotesList.Count) { result.ChikouSpan = quotesList[i + chikouOffset].Close; } } return(results); }