New Version 5.0!

Try it for free with our fully functional 60-day trial version.

Download now!

QuickStart Samples

Variable Transformations QuickStart Sample (C#)

Illustrates how to perform a range of transformations on statistical data in C#.

Visual Basic code F# code IronPython code Back to QuickStart Samples

using System;
using System.Data;
using System.Data.OleDb;

using Extreme.Statistics;
using Extreme.Statistics.TimeSeriesAnalysis;

namespace Extreme.Numerics.QuickStart.CSharp
{
	/// <summary>
	/// Illustrates various kinds of transformations of numerical variables
	/// by showing how to compute several financial indicators.
	/// </summary>
	class VariableTransforms
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{
			// We use a TimeSeriesCollection to load the data.
			DataTable seriesTable = LoadTimeSeriesData();
            TimeSeriesCollection timeSeries = new TimeSeriesCollection(seriesTable);

			NumericalVariable open = (NumericalVariable)timeSeries["Open"];
			NumericalVariable close = (NumericalVariable)timeSeries["Close"];
			NumericalVariable high = (NumericalVariable)timeSeries["High"];
			NumericalVariable low = (NumericalVariable)timeSeries["Low"];
			NumericalVariable volume = (NumericalVariable)timeSeries["Volume"];

			//
			// Arithmetic operations
			//

			// The NumericalVariable class defines the standard
			// arithmetic operators. Operands can be either
			// numerical variables or constants.

			// The Typical Price (TP) is the average of the day's high, low and close:
			NumericalVariable TP = (high + low + close) / 3;

			// Exponentiation is available through the Power method:
			NumericalVariable inverseVolume = NumericalVariable.Power(volume, -1);
			

			//
			// Simple transformations
			//

			// The Transforms property of a numerical variable gives access
			// to a large number of transformations.

			// The GetLag method returns a variable whose observations 
			// are moved ahead by the specified amount:
			NumericalVariable close1 = close.Transforms.GetLag(1);
			// You can get cumulative sums and products:
			NumericalVariable cumVolume = volume.Transforms.GetCumulativeSum();

			//
			// Indicators of change
			//

			// You can get the absolute change, percent change, 
			// or (exponential) growth rate of a variable. The optional
			// parameter is the number of periods to go back.
			// The default is 1.
			NumericalVariable closeChange = close.Transforms.GetChange(10);
			
			// You can extrapolate the change to a longer number of periods.
			// The additional argument is the number of large periods.
			NumericalVariable monthyChange = close.Transforms.GetExtrapolatedChange(10, 20);

			//
			// Moving averages
			//

			// You can get simple, exponential, and weighted moving averages.
			NumericalVariable MA20 = close.Transforms.GetMovingAverage(20);

			// Weighted moving averages can use either a fixed array or vector
			// to specify the weight. The weights are automatically normalized.
			double[] weights = {1.0, 2.0, 3.0};
			NumericalVariable WMA3 = close.Transforms.GetWeightedMovingAverage(weights);
			// You can also specify another variable for the weights.
			// In this case, the corresponding observations are used.
			// For example, to obtain the volume weighted average
			// of the close price over a 14 day period, you can write:
			NumericalVariable VWA14 = close.Transforms.GetWeightedMovingAverage(14, volume);

			// Other statistics, such as maximum, minimum and standard 
			// deviation are also available.

			//
			// Misc. transforms
			//

			// The Box-Cox transform is often used to reduce the effects
			// of non-normality of a variable. It takes one parameter,
			// which must be between 0 and 1.
			NumericalVariable bcVolume = volume.Transforms.GetBoxCoxTransform(0.4);

			//
			// Creating more complicated indicators
			//

			// All these transformations can be combined to create
			// more compicated transformations. We give some examples
			// of common Technical Analysis indicators.

			// The Accumulation Distribution is a leading indicator of price movements.
			// It is used in many other indicators.
			// The formula uses only arithmetic operations:
			NumericalVariable AD = (close - open) / (high - low) * volume;

			// The Chaikin oscillator is used to monitor the flow of money into
			// and out of a market.  It is the difference between a 3 day and a 10 day
			// moving average of the Accumulation Distribution.
			// We use the GetExponentialMovingAverage method for this purpose.
			NumericalVariable	CO = AD.Transforms.GetExponentialMovingAverage(3) 
				- AD.Transforms.GetExponentialMovingAverage(10);

			// Bollinger bands provide an envelope around the price that indicates
			// whether the current price level is relatively high or low.
			// It uses a 20 day simple average as a central line:
			NumericalVariable TPMA20 = TP.Transforms.GetMovingAverage(20);
			// The actual bands are at 2 standard deviations (over the same period)
			// from the central line. We have to pass the moving average
			// over the same period as the second parameter.
			NumericalVariable SD20 = TP.Transforms.GetMovingStandardDeviation(20, TPMA20);
			NumericalVariable BOLU = MA20 + 2*SD20;
			NumericalVariable BOLD = MA20 - 2*SD20;

			// The Relative Strength Index is an index that compares 
			// the average price gain to the average loss.
			// The GetPositiveToNegativeIndex method performs this
			// calculation in one operation. The first argument is the period.
			// The second argument is the variable that determines
			// if an observation counts towards the plus or the minus side.
			NumericalVariable change = close.Transforms.GetChange(1);
			NumericalVariable RSI = change.Transforms.GetPositiveToNegativeIndex(14, change);

			// Finally, let's print some of our results:
			int index = timeSeries.GetRowIndex(new DateTime(2002, 9, 17));
			Console.WriteLine("Data for September 17, 2002:");
			Console.WriteLine("Acumulation Distribution (in millions): {0:F2}", AD[index] / 1000000);
			Console.WriteLine("Chaikin Oscillator (in millions): {0:F2}", CO[index] / 1000000);
			Console.WriteLine("Bollinger Band (Upper): {0:F2}", BOLU[index]);
			Console.WriteLine("Bollinger Band (Central): {0:F2}", TPMA20[index]);
			Console.WriteLine("Bollinger Band (Lower): {0:F2}", BOLD[index]);
			Console.WriteLine("Relative Strength Index: {0:F2}", RSI[index]);

			Console.Write("Press any key to exit.");
			Console.ReadLine();
		}

	
		private static DataTable LoadTimeSeriesData()
		{
			string filename = @"..\..\..\..\Data\MicrosoftStock.xls";
			string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+filename+";Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";
			OleDbConnection cnn = null;
			DataSet ds = new DataSet();
			try
			{
				cnn = new OleDbConnection(connectionString);
				cnn.Open();
				OleDbDataAdapter adapter = new OleDbDataAdapter("Select * from [MicrosoftStock$]", cnn);
				adapter.Fill(	ds);
			}
			catch (OleDbException ex)
			{
				Console.WriteLine(ex.InnerException);
			}
			finally
			{
				if (cnn != null)
					cnn.Close();
			}
			return ds.Tables[0];
		}
	}
}