private bool BuildPopulationMatrix() { bool success = true; int i, nSize; List <Double> eqMemberX, eqMemberY; ClassificationKey keyX = (cbProtoAttributeX.SelectedIndex < 0) ? ClassificationKey.NULL : ClassKeyList[cbProtoAttributeX.SelectedIndex]; ClassificationKey keyY = (cbProtoAttributeY.SelectedIndex < 0) ? ClassificationKey.NULL : ClassKeyList[cbProtoAttributeY.SelectedIndex]; nSize = DataSrc.HistoricalData.Constituents.Count; PopulationToClassify = new double[nSize, 2]; eqMemberX = null; eqMemberY = null; if (keyX == keyY || keyX == ClassificationKey.NULL || keyY == ClassificationKey.NULL) { success = false; } else { for (i = 0; i < nSize; i++) { eqMemberX = SelectDataComponent(keyX, DataSrc.HistoricalData.Constituents[i]); eqMemberY = SelectDataComponent(keyY, DataSrc.HistoricalData.Constituents[i]); if (eqMemberX != null && eqMemberY != null) { switch (ClassFnList[cbProtoFunction.SelectedIndex]) { case PrototypeFunction.AVERAGE: PopulationToClassify[i, 0] = eqMemberX.Average(); PopulationToClassify[i, 1] = eqMemberY.Average(); break; case PrototypeFunction.STD_DEV: PopulationToClassify[i, 0] = Helpers.StdDev(eqMemberX); PopulationToClassify[i, 1] = Helpers.StdDev(eqMemberY); break; case PrototypeFunction.VARIANCE: default: break; } } else { success = false; break; } } } return(success); }
/***************************************************************************** * FUNCTION: PearsonProductCoefficient * * Description: Calculates the Pearson Product Coefficient (PPC) for each * Equity in pInputList based on it's HistoricalPrice list, against * every other Equity in pInputList. * * The intent is to find correlation between Equities whose * HistoricalPrice values tend to move together. * Each coefficient is a value between -1 and 1. A value of * 1 corresponds to a high positive correlation. That is, the * Equities tend to move in the same direction at the same time * over the series of data provided. A value of -1 corresponds to * a high negative correlation. That is, the Equities tend to move * in opposite directions at the same time. A value of 0 means there * is no identifiable correlation between the direction of movement. * * Parameters: * pInputList - the input data, consisting of multiple Equity instances *****************************************************************************/ public static Double[] PearsonProductCoefficient(List <Equity> pInputList) { int N, cSize, i, j, k, count, key; Double coeff, numerator, denominator; Double meanRange1, meanRange2; Double[] CorrelationCoefficients; /*Create the empty correlation table. Note that we only need to calculate the correlation between any 2 equities once. * Ex. Given 5 inputs {a,b,c,d,e}: * a b c d e * --------------- cSize = (5 * (4)) / 2 = 10 * a|- C0 C1 C2 C3 * b| - C4 C5 C6 * c| - C7 C8 * d| - C9 * e| - */ N = pInputList.Count(); cSize = N * (N - 1) / 2; CorrelationCoefficients = new Double[cSize]; if (N > 0) { count = 1; for (i = 0; i < N; i++) { coeff = 0; denominator = 0; meanRange1 = 0; meanRange2 = 0; for (j = count; j < N; j++) { if (pInputList[i].HistoricalPrice.Count() == pInputList[j].HistoricalPrice.Count()) { numerator = 0; //Recalculate the average instead of using the 'avgPrice' member // because the rounded value introduces significant inaccuracy in some transformations meanRange1 = pInputList[i].HistoricalPrice.Average(); meanRange2 = pInputList[j].HistoricalPrice.Average(); for (k = 0; k < pInputList[j].HistoricalPrice.Count(); k++) { numerator += (pInputList[i].HistoricalPrice[k] * pInputList[j].HistoricalPrice[k]); } numerator -= (pInputList[j].HistoricalPrice.Count() * meanRange1 * meanRange2); denominator = Helpers.StdDev(pInputList[i].HistoricalPrice) * Helpers.StdDev(pInputList[j].HistoricalPrice); denominator *= (pInputList[j].HistoricalPrice.Count() - 1); coeff = numerator / denominator; } key = getHash(i + 1, j + 1, pInputList.Count()); CorrelationCoefficients[key] = coeff; } count++; } } return(CorrelationCoefficients); }
/***************************************************************************** * FUNCTION: CalculateVolatility * Description: * Parameters: *****************************************************************************/ private void CalculateVolatility() { Volatility = Helpers.StdDev(hist_daily_change); }
/***************************************************************************** * FUNCTION: GetFunction * Description: Evaluates the passed funuction on the given Equity at the * passed index (date/price) * Parameters: None *****************************************************************************/ private Double GetFunction(Fn pFn, Equity pEqIn, String pFnStr, int pIndex) { List <double> func_inputs; Double eval_data = 0.0; int index1, index2, filter_index1, filter_index2; Variable input_param; String input_param_str, filter_str; func_inputs = new List <double>(); index1 = pFnStr.IndexOf('['); index2 = pFnStr.IndexOf(']'); if (index1 >= 0 && index2 > index1) { input_param_str = pFnStr.Substring(index1 + 1, index2 - index1 - 1); input_param = GetParameterType(input_param_str); //Set the input array switch (input_param) { case Variable.MACD_SIG: func_inputs = new List <double>(pEqIn.MACD_B); break; case Variable.MACD_DIFF: func_inputs = new List <double>(pEqIn.MACD_C); break; case Variable.PRICE: func_inputs = new List <double>(pEqIn.HistoricalPrice); break; case Variable.VOLUME: func_inputs = new List <double>(pEqIn.HistoricalVolumes); break; case Variable.PCT: func_inputs = new List <double>(pEqIn.HistoricalPctChange); break; default: break; } if ((pFnStr.Length > (index2 + 1)) && pFnStr.ToCharArray()[index2 + 1] == '[') { index1 = index2 + 1; index2 = pFnStr.IndexOf(']', index1); filter_index1 = 1; filter_index2 = 1; if (index2 > index1) { filter_str = pFnStr.Substring(index1 + 1, index2 - index1 - 1); if (Regex.Matches(filter_str, "[-][0-9][.][.][-]?[0-9]").Count > 0) { index1 = filter_str.IndexOf('.'); filter_index1 = int.Parse(filter_str.Substring(0, index1)); filter_index2 = int.Parse(filter_str.Substring(index1 + 2, filter_str.Length - index1 - 2)); } } if ((filter_index1 <= 0 && filter_index2 <= 0) && (pIndex + filter_index1 >= 0) && func_inputs.Count > pIndex) { func_inputs = func_inputs.GetRange(pIndex + filter_index1, filter_index2 - filter_index1 - 1); switch (pFn) { case Fn.AVG: eval_data = func_inputs.Average(); break; case Fn.MAX: eval_data = func_inputs.Max(); break; case Fn.MIN: eval_data = func_inputs.Min(); break; case Fn.TREND: //Need some kind of curve/line fitting algorithm break; case Fn.STDEV: eval_data = Helpers.StdDev(func_inputs); break; default: break; } } } else { //If the data to be analyzed is one of the MACD signals, ensure the passed index is valid // The index needs to be greater than the first day for which the MACD can be calculated. // ie. for the standard 12,26,9 series, pIndex must be greater than (26 + 9) = 35 if (input_param == Variable.MACD_DIFF || input_param == Variable.MACD_SIG) { if (pIndex > (pEqIn.HistoricalPrice.Count() - pEqIn.MACD_C.Count())) { eval_data = func_inputs[pIndex]; } else { eval_data = 0.0; } } else { eval_data = func_inputs[pIndex]; } } } return(eval_data); }
/***************************************************************************** * FUNCTION: GetParameter * Description: * Parameters: None *****************************************************************************/ private Double GetParameter(Equity pEqIn, String pKey, int pIndex) { double return_val = 0.0; pKey = pKey.Trim(); int macd_i_diff; int index1 = -1, index2 = -1, filter_index; string IndexStr = ""; Variable get_param = 0; index1 = pKey.IndexOf('[', 1); if (index1 > 0) { index2 = pKey.IndexOf(']', index1); } filter_index = pIndex; //If the parameter asks for a specific index other than pIndex if (index2 > index1) { IndexStr = pKey.Substring(index1 + 1, index2 - index1 - 1).Trim(); if (Regex.Matches(IndexStr, "^[-][0-9]*$").Count > 0) { filter_index = pIndex + int.Parse(IndexStr); } else { throw new ArgumentException(); } //clear the index specifier pKey = pKey.Substring(0, index1); } //Ex. If the passed parameter string is "P", filter_index = pIndex // If the passed parameter string is "P[-2], filter_index = pIndex - 2 // // At this point, in both cases pKey will be "P" if (filter_index < 0) { throw new IndexOutOfRangeException(); } get_param = GetParameterType(pKey); switch (get_param) { case Variable.MACD_SIG: macd_i_diff = pEqIn.HistoricalPrice.Count - pEqIn.MACD_B.Count; if (filter_index >= macd_i_diff) { return_val = pEqIn.MACD_B[filter_index - macd_i_diff]; } break; case Variable.MACD_DIFF: macd_i_diff = pEqIn.HistoricalPrice.Count - pEqIn.MACD_C.Count; if (filter_index >= macd_i_diff) { return_val = pEqIn.MACD_C[filter_index - macd_i_diff]; } break; case Variable.PRICE: return_val = pEqIn.HistoricalPrice[filter_index]; break; case Variable.PCT: return_val = pEqIn.HistoricalPctChange[filter_index]; break; case Variable.VOLUME: return_val = pEqIn.HistoricalVolumes[filter_index]; break; case Variable.VX: return_val = Helpers.StdDev(pEqIn.HistoricalPrice.GetRange(0, filter_index)); break; case Variable.LASTBUY: return_val = (double)(filter_index - this.buy_history.LastIndexOf(true)); break; case Variable.LASTSELL: return_val = (double)(filter_index - this.sell_history.LastIndexOf(true)); break; default: throw new ArgumentException(); } return(return_val); }
/***************************************************************************** * FUNCTION: CalculateVolatility * Description: * Parameters: *****************************************************************************/ private void CalculateVolatility() { Volatility = Helpers.StdDev(HistoricalPctChange); }