private static void RenderTableRow(string p_tableTitle, string p_rowTitle, bool p_isRowEven, ref SampleStats p_stat, bool p_isHtml, StringBuilder p_sb) { if (p_isHtml) { string aMeanPerYearRowId = "id" + (p_tableTitle + p_rowTitle).Replace(' ', '_').Replace(',', '_'); string aMeanPerYearCSV = String.Join(", ", p_stat.AMeanPerYear.Select(r => r.Item1 + ":" + r.Item2.ToString("#0.000%"))); p_sb.AppendFormat("<tr{0}><td>" + p_rowTitle + "</td>", (p_isRowEven) ? " class='even'" : ""); p_sb.Append("<td>" + p_stat.Samples.Count() + "</td>"); p_sb.Append("<td>" + p_stat.WinPct.ToString("#0.0%") + "</td>"); //p_sb.AppendFormat(@"<td onclick=""document.getElementById('{0}').style.color = 'red'"">" + p_maskItem.AMean.ToString("#0.000%") + "</td>", aMeanPerYearRowId); //p_sb.AppendFormat(@"<td onclick=""document.getElementById('{0}').style.display = 'table-row'"">" + p_maskItem.AMean.ToString("#0.000%") + @"<button onclick=""document.getElementById('{0}').style.display = 'table-row'"">*</button></td>", aMeanPerYearRowId); //p_sb.AppendFormat(@"<td onclick=""document.getElementById('{0}').style.display = 'table-row'"">" + p_maskItem.AMean.ToString("#0.000%") + @"</td>", aMeanPerYearRowId); //p_sb.AppendFormat(@"<td>" + p_maskItem.AMean.ToString("#0.000%") + @"<a href="""" onclick=""document.getElementById('{0}').style.display = 'table-row'"">*</a></td>", aMeanPerYearRowId); //p_sb.AppendFormat(@"<td onclick=""document.getElementById('{0}').style.display = 'table-row'"">" + p_maskItem.AMean.ToString("#0.000%") + @"<span style=""color: #2581cc; font-size: x-small; vertical-align:super;"">i</span></td>", aMeanPerYearRowId); //p_sb.AppendFormat(@"<td{0} onclick=""InvertVisibilityOfTableRow('{1}')"">" + p_stat.AMean.ToString("#0.000%") + @"<span style=""color: #2581cc; font-size: x-small; vertical-align:super;"">i</span></td>", (p_stat.AMean > 0.0) ? " class='green'" : " class='red'", aMeanPerYearRowId); p_sb.AppendFormat(@"<td{0} onclick=""GlobalScopeInvertVisibilityOfTableRow('{1}')"">" + p_stat.AMean.ToString("#0.000%") + @"<span style=""color: #2581cc; font-size: x-small; vertical-align:super;"">i</span></td>", (p_stat.AMean > 0.0) ? " class='green'" : " class='red'", aMeanPerYearRowId); p_sb.Append("<td>" + p_stat.GMean.ToString("#0.000%") + "</td>"); p_sb.Append("<td>" + p_stat.Median.ToString("#0.000%") + "</td>"); p_sb.Append("<td>" + p_stat.CorrectedStDev.ToString("#0.000%") + "</td>"); p_sb.Append("<td>" + p_stat.StandardError.ToString("#0.000%") + "</td>"); p_sb.AppendFormat("<td{0} >" + p_stat.TvalueToZero.ToString("#0.00") + "</td>", (p_stat.TvalueToZero >= 1.0) ? " class='green'" : ((p_stat.TvalueToZero <= -1.0) ? " class='red'" : "")); p_sb.Append("<td>" + p_stat.PvalueToZero.ToString("#0.00%") + "</td>"); p_sb.Append("<td>" + ((p_stat.PvalueToZero < 0.05) ? "Yes" : "") + "</td>"); p_sb.Append("<td>" + p_stat.TvalueToAMean.ToString("#0.00") + "</td>"); p_sb.Append("<td>" + p_stat.PvalueToAMean.ToString("#0.00%") + "</td>"); p_sb.Append("<td>" + ((p_stat.PvalueToAMean < 0.05) ? "Yes" : "") + "</td>"); p_sb.Append("</tr>"); p_sb.AppendFormat(@"<tr{0} ID=""{1}"" style=""display:none;""><td colspan=""14"">{2} aMean:{3}</td>", (p_isRowEven) ? " class='even'" : "", aMeanPerYearRowId, p_rowTitle, aMeanPerYearCSV); p_sb.Append("</tr>"); } else { p_sb.AppendLine($"{p_rowTitle} (#{p_stat.Samples.Count()}): {p_stat.WinPct.ToString("#0.0%")}, {p_stat.AMean.ToString("#0.000%")}, {p_stat.TvalueToZero.ToString("#0.00")}, {p_stat.PvalueToZero.ToString("#0.00%")}"); } }
private static void CalculateSampleStatsPerDayOffset(ref SampleStats p_sampleStats, double p_pctChgTotalAMean) { int nInt = p_sampleStats.Samples.Count(); if (nInt == 0) return; double n = (double)nInt; List<double> samples = p_sampleStats.Samples.Select(r => r.Item2).ToList(); // only the PctChanges are needed, not the Dates; but keep the Date in the sample for Debugging reasons double aMean = samples.Average(); double correctedStDev = Math.Sqrt(samples.Sum(r => (r - aMean) * (r - aMean)) / (n - 1.0)); double standardError = correctedStDev / Math.Sqrt(n); p_sampleStats.WinPct = (double)samples.Count(r => r > 0) / n; p_sampleStats.AMean = aMean; p_sampleStats.GMean = samples.GMeanExtendingWithOne(); p_sampleStats.Median = samples.Median(); p_sampleStats.CorrectedStDev = correctedStDev; p_sampleStats.StandardError = standardError; p_sampleStats.TvalueToZero = (p_sampleStats.AMean - 0.0) / standardError; p_sampleStats.TvalueToAMean = (p_sampleStats.AMean - p_pctChgTotalAMean) / standardError; // PvalueToZero = P = probability that the observed aMean result is due to chance if (!Double.IsNaN(p_sampleStats.TvalueToZero)) p_sampleStats.PvalueToZero = Utils.TDistribution(p_sampleStats.TvalueToZero, nInt - 1, true); else p_sampleStats.PvalueToZero = Double.NaN; if (!Double.IsNaN(p_sampleStats.TvalueToAMean)) p_sampleStats.PvalueToAMean = Utils.TDistribution(p_sampleStats.TvalueToAMean, nInt - 1, true); else p_sampleStats.PvalueToAMean = Double.NaN; p_sampleStats.AMeanPerYear = new List<Tuple<string, double>>(); var years = p_sampleStats.Samples.Select(r => r.Item1.Year).Distinct().OrderBy(r => r).ToList(); int nYears = years.Count(); int[] nSamplesPerYear = new int[nYears]; double[] aMeanPerYear = new double[nYears]; for (int i = 0; i < n; i++) { int iYears = years.IndexOf(p_sampleStats.Samples[i].Item1.Year); nSamplesPerYear[iYears]++; aMeanPerYear[iYears] += p_sampleStats.Samples[i].Item2; } for (int i = 0; i < nYears; i++) { aMeanPerYear[i] /= (double)nSamplesPerYear[i]; p_sampleStats.AMeanPerYear.Add(new Tuple<string, double>(years[i].ToString() + "(" + nSamplesPerYear[i] + ")", aMeanPerYear[i])); } }
private void RenderStatsForDisplaying(string p_title, SampleStats[] p_forward, SampleStats[] p_backward, bool p_isHtml, StringBuilder p_sbStats) { if (p_isHtml) p_sbStats.Append(@"<b>" + p_title + @":</b><br> <table class=""strategyNoteTable1"">" + @"<th>Day</th><th>nSamples</th><th>WinPct</th><th> aMean </th><th>gMean</th><th>Median</th><th>StDev</th><th>StError</th><th>t-value(0)</th>" + @"<th><div title=""P is calculated by one tailed, one sample T-test"">p-value(0)</div></th>" + @"<th><div title=""With at least 1-P=95% probability: the real population mean (of the daily%changes on day T) > 0 {or opposite if T-value negative}"">Signif>0</div></th>" + @"<th>t-value(mean)</th>" + @"<th><div title=""P is calculated by one tailed, one sample T-test"">p-value(mean)</div></th>" + @"<th><div title=""With at least 1-P=95% probability: the real population mean (of the daily%changes on day T) > allDayMean {or opposite if T-value negative}"">Signif>mean</div></th>"); else p_sbStats.AppendLine($"--- Stats for {p_title}: (Win%, aMean, t-value, p-value)"); bool isRowEven = false; // 1st Row is Odd for (int i = 16; i >= 0; i--) // write only from T-17 to T+17 { if (p_backward[i].Samples.Count() == 0) continue; RenderTableRow(p_title, "T-" + (i + 1).ToString(), isRowEven, ref p_backward[i], p_isHtml, p_sbStats); isRowEven = !isRowEven; } for (int i = 0; i <= 16; i++) // write only from T-17 to T+17 { if (p_forward[i].Samples.Count() == 0) continue; RenderTableRow(p_title, "T+" + (i + 1).ToString(), isRowEven, ref p_forward[i], p_isHtml, p_sbStats); isRowEven = !isRowEven; } if (p_isHtml) p_sbStats.Append("</table>"); else p_sbStats.Append(Environment.NewLine); }