/// <summary> /// Downloads and processes historical data for given stock symbol. /// </summary> /// <param name="symbol">stock symbol, e.g. "msft"</param> /// <param name="numYearsOfHistory">years of history > 0, e.g. 10</param> private static void ProcessStockSymbol(string symbol, int numYearsOfHistory) { try { StockData data = DownloadData.GetHistoricalData(symbol, numYearsOfHistory); int N = data.Prices.Count; Task <decimal> T_min = Task.Factory.StartNew <decimal>(() => { return(data.Prices.Min()); } ); Task <decimal> T_max = Task.Factory.StartNew <decimal>(() => { return(data.Prices.Max()); } ); Task <decimal> T_avg = Task.Factory.StartNew <decimal>(() => { return(data.Prices.Average()); } ); Task <double> T_stddev = Task.Factory.StartNew(() => { // Standard deviation: double sum = 0.0; decimal l_avg = data.Prices.Average(); foreach (decimal value in data.Prices) { sum += Math.Pow(Convert.ToDouble(value - l_avg), 2.0); } // // NOTE: want to test exception handling? Uncomment the following to trigger // divide-by-zero, and notice you get 2 task exceptions, one from this code // and one from the continuation task (stderr) that fails because we fail. // //int abc = 0; //int x = 1000 / abc; return(Math.Sqrt(sum / N)); } ); Task <double> T_stderr = T_stddev.ContinueWith((antecedent) => { return(antecedent.Result / Math.Sqrt(N)); } ); // // Wait and harvest results when done: // // NOTE: even though WaitAll is not required for correctness (calls to .Result do // an implicit .Wait), we use WaitAll for efficiency so that we process tasks in // order as they finish (versus an arbitrary order implied by calls to .Result). // try { Task.WaitAll(new Task[] { T_min, T_max, T_avg, T_stddev, T_stderr }); } catch (AggregateException) // tasking errors: { throw; // re-throw, output error messages below: } decimal min = T_min.Result; decimal max = T_max.Result; decimal avg = T_avg.Result; double stddev = T_stddev.Result; double stderr = T_stderr.Result; // // Output: // // NOTE: we build a single output string and then write to the console in one op. // Otherwise, if we output one value at a time, our output might get intermixed // with the output from another, parallel task. Note that Console class is thread- // safe, so this works as long as we make only a single call for our output. // string output = string.Format("\n** {0} **", symbol); output = string.Format("{0}\n Data source: '{1}'", output, data.DataSource); output = string.Format("{0}\n Data points: {1:#,##0}", output, N); output = string.Format("{0}\n Min price: {1:C}", output, min); output = string.Format("{0}\n Max price: {1:C}", output, max); output = string.Format("{0}\n Avg price: {1:C}", output, avg); output = string.Format("{0}\n Std dev/err: {1:0.000} / {2:0.000}", output, stddev, stderr); Console.WriteLine(output); } catch (AggregateException ae) { string output = string.Format("\n** {0} **", symbol); ae = ae.Flatten(); // could have a tree of exceptions, so flatten first: foreach (Exception ex in ae.InnerExceptions) { output = string.Format("{0}\nError: {1}", output, ex.Message); } Console.WriteLine(output); } catch (Exception ex) { string output = string.Format("\n** {0} **\nError: {1}", symbol, ex.Message); Console.WriteLine(output); } }
/// <summary> /// Downloads and processes historical data for given stock symbol. /// </summary> /// <param name="symbol">stock symbol, e.g. "msft"</param> /// <param name="numYearsOfHistory">years of history > 0, e.g. 10</param> private static void ProcessStockSymbol(string symbol, int numYearsOfHistory) { try { StockData data = DownloadData.GetHistoricalData(symbol, numYearsOfHistory); int N = data.Prices.Count; Task <decimal> T_min = Task.Factory.StartNew <decimal>(() => { return(data.Prices.Min()); } ); Task <decimal> T_max = Task.Factory.StartNew <decimal>(() => { return(data.Prices.Max()); } ); Task <decimal> T_avg = Task.Factory.StartNew <decimal>(() => { return(data.Prices.Average()); } ); Task <double> T_stddev = Task.Factory.StartNew(() => { // Standard deviation: double sum = 0.0; decimal l_avg = data.Prices.Average(); foreach (decimal value in data.Prices) { sum += Math.Pow(Convert.ToDouble(value - l_avg), 2.0); } // // NOTE: want to test exception handling? Uncomment the following to trigger // divide-by-zero, and notice you get 2 task exceptions, one from this code // and one from the continuation task (stderr) that fails because we fail. // //int abc = 0; //int x = 1000 / abc; return(Math.Sqrt(sum / N)); } ); Task <double> T_stderr = T_stddev.ContinueWith((antecedent) => { return(antecedent.Result / Math.Sqrt(N)); } ); // // Wait and harvest results when done: // // NOTE: even though WaitAll is not required for correctness (calls to .Result do // an implicit .Wait), we use WaitAll for efficiency so that we process tasks in // order as they finish (versus an arbitrary order implied by calls to .Result). // Task.WaitAll(new Task[] { T_min, T_max, T_avg, T_stddev, T_stderr }); decimal min = T_min.Result; decimal max = T_max.Result; decimal avg = T_avg.Result; double stddev = T_stddev.Result; double stderr = T_stderr.Result; // // Output: // Console.WriteLine(); Console.WriteLine("** {0} **", symbol); Console.WriteLine(" Data source: '{0}'", data.DataSource); Console.WriteLine(" Data points: {0:#,##0}", N); Console.WriteLine(" Min price: {0:C}", min); Console.WriteLine(" Max price: {0:C}", max); Console.WriteLine(" Avg price: {0:C}", avg); Console.WriteLine(" Std dev/err: {0:0.000} / {1:0.000}", stddev, stderr); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("** {0} **", symbol); Console.WriteLine("Error: {0}", ex.Message); } }
/// <summary> /// Downloads and processes historical data for given stock symbol. /// </summary> /// <param name="symbol">stock symbol, e.g. "msft"</param> /// <param name="numYearsOfHistory">years of history > 0, e.g. 10</param> private static void ProcessStockSymbol(string symbol, int numYearsOfHistory) { try { StockData data = DownloadData.GetHistoricalData(symbol, numYearsOfHistory); int N = data.Prices.Count; decimal min = 0, max = 0, avg = 0; Task t_min = Task.Run(() => { min = data.Prices.Min(); }); Task t_max = Task.Run(() => { max = data.Prices.Max(); }); Task t_avg = Task.Run(() => { avg = data.Prices.Average(); }); // Standard deviation: double sum = 0.0; foreach (decimal value in data.Prices) { sum += Math.Pow(Convert.ToDouble(value - avg), 2.0); } double stddev = Math.Sqrt(sum / N); // Standard error: double stderr = stddev / Math.Sqrt(N); // // Output: // Console.WriteLine(); Console.WriteLine("** {0} **", symbol); Console.WriteLine(" Data source: '{0}'", data.DataSource); Console.WriteLine(" Data points: {0:#,##0}", N); t_min.Wait(); Console.WriteLine(" Min price: {0:C}", min); t_max.Wait(); Console.WriteLine(" Max price: {0:C}", max); t_avg.Wait(); Console.WriteLine(" Avg price: {0:C}", avg); Console.WriteLine(" Std dev/err: {0:0.000} / {1:0.000}", stddev, stderr); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("** {0} **", symbol); Console.WriteLine("Error: {0}", ex.Message); } }
/// <summary> /// Tries to download historial data from 3 different web sites, and takes the data /// from the first site that responds. Sites used: nasdaq, yahoo, and msn (although /// msn only provides a year of weekly data, so others are preferred). /// /// NOTE: we use the async web methods BeginGetResponse and EndGetResponse to access /// the web sites asynchronously, with a Task-based facade on top. This has the advantages /// that (1) worker thread is not dedicated to request (i.e. different threads can /// initiate vs. handle callback), and (2) easier to cancel outstanding requests. /// </summary> /// <param name="symbol"></param> /// <param name="numYearsOfHistory"></param> /// <returns></returns> private static StockData GetDataFromInternet(string symbol, int numYearsOfHistory) { // // initiate web requests: // Task <StockData> t_yahoo = GetDataFromYahooAsync(symbol, numYearsOfHistory); Task <StockData> t_nasdaq = GetDataFromNasdaqAsync(symbol, numYearsOfHistory); Task <StockData> t_msn = GetDataFromMsnAsync(symbol, numYearsOfHistory); // // Now wait for the first one to successfully return data (the others we'll cancel): // List <Task <StockData> > tasks = new List <Task <StockData> >(); tasks.Add(t_yahoo); tasks.Add(t_nasdaq); tasks.Add(t_msn); // // WaitOneByOne pattern: first one that returns without exception // StockData result = null; while (tasks.Count > 0) { int timeout = 15 * 1000; // 15 secs: int winner = Task.WaitAny(tasks.ToArray(), timeout); // no task-based exception thrown here: if (winner < 0) // timeout! { break; } // was task successful? Check exception here: if (tasks[winner].Exception == null) // success! { result = tasks[winner].Result; tasks.RemoveAt(winner); break; } // else this task failed, wait for next to finish: tasks.RemoveAt(winner); } // // did we succeed or fail? Either way, first cancel any unfinished requests, // and then return result or throw exception... // foreach (Task t in tasks) // cancel outstanding requests: { (t.AsyncState as RequestState).Request.Abort(); } if (result != null) // success! { return(result); } else { throw new ApplicationException("all web sites failed"); } }
/// <summary> /// Downloads and processes historical data for given stock symbol. /// </summary> /// <param name="symbol">stock symbol, e.g. "msft"</param> /// <param name="numYearsOfHistory">years of history > 0, e.g. 10</param> private static void ProcessStockSymbol(string symbol, int numYearsOfHistory) { try { Task t_error = Task.Factory.StartNew(() => { int i = 10; int j = 10 / i; }); StockData data = DownloadData.GetHistoricalData(symbol, numYearsOfHistory); int N = data.Prices.Count; Task <decimal> t_min = Task.Factory.StartNew(() => { decimal min = data.Prices.Min(); return(min); }); Task <decimal> t_max = Task.Factory.StartNew(() => { decimal max = data.Prices.Max(); return(max); }); Task <decimal> t_avg = Task.Factory.StartNew(() => { decimal avg = data.Prices.Average(); return(avg); }); // Standard deviation: Task <double> t_stddev = Task.Factory.StartNew(() => { double sum = 0.0; decimal l_avg = data.Prices.Average(); foreach (decimal value in data.Prices) { sum += Math.Pow(Convert.ToDouble(value - l_avg), 2.0); } int i = 10; int j = 10 / i; double stddev = Math.Sqrt(sum / N); return(stddev); }); // Standard error: Task <double> t_stderr = t_stddev.ContinueWith((antecedent) => { //t_stddev.Wait(); double stderr = antecedent.Result / Math.Sqrt(N); return(stderr); }); // // Output: // //t_min.Wait(); //t_max.Wait(); //t_avg.Wait(); //t_stddev.Wait(); //t_stderr.Wait(); Task[] tasks = { t_min, t_max, t_avg, t_stddev, t_stderr, t_error }; Task.WaitAll(tasks); //lock (Console.Out) //{ // Console.WriteLine(); // Console.WriteLine("** {0} **", symbol); // Console.WriteLine(" Data source: '{0}'", data.DataSource); // Console.WriteLine(" Data points: {0:#,##0}", N); // Console.WriteLine(" Min price: {0:C}", t_min.Result); // Console.WriteLine(" Max price: {0:C}", t_max.Result); // Console.WriteLine(" Avg price: {0:C}", t_avg.Result); // Console.WriteLine(" Std dev/err: {0:0.000} / {1:0.000}", t_stddev.Result, t_stderr.Result); //} decimal min0 = t_min.Result; decimal max0 = t_max.Result; decimal avg0 = t_avg.Result; double stddev0 = t_stddev.Result; double stderr0 = t_stderr.Result; // // Output: // // NOTE: we build a single output string and then write to the console in one op. // Otherwise, if we output one value at a time, our output might get intermixed // with the output from another, parallel task. Note that Console class is thread- // safe, so this works as long as we make only a single call for our output. // string output = string.Format("\n** {0} **", symbol); output = string.Format("{0}\n Data source: '{1}'", output, data.DataSource); output = string.Format("{0}\n Data points: {1:#,##0}", output, N); output = string.Format("{0}\n Min price: {1:C}", output, min0); output = string.Format("{0}\n Max price: {1:C}", output, max0); output = string.Format("{0}\n Avg price: {1:C}", output, avg0); output = string.Format("{0}\n Std dev/err: {1:0.000} / {2:0.000}", output, stddev0, stderr0); Console.WriteLine(output); } catch (AggregateException ae) { //lock (Console.Out) //{ // Console.WriteLine(); // ae = ae.Flatten(); // foreach (var ex in ae.InnerExceptions) // { // Console.WriteLine("Tasking Error: {0}", ex.Message); // } //} string output = string.Format("\n** {0} **", symbol); ae = ae.Flatten(); // could have a tree of exceptions, so flatten first: foreach (Exception ex in ae.InnerExceptions) { output = string.Format("{0}\nError: {1}", output, ex.Message); } Console.WriteLine(output); } catch (Exception ex) { //lock (Console.Out) //{ // Console.WriteLine(); // Console.WriteLine("** {0} **", symbol); // Console.WriteLine("Error: {0}", ex.Message); //} string output = string.Format("\n** {0} **\nError: {1}", symbol, ex.Message); Console.WriteLine(output); } }
/// <summary> /// Tries to download historial data from 3 different web sites, and takes the data /// from the first site that responds. Sites used: nasdaq, yahoo, and msn (although /// msn only provides a year of weekly data, so others are preferred). /// /// NOTE: we use the async web methods BeginGetResponse and EndGetResponse to access /// the web sites asynchronously, with a Task-based facade on top. This has the advantages /// that (1) worker thread is not dedicated to request (i.e. different threads can /// initiate vs. handle callback), and (2) easier to cancel outstanding requests. /// </summary> /// <param name="symbol"></param> /// <param name="numYearsOfHistory"></param> /// <returns></returns> private static StockData GetDataFromInternet(string symbol, int numYearsOfHistory) { IAsyncResult[] iars = new IAsyncResult[3]; WaitHandle[] handles = new WaitHandle[3]; // // initiate web requests: // Task <StockData> t_yahoo = Task.Factory.StartNew(() => { StockData yahoo = GetDataFromYahoo(symbol, numYearsOfHistory); return(yahoo); }); Task <StockData> t_nasdaq = Task.Factory.StartNew(() => { StockData nasdaq = GetDataFromNasdaq(symbol, numYearsOfHistory); return(nasdaq); }); Task <StockData> t_msn = Task.Factory.StartNew(() => { StockData msn = GetDataFromMsn(symbol, numYearsOfHistory); return(msn); }); List <Task <StockData> > tasks = new List <Task <StockData> >(); tasks.Add(t_yahoo); tasks.Add(t_nasdaq); tasks.Add(t_msn); //Task<StockData>[] tasks = {t_yahoo, t_nasdaq, t_msn}; //WaitOneByOne pattern: first one that returns without exception StockData result = null; while (tasks.Count > 0) { int timeout = 15 * 1000; //15 secs; int winner = Task.WaitAny(tasks.ToArray(), timeout); if (winner < 0) { break; // timeout! } Task <StockData> finished = tasks[winner]; if (finished.Exception == null) { result = finished.Result; tasks.RemoveAt(winner); break; } tasks.RemoveAt(winner); //tasks = tasks.Where(t => t != finished).ToArray(); } // // did we succeed or fail? Either way, first cancel any unfinished requests, // and then return result or throw exception... // foreach (Task t in tasks) // cancel outstanding requests: { (t.AsyncState as RequestState)?.Request.Abort(); } if (result != null) // success! { return(result); } else { throw new ApplicationException("all web sites failed"); } // if we get here, all tasks failed: // throw new ApplicationException("all web sites timed out"); // // wait for first to finish: // //for (int i = 0; i < iars.Length; i++) // handles[i] = (iars[i].AsyncState as RequestState).Done; //int index = WaitHandle.WaitAny(handles, 15 * 1000 /*15 secs*/); //int index = Task.WaitAny(new Task[] {t_yahoo, t_nasdaq, t_msn}); //// //// did *all* the requests timeout? //// //if (index == WaitHandle.WaitTimeout) // if so, cancel and throw exception: //{ // foreach (IAsyncResult iar in iars) // (iar.AsyncState as RequestState).Request.Abort(); // throw new ApplicationException("all web sites timed out"); //} //// //// Otherwise we have a winning request, cancel the others: //// //IAsyncResult winner = iars[index]; //foreach (IAsyncResult iar in iars) // cancel others: // if (iar != winner) // (iar.AsyncState as RequestState).Request.Abort(); //// //// And return the winner's result: //// //RequestState state = winner.AsyncState as RequestState; //if (state.Exception == null) // success! // return state.Result; //else // throw state.Exception; }
/// <summary> /// Downloads and processes historical data for given stock symbol. /// </summary> /// <param name="symbol">stock symbol, e.g. "msft"</param> /// <param name="numYearsOfHistory">years of history > 0, e.g. 10</param> private static void ProcessStockSymbol(string symbol, int numYearsOfHistory) { try { StockData data = DownloadData.GetHistoricalData(symbol, numYearsOfHistory); int N = data.Prices.Count; double stddev, stderr; stddev = stderr = 0.0; Task <decimal> t_min = Task.Factory.StartNew(() => { decimal min = data.Prices.Min(); return(min); } ); Task <decimal> t_max = Task.Factory.StartNew(() => { decimal max = data.Prices.Max(); return(max); } ); Task <decimal> t_avg = Task.Factory.StartNew(() => { decimal avg = data.Prices.Average(); return(avg); } ); // Standard deviation: Task <double> t_stddev = Task.Factory.StartNew(() => { double sum = 0.0; decimal l_avg = data.Prices.Average(); foreach (decimal value in data.Prices) { sum += Math.Pow(Convert.ToDouble(value - l_avg), 2.0); } stddev = Math.Sqrt(sum / N); return(stddev); } ); // Standard error: Task <double> t_stderr = Task.Factory.StartNew(() => { stderr = t_stddev.Result / Math.Sqrt(N); return(stderr); } ); // // Output: // Console.WriteLine(); Console.WriteLine("** {0} **", symbol); Console.WriteLine(" Data source: '{0}'", data.DataSource); Console.WriteLine(" Data points: {0:#,##0}", N); t_min.Wait(); Console.WriteLine(" Min price: {0:C}", t_min.Result); t_max.Wait(); Console.WriteLine(" Max price: {0:C}", t_max.Result); Console.WriteLine(" Avg price: {0:C}", t_avg.Result); Console.WriteLine(" Std dev/err: {0:0.000} / {1:0.000}", t_stddev.Result, t_stderr.Result); } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("** {0} **", symbol); Console.WriteLine("Error: {0}", ex.Message); } }
/// <summary> /// Downloads and processes historical data for given stock symbol. /// </summary> /// <param name="symbol">stock symbol, e.g. "msft"</param> /// <param name="numYearsOfHistory">years of history > 0, e.g. 10</param> private static void ProcessStockSymbol(string symbol, int numYearsOfHistory) { try { //Create .Net exception //Task t_error = Task.Factory.StartNew(() => //{ // int i = 0; // int j = 1000 / i; //}); StockData data = DownloadData.GetHistoricalData(symbol, numYearsOfHistory); int N = data.Prices.Count; //decimal min = 0, max = 0, avg = 0; //Create parallel tasks Task <decimal> t_Min = Task.Factory.StartNew(() => { return(data.Prices.Min()); }); //decimal min = t_Min.Result; Task <decimal> t_Max = Task.Factory.StartNew(() => { return(data.Prices.Max()); }); Task <decimal> t_Avg = Task.Factory.StartNew(() => { return(data.Prices.Average()); }); // Standard deviation: //double sum = 0.0, stddev = 0.0, stderr = 0.0; Task <double> t_stddev = Task.Factory.StartNew(() => { //Use local calculated average value instead of waiting for the global value decimal local_avg = data.Prices.Average(); double sum = 0; foreach (decimal value in data.Prices) { sum += Math.Pow(Convert.ToDouble(value - local_avg), 2.0); } return(Math.Sqrt(sum / N)); }); // double stddev = t_stddev.Result; // Standard error: //Task<double> t_stderr = Task.Factory.StartNew(() => { Task <double> t_stderr = t_stddev.ContinueWith((t) => { //t_stddev.Wait(); //Wait until task is finished return(t.Result / Math.Sqrt(N)); }); //Array of tasks Task[] tasks = { t_Min, t_Max, t_Avg, t_stddev, t_stderr }; //Wait for completion of all tasks Task.WaitAll(tasks); // // Output: // Console.WriteLine(); Console.WriteLine("** {0} **", symbol); Console.WriteLine(" Data source: '{0}'", data.DataSource); Console.WriteLine(" Data points: {0:#,##0}", N); //t_Min.Wait(); //Wait until task is finished Console.WriteLine(" Min price: {0:C}", t_Min.Result); //t_Max.Wait(); //Wait until task is finished Console.WriteLine(" Max price: {0:C}", t_Max.Result); //t_Avg.Wait(); //Wait until task is finished Console.WriteLine(" Avg price: {0:C}", t_Avg.Result); //t_stderr.Wait(); //Wait until task is finished Console.WriteLine(" Std dev/err: {0:0.000} / {1:0.000}", t_stddev.Result, t_stderr.Result); } catch (AggregateException ae) { Console.WriteLine(); //Console.WriteLine("Tasking Error: {0}", ae.InnerException.Message); //Flatten all exceptions since there could be many of them ae = ae.Flatten(); foreach (var err in ae.InnerExceptions) { Console.WriteLine("Tasking Error: {0}", err.Message); } } catch (Exception ex) { Console.WriteLine(); Console.WriteLine("** {0} **", symbol); Console.WriteLine("Error: {0}", ex.Message); } }