/***************************************************************************** * 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); }
public void ReadXml(XmlReader reader) { XmlReader subReader; String txt, chgStr; Double lastPrice; DateTime lastDate; reader.MoveToContent(); reader.ReadStartElement(); IsInitializing = true; //subReader = reader.ReadSubtree(); while (reader.ReadToFollowing("WatchItem")) { subReader = reader.ReadSubtree(); subReader.ReadToFollowing("Name"); if (subReader.IsEmptyElement) { txt = ""; } else { txt = subReader.ReadElementContentAsString(); } Equity eq = new Equity(txt); /*** Get Last Data Values ***/ if (subReader.Name != "Last") { subReader.ReadToFollowing("Last"); } if (subReader.IsEmptyElement) { lastPrice = 0; } else { txt = subReader.ReadElementContentAsString(); lastPrice = Double.Parse(txt); } if (subReader.Name != "Change") { subReader.ReadToFollowing("Change"); } if (subReader.IsEmptyElement) { chgStr = ""; } else { chgStr = subReader.ReadElementContentAsString(); } if (subReader.Name != "Date") { subReader.ReadToFollowing("Date"); } if (subReader.IsEmptyElement) { lastDate = DateTime.Today; } else { txt = subReader.ReadElementContentAsString(); lastDate = DateTime.Parse(txt); } eq.LoadDataFromProfile(this, lastPrice, chgStr, lastDate); /****************************/ //Live data url if(subReader.Name != "Source") { subReader.ReadToFollowing("Source"); } if (subReader.IsEmptyElement) { txt = ""; } else { txt = subReader.ReadElementContentAsString(); } eq.LiveDataAddress = txt; //Historical data file if (subReader.Name != "Hist") { subReader.ReadToFollowing("Hist"); } if (subReader.IsEmptyElement) { txt = ""; } else { txt = subReader.ReadElementContentAsString(); } eq.DataFileName = txt; //Historical data file if (subReader.Name != "Listed") { subReader.ReadToFollowing("Listed"); } if (subReader.IsEmptyElement) { txt = ""; } else { txt = subReader.ReadElementContentAsString(); } eq.ListedMarket = txt; this.WatchlistItems.Add(eq); } IsInitializing = false; }
/***************************************************************************** * 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); }
/***************************************************************************** * CONSTRUCTOR: VisualSummaryTabPage * Description: * Parameters: *****************************************************************************/ public VisualSummaryTabPage() { InitializeComponent(); dataSet = new Equity(); InitTechnicalIndicators(); }
/***************************************************************************** * FUNCTION: Parse * Description: Replaces a primitive expression with corresponding numeric values * to enable evaluation. * * Ex. (P < AVG[P][-5..0]) * Parameters: * *****************************************************************************/ private String Parse(String pExpression, Equity pEqIn, int pIndex, List <Fn> pFNs) { string parameter, str_expression, fn_str; double parameter_value = 0.0; string[] split_str; int index1, index2; Variable in_param; str_expression = pExpression; //For each function in the expression being parsed foreach (Fn func in pFNs) { fn_str = ""; if (pExpression.Contains(StringEnum.GetStringValue(func))) { //Get the substring containing only the logical expression for this function index1 = pExpression.IndexOf(StringEnum.GetStringValue(func)); index2 = pExpression.IndexOf("]", index1); if (pExpression.Length > index2 && pExpression.ToCharArray()[index2 + 1] == '[') { index2 = pExpression.IndexOf("]", index2 + 1); } fn_str = pExpression.Substring(index1, index2 - index1 + 1); try { //Evaluate the function and replace the substring in the original parent expression with the value str_expression = str_expression.Replace(fn_str.Trim(), GetFunction(func, pEqIn, fn_str, pIndex).ToString()); } catch (IndexOutOfRangeException) { //The index will be out of range even for a valid command if the function operates on past data that // isn't available at the start of a series. // // Ex. AVG[P][-5..0] --> at the start of the price data series, there aren't 5 previous data points available // to calculate an average on. // // In this case, just return false to allow the rest of the command to be processed. return("false"); } catch (Exception) { errorIndex[0] = index1; errorIndex[1] = index2; return("ERROR"); } } } split_str = str_expression.Split(RuleParserInputs.Comparators, StringSplitOptions.RemoveEmptyEntries); foreach (string exp_part in split_str) { parameter = CleanExpression(exp_part.Trim()).Replace("NOT", ""); if (Helpers.ValidateNumeric(parameter) == false) { in_param = GetParameterType(parameter); try { //If the data to be analyzed is one of the MACD signals, ensure the passed index is valid if (in_param == Variable.MACD_DIFF || in_param == Variable.MACD_SIG) { if (pIndex > (pEqIn.HistoricalPrice.Count() - pEqIn.MACD_C.Count())) { parameter_value = GetParameter(pEqIn, parameter, pIndex); str_expression = str_expression.ReplaceFirstOccurrence(parameter, parameter_value.ToString()); } } else { parameter_value = GetParameter(pEqIn, parameter, pIndex); str_expression = str_expression.ReplaceFirstOccurrence(parameter, parameter_value.ToString()); } } catch (IndexOutOfRangeException) { return("false"); } catch (Exception) { errorIndex[0] = 0; errorIndex[1] = 0; return("ERROR"); } } } return(str_expression); }