Variable Transformations in IronPython QuickStart Sample
Illustrates how to perform a range of transformations on statistical data in IronPython.
This sample is also available in: C#, Visual Basic, F#.
Overview
This QuickStart sample demonstrates how to perform various transformations on time series data using financial market data as an example. It shows how to calculate common technical analysis indicators and statistical measures.
The sample loads Microsoft stock price data and shows how to:
- Perform basic arithmetic operations on numerical variables
- Calculate lagged values and cumulative statistics
- Compute various types of moving averages (simple, exponential, weighted)
- Calculate indicators of change including absolute change and percent change
- Apply the Box-Cox transform for normalizing data
- Implement common technical analysis indicators including:
- Accumulation Distribution
- Chaikin Oscillator
- Bollinger Bands
- Relative Strength Index (RSI)
The code demonstrates how to combine basic transformations to create more complex indicators, while showing proper usage of the Numerics.NET Data Analysis library’s variable transformation capabilities. Error handling and computational efficiency are emphasized throughout the examples.
The code
import numerics
from System import DateTime
from Extreme.Mathematics import *
from Extreme.Statistics import *
from Extreme.Statistics.TimeSeriesAnalysis import *
# Illustrates various kinds of transformations of numerical variables
# by showing how to compute several financial indicators.
# We use a TimeSeriesCollection to load the data.
import clr
clr.AddReference("System.Data")
from System.Data import *
from System.Data.OleDb import *
def LoadTimeSeriesData():
filename = r'..\Data\MicrosoftStock.xls'
connectionString = r'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+filename+';Extended Properties="Excel 8.0;HDR=Yes;IMEX=1"'
cnn = None
ds = DataSet()
try:
cnn = OleDbConnection(connectionString)
cnn.Open()
adapter = OleDbDataAdapter("Select * from [MicrosoftStock$]", cnn)
adapter.Fill(ds)
except OleDbException as ex:
print ex.InnerException
finally:
if cnn != None:
cnn.Close()
return ds.Tables[0]
seriesTable = LoadTimeSeriesData()
timeSeries = TimeSeriesCollection(seriesTable)
open = timeSeries["Open"]
close = timeSeries["Close"]
high = timeSeries["High"]
low = timeSeries["Low"]
volume = 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:
TP = (high + low + close) / 3
# Exponentiation is available through the Power method:
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:
close1 = close.Transforms.GetLag(1)
# You can get cumulative sums and products:
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.
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.
monthyChange = close.Transforms.GetExtrapolatedChange(10, 20)
#
# Moving averages
#
# You can get simple, exponential, and weighted moving averages.
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.
weights = Vector([ 1.0, 2.0, 3.0 ])
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:
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.
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:
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.
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:
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.
SD20 = TP.Transforms.GetMovingStandardDeviation(20, TPMA20)
BOLU = MA20 + 2*SD20
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.
change = close.Transforms.GetChange(1)
RSI = change.Transforms.GetPositiveToNegativeIndex(14, change)
# Finally, let's print some of our results:
index = timeSeries.GetRowIndex(DateTime(2002, 9, 17))
print "Data for September 17, 2002:"
print "Accumulation Distribution (in millions): {0:.2f}".format(AD[index] / 1000000)
print "Chaikin Oscillator (in millions): {0:.2f}".format(CO[index] / 1000000)
print "Bollinger Band (Upper): {0:.2f}".format(BOLU[index])
print "Bollinger Band (Central): {0:.2f}".format(TPMA20[index])
print "Bollinger Band (Lower): {0:.2f}".format(BOLD[index])
print "Relative Strength Index: {0:.2f}".format(RSI[index])