hi, i'm trying to create a new custom indicator. i took the sample code for "price relative" indicator and modified it to perform the calculations. It kind of works, but it runs very, very slow. It takes minutes to complete the calculation in daily charts. PSS seems to update the indicator every few seconds which leads to long delays in application's responsivness. Maybe there's something fundamentally wrong (i'm at very early stages of learning this) with my approach?
The code follows:
<pre>
<pss_extension name="Fractal Dimension" version="1.0.20">Fractal Dimension
<author email="" name="" url="" />
<script language="VBScript">
<![CDATA[
class FractalDimensionIndicator
dim y()
dim n,d
dim ymax, ymin
dim reca
public Function InitFD
n = 1
d = 0
Redim y(0)
y(0) = 0
ymax = y(0)
ymin = ymax
End Function
Public Function FD(price)
n = n+1
Redim y(n)
y(n) = price
If y(N) >= ymax THEN ymax = y(N)
If y(N) <= ymin THEN ymin = y(N)
If ymax-ymin <> 0 then
LenCalc y, ymin, ymax, N, Length
if (2*(N - 1)) > 0 and length > 0 then D = 1 + Log(Length) / Log(2*(N - 1))
'D = (d - Int(d))*100
FD=D
End If
End Function
' ****** Len Calc; Subroutine that Calculates the Normalized Length of the Waveform
public Function LenCalc (y(), ymin, ymax, N, Length)
Length = 0
FOR i = 1 TO N
yi = (y(i) - ymin) / (ymax - ymin)
IF (i > 1) THEN Length = Length + SQR((yi - yant) ^ 2 + (1 / (N - 1)) ^ 2)
yant = yi
NEXT
END function ' ***** End of LenCalc *****
' create the chart
public Function Create ( ChartObject )
Set ChartManager = Application.GetObject("ChartManager")
' create the dataset
Set MyDataSet = ChartObject.CreateObject("DataSet")
MyDataSet.ID = "Fractal Dimension"
MyDataSet.Color = "Black"
MyDataSet.PenWidth = 2
ChartObject.AddObject(MyDataSet)
' create a separate canvas, the background rectangle for the chart
Set Canvas = ChartObject.CreateObject("Canvas")
Canvas.ID = "Fractal Dimension"
ChartObject.AddObject(Canvas)
' create a legend for this chart
Set Legend = ChartObject.CreateObject("Legend")
Canvas.AddObject(Legend)
Legend.AddDataSet(MyDataSet)
' create the actual chart object, in this case a line chart
Set LineChart = ChartObject.CreateObject("LineChart")
Canvas.AddObject(LineChart)
LineChart.ID = "Fractal Dimension"
LineChart.AddDataSet(MyDataSet)
' create and add the chart frame
Set Frame = ChartObject.CreateObject("Frame")
Frame.SetRelativeObject(LineChart)
Canvas.AddObject(Frame)
' create and add the axis
Set YAxis = ChartObject.CreateObject("Axis")
YAxis.TranslateReverse = true
YAxis.LabelFormat = "%0.4lf"
LineChart.SetAxis YAxis, "Right", false
LineChart.AddObject(YAxis)
Set XAxis = ChartObject.CreateObject("Axis")
XAxis.TickSize = 0
XAxis.MinorTickSize = 0
XAxis.FontSize = 0
LineChart.SetAxis XAxis, "Bottom", false
LineChart.AddObject(XAxis)
' the Create function needs to return a reference to the chart object
Set Create = LineChart
end Function
' recalculate the indicator based on current settings
public Function Recalc ( ChartObject )
Set ChartManager = Application.GetObject("ChartManager")
' get the data sets to work with
Set MyDataSet = ChartObject.GetDataSet("Fractal Dimension")
Set CloseDataSet = ChartObject.GetDataSet("Close")
Set DateDataSet = ChartObject.GetDataSet("Date")
' find the relative ticker requested by user
Set Doc = Application.ActiveDocument
Set AltTicker = Doc.FindTicker(Nothing, ChartObject.GetParam(0), 0)
' check if the ticker exists in the document
If AltTicker Is Nothing Then
' if ticker was not found, create temporary ticker
Set AltTicker = Doc.CreateTicker
Set Portfolio = Doc.CurrentPortfolio
If Not AltTicker Is Nothing Then
AltTicker.SetProperty "Symbol", ChartObject.GetParam(0)
AltTicker.SetProperty "Visible", "0"
Portfolio.Insert -1, AltTicker
' set the label on this chart
MyDataSet.Label = MyDataSet.ID + " (" + ChartObject.GetParam(0) + ") "
' make sure this ticker gets deleted when the chart is closed
ChartObject.DeferDeleteTicker(AltTicker)
End If
End If
' now that we have a ticker, process the historical data
If Not AltTicker Is Nothing Then
Set AltCloseDataSet = ChartObject.GetDataSetFromTicker(AltTicker, "Close")
LastValidAltCloseData = -1
LastValidCloseData = -1
' make sure we generate the exact same amount of data as in the original data set
MyDataSet.Size = CloseDataSet.Size
' check for a valid data set
If AltCloseDataSet Is Nothing Then
' if there was no data set, set a dummy value so it will at least display the chart
MyDataSet.Data(MyDataSet.Size - 1) = 0
MyDataSet.Label = MyDataSet.ID + " (" + ChartObject.GetParam(0) + ") "
' request historical data from the application
ChartObject.RequestHistoricalDataForTicker(AltTicker)
Else
' loop through all of the data and calculate the indicator
InitFD()
'dim filesys, filetxt, getname, path
'Set filesys = CreateObject("Scripting.FileSystemObject")
' Set filetxt = filesys.CreateTextFile("c:\sndk.txt", True)
'path = filesys.GetAbsolutePathName("c:\sndk.txt")
' getname = filesys.GetFileName(path)
For x = 0 To CloseDataSet.Size - 1
If (CloseDataSet.IsValidData(x) And CloseDataSet.Data(x) > 0) Then
LastValidCloseData = x
MyDataSet.Data(x) = FD(CloseDataSet.Data(x))
'filetxt.WriteLine(CloseDataSet.Data(x))
If (AltCloseDataSet.IsValidData(x) And AltCloseDataSet.Data(x) > 0) Then
LastValidAltCloseData = x
'MyDataSet.Data(x) = CloseDataSet.Data(x) 'CloseDataSet.Data(x) / AltCloseDataSet.Data(x)
End If
End If
Next
'filetxt.Close
' set the label on this chart
If (LastValidAltCloseData >= 0) Then
MyDataSet.Label = MyDataSet.ID + " (" + ChartObject.GetParam(0) + ") " + FormatNumber(MyDataSet.Data(LastValidAltCloseData), 4)
Else
MyDataSet.Label = MyDataSet.ID + " (" + ChartObject.GetParam(0) + ") "
End If
' check data at the end of the range
If LastValidAltCloseData < LastValidCloseData - 2 Then
ChartObject.RequestHistoricalDataForTicker(AltTicker)
End If
End If
End If
end Function
end Class
' ================================================
Set ChartManager = Application.GetObject("ChartManager")
If Not ChartManager Is Nothing Then
Set MyIndicator = ChartManager.RegisterIndicator("Fractal Dimension")
If IsObject(MyIndicator) And Not MyIndicator Is Nothing Then
MyIndicator.ID = "Fractal Dimension"
MyIndicator.Description = "Fractal_Dimension"
MyIndicator.HandlerObject = new FractalDimensionIndicator
MyIndicator.NumParameters = 1
MyIndicator.DefaultParameters = ""
MyIndicator.OverlaysAllowed = "SMA,EMA,T3,TEMA,DEMA,TRIMA,WMA"
MyIndicator.AllowOnIntradayChart = True
End If
End If
]]>
</script>
</pss_extension>
</pre>