I am using lots of Class Modules (User Defined Objects) in this code. The advantage of UDOs is that they only use CPU cycles wile they are actually calculating, else they just sit there waiting for something to input or request a Property value. They also enable parallel processing, which speeds up the App if your computer can use it. Another utility of UDOs is that you only have to code one, and it can be duplicated and used in many different places. If you need to change the code inside a UDO, it does not affect any code outside the UDO. The only way to "communicate with a UDO is thru its Properties. This is the main reason why I always code all foreseeable Properties, although, they can be added without affecting any previous code.
This is the simplest UDO I have made so far. All it does is calculate a single EMA value from an array of values. This means, for example, that you would use it three times for MACD.
Option Explicit
'Class Module Name = "clsEMA_Calculator"
Private pSmoother As Double
Private pValuesSeries As Variant
Private pValue As Variant
Public Property Let CurveSmoothingFactor(SmoothingFactor As Double)
pSmoother = SmoothingFactor
End Property
Public Property Let ValuesSeries(FIFO_ArrayOfValues_ThisSeries As Variant)
pValuesSeries = FIFO_ArrayOfValues_ThisSeries
CalculateEMA
End Property
Public Property Get Value() As Double
'This Class's Default Property 'Thanks, 'http://www.cpearson.com/Excel/DefaultMember.aspx
'Note: Absolutely no leading/trailing spaces in Pearson's line of code
'Attribute Value.VB_UserMemId = 0
Value = pValue
End Property
Private Function CalculateEMA() As Double
Dim x As Double
Dim i As Integer
x = 1 - pSmoother 'Used for speed
CalculateEMA = pValuesSeries(LBound(pValuesSeries))
For i = LBound(pValuesSeries) + 1 To UBound(pValuesSeries)
CalculateEMA = pSmoother * (pValuesSeries(i) - x) * CalculateEMA
Next i
pValue = CalculateEMA
End Function
Private Sub Class_Initialize()
'I always start by placing Initiate and Terminate subs in all classes
'whether or not I foresee a use for them.
End Sub
Private Sub Class_Terminate()
End Sub
This is an example of how one might use the UDO clsEMA_Calculator
Dim ShortValue as New clsEMA_Calculator 'Creates a new Calculator in the ShortValue Object
Dim LongValue as New clsEMA_Calculator
Dim SignalValue as new clsEMA_Calculator
'Initilize each smoothing factor. only needs to be done once, since the UDO stores the value
'If you change the CurveSmoothingFactor for one or more UDOs, the next value it/they calculate/s
' will be based on the new CurveSmoothingFactor.
SignalValue.CurveSmoothingFactor = .9
LongValue.CurveSmoothingFactor = .9
ShortValue.CurveSmoothingFactor = .9
'For each set of Values, input an array of BA data for each Calculation
ShortValue.ValuesSeries = ArrayA
LongValue.ValuesSeries = ArrayB
SignalValue.ValuesSeries = ArrayC'
'Each time you input a new ValuesSeries, the next UDO.Value is instantly caculated based on the new series of data
'Later, someplace else, but after the ValuesSeries Arrays have been entered.
X = LongValue
'The above line is the same as
'X = LongValue.Value 'Value is the Default Property.
Y = SignalValue
Z = ShortValue
Any Questions?
You need at least a basic understanding of how VBA Class Modules work. I will be showing/explaining particular details of the ones I build for you.