Path: C:\
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "FinanceChart"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Option Explicit
'/////////////////////////////////////////////////////////////////////////////////////////////////
' Copyright 2012 Advanced Software Engineering Limited
'
' ChartDirector FinanceChart class library
' - Requires ChartDirector Ver 5.1 or above
'
' You may use and modify the code in this file in your application, provided the code and
' its modifications are used only in conjunction with ChartDirector. Usage of this software
' is subjected to the terms and condition of the ChartDirector license.
'/////////////////////////////////////////////////////////////////////////////////////////////////
'/ <summary>
'/ Represents a Financial Chart
'/ </summary>
Private cd As Object
Private base As Object
Private m_totalWidth As Long
Private m_totalHeight As Long
Private m_antiAlias As Boolean
Private m_logScale As Boolean
Private m_axisOnRight As Boolean
Private m_leftMargin As Long
Private m_rightMargin As Long
Private m_topMargin As Long
Private m_bottomMargin As Long
Private m_plotAreaBgColor As Long
Private m_plotAreaBorder As Long
Private m_plotAreaGap As Long
Private m_majorHGridColor As Long
Private m_minorHGridColor As Long
Private m_majorVGridColor As Long
Private m_minorVGridColor As Long
Private m_legendFont As String
Private m_legendFontSize As Double
Private m_legendFontColor As Long
Private m_legendBgColor As Long
Private m_yAxisFont As String
Private m_yAxisFontSize As Double
Private m_yAxisFontColor As Long
Private m_yAxisMargin As Long
Private m_xAxisFont As String
Private m_xAxisFontSize As Double
Private m_xAxisFontColor As Long
Private m_xAxisFontAngle As Double
Private m_timeStamps()
Private m_highData()
Private m_lowData()
Private m_openData()
Private m_closeData()
Private m_volData()
Private m_volUnit As String
Private m_extraPoints As Long
Private m_yearFormat As String
Private m_firstMonthFormat As String
Private m_otherMonthFormat As String
Private m_firstDayFormat As String
Private m_otherDayFormat As String
Private m_firstHourFormat As String
Private m_otherHourFormat As String
Private m_timeLabelSpacing As Long
Private m_generalFormat As String
Private m_toolTipMonthFormat As String
Private m_toolTipDayFormat As String
Private m_toolTipHourFormat As String
Private m_mainChart As Object
Private m_currentChart As Object
Private Sub InitializeMembers()
m_totalWidth = 0
m_totalHeight = 0
m_antiAlias = True
m_logScale = False
m_axisOnRight = True
m_leftMargin = 40
m_rightMargin = 40
m_topMargin = 30
m_bottomMargin = 30
m_plotAreaBgColor = &Hffffff
m_plotAreaBorder = &H888888
m_plotAreaGap = 2
m_majorHGridColor = &Hdddddd
m_minorHGridColor = &Hdddddd
m_majorVGridColor = &Hdddddd
m_minorVGridColor = &Hdddddd
m_legendFont = "normal"
m_legendFontSize = 8
m_legendFontColor = cd.TextColor
m_legendBgColor = &H80cccccc
m_yAxisFont = "normal"
m_yAxisFontSize = 8
m_yAxisFontColor = cd.TextColor
m_yAxisMargin = 14
m_xAxisFont = "normal"
m_xAxisFontSize = 8
m_xAxisFontColor = cd.TextColor
m_xAxisFontAngle = 0
m_timeStamps = Array()
m_highData = Array()
m_lowData = Array()
m_openData = Array()
m_closeData = Array()
m_volData = Array()
m_volUnit = ""
m_extraPoints = 0
m_yearFormat = "{value|yyyy}"
m_firstMonthFormat = "<*font=bold*>{value|mmm yy}"
m_otherMonthFormat = "{value|mmm}"
m_firstDayFormat = "<*font=bold*>{value|d mmm}"
m_otherDayFormat = "{value|d}"
m_firstHourFormat = "<*font=bold*>{value|d mmm<*br*>h:nna}"
m_otherHourFormat = "{value|h:nna}"
m_timeLabelSpacing = 50
m_generalFormat = "P3"
m_toolTipMonthFormat = "[{xLabel|mmm yyyy}]"
m_toolTipDayFormat = "[{xLabel|mmm d, yyyy}]"
m_toolTipHourFormat = "[{xLabel|mmm d, yyyy hh:nn:ss}]"
Set m_mainChart = Nothing
Set m_currentChart = Nothing
End Sub
'/ <summary>
'/ Create a FinanceChart with a given width. The height will be automatically determined
'/ as the chart is built.
'/ </summary>
'/ <param name="width">Width of the chart in pixels</param>
Public Function Init(myAPI, width)
Set cd = myAPI
Set base = cd.MultiChart(width, 1)
InitializeMembers
m_totalWidth = width
Call setMainChart(Base)
Set Init = Me
End Function
'/ <summary>
'/ Enable/Disable anti-alias. Enabling anti-alias makes the line smoother. Disabling
'/ anti-alias make the chart file size smaller, and so can be downloaded faster
'/ through the Internet. The default is to enable anti-alias.
'/ </summary>
'/ <param name="antiAlias">True to enable anti-alias. False to disable anti-alias.</param>
Public Sub enableAntiAlias(antiAlias)
m_antiAlias = antiAlias
End Sub
'/ <summary>
'/ Set the margins around the plot area.
'/ </summary>
'/ <param name="m_leftMargin">The distance between the plot area and the chart left edge.</param>
'/ <param name="m_topMargin">The distance between the plot area and the chart top edge.</param>
'/ <param name="m_rightMargin">The distance between the plot area and the chart right edge.</param>
'/ <param name="m_bottomMargin">The distance between the plot area and the chart bottom edge.</param>
Public Sub setMargins(leftMargin, topMargin, rightMargin, bottomMargin)
m_leftMargin = leftMargin
m_rightMargin = rightMargin
m_topMargin = topMargin
m_bottomMargin = bottomMargin
End Sub
'/ <summary>
'/ Add a text title above the plot area. You may add multiple title above the plot area by
'/ calling this method multiple times.
'/ </summary>
'/ <param name="alignment">The alignment with respect to the region that is on top of the
'/ plot area.</param>
'/ <param name="text">The text to add.</param>
'/ <returns>The TextBox object representing the text box above the plot area.</returns>
Public Function addPlotAreaTitle(alignment, text)
Dim ret As Object
Set ret = addText(m_leftMargin, 0, text, "bold", 10, cd.TextColor, alignment)
Call ret.setSize(m_totalWidth - m_leftMargin - m_rightMargin + 1, m_topMargin - 1)
Call ret.setMargin(0)
Set addPlotAreaTitle = ret
Exit Function
End Function
'/ <summary>
'/ Set the plot area style. The default is to use pale yellow 0xfffff0 as the background,
'/ and light grey 0xdddddd as the grid lines.
'/ </summary>
'/ <param name="bgColor">The plot area background color.</param>
'/ <param name="majorHGridColor">Major horizontal grid color.</param>
'/ <param name="majorVGridColor">Major vertical grid color.</param>
'/ <param name="minorHGridColor">Minor horizontal grid color. In current version, minor
'/ horizontal grid is not used.</param>
'/ <param name="minorVGridColor">Minor vertical grid color.</param>
Public Sub setPlotAreaStyle(bgColor, majorHGridColor, majorVGridColor, minorHGridColor, _
minorVGridColor)
m_plotAreaBgColor = bgColor
m_majorHGridColor = majorHGridColor
m_majorVGridColor = majorVGridColor
m_minorHGridColor = minorHGridColor
m_minorVGridColor = minorVGridColor
End Sub
'/ <summary>
'/ Set the plot area border style. The default is grey color (888888), with a gap
'/ of 2 pixels between charts.
'/ </summary>
'/ <param name="borderColor">The color of the border.</param>
'/ <param name="borderGap">The gap between two charts.</param>
Public Sub setPlotAreaBorder(borderColor, borderGap)
m_plotAreaBorder = borderColor
m_plotAreaGap = borderGap
End Sub
'/ <summary>
'/ Set legend style. The default is Arial 8 pt black color, with light grey background.
'/ </summary>
'/ <param name="font">The font of the legend text.</param>
'/ <param name="fontSize">The font size of the legend text in points.</param>
'/ <param name="fontColor">The color of the legend text.</param>
'/ <param name="bgColor">The background color of the legend box.</param>
Public Sub setLegendStyle(font, fontSize, fontColor, bgColor)
m_legendFont = font
m_legendFontSize = fontSize
m_legendFontColor = fontColor
m_legendBgColor = bgColor
End Sub
'/ <summary>
'/ Set x-axis label style. The default is Arial 8 pt black color no rotation.
'/ </summary>
'/ <param name="font">The font of the axis labels.</param>
'/ <param name="fontSize">The font size of the axis labels in points.</param>
'/ <param name="fontColor">The color of the axis labels.</param>
'/ <param name="fontAngle">The rotation of the axis labels.</param>
Public Sub setXAxisStyle(font, fontSize, fontColor, fontAngle)
m_xAxisFont = font
m_xAxisFontSize = fontSize
m_xAxisFontColor = fontColor
m_xAxisFontAngle = fontAngle
End Sub
'/ <summary>
'/ Set y-axis label style. The default is Arial 8 pt black color, with 13 pixels margin.
'/ </summary>
'/ <param name="font">The font of the axis labels.</param>
'/ <param name="fontSize">The font size of the axis labels in points.</param>
'/ <param name="fontColor">The color of the axis labels.</param>
'/ <param name="axisMargin">The margin at the top of the y-axis in pixels (to leave
'/ space for the legend box).</param>
Public Sub setYAxisStyle(font, fontSize, fontColor, axisMargin)
m_yAxisFont = font
m_yAxisFontSize = fontSize
m_yAxisFontColor = fontColor
m_yAxisMargin = axisMargin
End Sub
'/ <summary>
'/ Set whether the main y-axis is on right of left side of the plot area. The default is
'/ on right.
'/ </summary>
'/ <param name="b">True if the y-axis is on right. False if the y-axis is on left.</param>
Public Sub setAxisOnRight(b)
m_axisOnRight = b
End Sub
'/ <summary>
'/ Determines if log scale should be used for the main chart. The default is linear scale.
'/ </summary>
'/ <param name="b">True for using log scale. False for using linear scale.</param>
Public Sub setLogScale(b)
m_logScale = b
If Not m_mainChart Is Nothing Then
If m_logScale Then
Call m_mainChart.yAxis().setLogScale()
Else
Call m_mainChart.yAxis().setLinearScale()
End If
End If
End Sub
'/ <summary>
'/ Set the date/time formats to use for the x-axis labels under various cases.
'/ </summary>
'/ <param name="yearFormat">The format for displaying labels on an axis with yearly ticks. The
'/ default is "yyyy".</param>
'/ <param name="firstMonthFormat">The format for displaying labels on an axis with monthly ticks.
'/ This parameter applies to the first available month of a year (usually January) only, so it can
'/ be formatted differently from the other labels.</param>
'/ <param name="otherMonthFormat">The format for displaying labels on an axis with monthly ticks.
'/ This parameter applies to months other than the first available month of a year.</param>
'/ <param name="firstDayFormat">The format for displaying labels on an axis with daily ticks.
'/ This parameter applies to the first available day of a month only, so it can be formatted
'/ differently from the other labels.</param>
'/ <param name="otherDayFormat">The format for displaying labels on an axis with daily ticks.
'/ This parameter applies to days other than the first available day of a month.</param>
'/ <param name="firstHourFormat">The format for displaying labels on an axis with hourly
'/ resolution. This parameter applies to the first tick of a day only, so it can be formatted
'/ differently from the other labels.</param>
'/ <param name="otherHourFormat">The format for displaying labels on an axis with hourly.
'/ resolution. This parameter applies to ticks at hourly boundaries, except the first tick
'/ of a day.</param>
Public Sub setDateLabelFormat(yearFormat, firstMonthFormat, otherMonthFormat, firstDayFormat, _
otherDayFormat, firstHourFormat, otherHourFormat)
If yearFormat <> "" Then
m_yearFormat = yearFormat
End If
If firstMonthFormat <> "" Then
m_firstMonthFormat = firstMonthFormat
End If
If otherMonthFormat <> "" Then
m_otherMonthFormat = otherMonthFormat
End If
If firstDayFormat <> "" Then
m_firstDayFormat = firstDayFormat
End If
If otherDayFormat <> "" Then
m_otherDayFormat = otherDayFormat
End If
If firstHourFormat <> "" Then
m_firstHourFormat = firstHourFormat
End If
If otherHourFormat <> "" Then
m_otherHourFormat = otherHourFormat
End If
End Sub
'/ <summary>
'/ Set the minimum label spacing between two labels on the time axis
'/ </summary>
'/ <param name="labelSpacing">The minimum label spacing in pixels.</param>
Public Sub setDateLabelSpacing(labelSpacing)
If labelSpacing > 0 Then
m_timeLabelSpacing = labelSpacing
Else
m_timeLabelSpacing = 0
End If
End Sub
'/ <summary>
'/ Set the tool tip formats for display date/time
'/ </summary>
'/ <param name="monthFormat">The tool tip format to use if the data point spacing is one
'/ or more months (more than 30 days).</param>
'/ <param name="dayFormat">The tool tip format to use if the data point spacing is 1 day
'/ to less than 30 days.</param>
'/ <param name="hourFormat">The tool tip format to use if the data point spacing is less
'/ than 1 day.</param>
Public Sub setToolTipDateFormat(monthFormat, dayFormat, hourFormat)
If monthFormat <> "" Then
m_toolTipMonthFormat = monthFormat
End If
If dayFormat <> "" Then
m_toolTipDayFormat = dayFormat
End If
If hourFormat <> "" Then
m_toolTipHourFormat = hourFormat
End If
End Sub
'/ <summary>
'/ Get the tool tip format for display date/time
'/ </summary>
'/ <returns>The tool tip format string.</returns>
Public Function getToolTipDateFormat()
If UBound(m_timeStamps) < 0 Then
getToolTipDateFormat = m_toolTipHourFormat
Exit Function
End If
If UBound(m_timeStamps) + 1 <= m_extraPoints Then
getToolTipDateFormat = m_toolTipHourFormat
Exit Function
End If
Dim resolution As Double
resolution = (m_timeStamps(UBound(m_timeStamps)) - m_timeStamps(0)) / (UBound(m_timeStamps) +1)
If resolution >= 30 * 86400 Then
getToolTipDateFormat = m_toolTipMonthFormat
Exit Function
ElseIf resolution >= 86400 Then
getToolTipDateFormat = m_toolTipDayFormat
Exit Function
Else
getToolTipDateFormat = m_toolTipHourFormat
Exit Function
End If
End Function
'/ <summary>
'/ Set the number format for use in displaying values in legend keys and tool tips.
'/ </summary>
'/ <param name="formatString">The default number format.</param>
Public Sub setNumberLabelFormat(formatString)
If formatString <> "" Then
m_generalFormat = formatString
End If
End Sub
'/ <summary>
'/ A utility function to compute triangular moving averages
'/ </summary>
'/ <param name="data">An array of numbers as input.</param>
'/ <param name="period">The moving average period.</param>
'/ <returns>An array representing the triangular moving average of the input array.</returns>
Private Function computeTriMovingAvg(data, period)
Dim p As Long
p = period / 2 + 1
computeTriMovingAvg = cd.ArrayMath(data).movAvg(p).movAvg(p).result()
Exit Function
End Function
'/ <summary>
'/ A utility function to compute weighted moving averages
'/ </summary>
'/ <param name="data">An array of numbers as input.</param>
'/ <param name="period">The moving average period.</param>
'/ <returns>An array representing the weighted moving average of the input array.</returns>
Private Function computeWeightedMovingAvg(data, period)
Dim acc As Object
Set acc = cd.ArrayMath(data)
Dim i As Long
For i = 2 To period
Call acc.add(cd.ArrayMath(data).movAvg(i).mul(i).result())
Next
computeWeightedMovingAvg = acc.div((1 + period) * period / 2).result()
Exit Function
End Function
'/ <summary>
'/ A utility function to obtain the first visible closing price.
'/ </summary>
'/ <returns>The first closing price.
'/ are cd.NoValue.</returns>
Private Function firstCloseValue()
Dim i As Long
For i = m_extraPoints To UBound(m_closeData)
If (m_closeData(i) <> cd.NoValue) And (m_closeData(i) <> 0) Then
firstCloseValue = m_closeData(i)
Exit Function
End If
Next
firstCloseValue = cd.NoValue
Exit Function
End Function
'/ <summary>
'/ A utility function to obtain the last valid position (that is, position not
'/ containing cd.NoValue) of a data series.
'/ </summary>
'/ <param name="data">An array of numbers as input.</param>
'/ <returns>The last valid position in the input array, or -1 if all positions
'/ are cd.NoValue.</returns>
Private Function lastIndex(data)
Dim i As Long
i = UBound(data)
Do While i >= 0
If data(i) <> cd.NoValue Then
Exit Do
End If
i = i - 1
Loop
lastIndex = i
Exit Function
End Function
'/ <summary>
'/ Set the data used in the chart. If some of the data are not available, some artifical
'/ values should be used. For example, if the high and low values are not available, you
'/ may use closeData as highData and lowData.
'/ </summary>
'/ <param name="timeStamps">An array of dates/times for the time intervals.</param>
'/ <param name="highData">The high values in the time intervals.</param>
'/ <param name="lowData">The low values in the time intervals.</param>
'/ <param name="openData">The open values in the time intervals.</param>
'/ <param name="closeData">The close values in the time intervals.</param>
'/ <param name="volData">The volume values in the time intervals.</param>
'/ <param name="extraPoints">The number of leading time intervals that are not
'/ displayed in the chart. These intervals are typically used for computing
'/ indicators that require extra leading data, such as moving averages.</param>
Public Sub setData(timeStamps, highData, lowData, openData, closeData, volData, extraPoints)
m_timeStamps = cd.CTime(timeStamps)
m_highData = highData
m_lowData = lowData
m_openData = openData
m_closeData = closeData
If extraPoints > 0 Then
m_extraPoints = extraPoints
Else
m_extraPoints = 0
End If
'///////////////////////////////////////////////////////////////////////
' Auto-detect volume units
'///////////////////////////////////////////////////////////////////////
Dim maxVol As Double
maxVol = cd.ArrayMath(volData).max()
Dim units()
units = Array("", "K", "M", "B")
Dim unitIndex As Long
unitIndex = UBound(units)
Do While (unitIndex > 0) And (maxVol < 1000 ^ unitIndex)
unitIndex = unitIndex - 1
Loop
m_volData = cd.ArrayMath(volData).div(1000 ^ unitIndex).result()
m_volUnit = units(unitIndex)
End Sub
'////////////////////////////////////////////////////////////////////////////
' Format x-axis labels
'////////////////////////////////////////////////////////////////////////////
Private Sub setXLabels(a)
Call a.setLabels2(m_timeStamps)
If m_extraPoints < UBound(m_timeStamps) + 1 Then
Dim tickStep As Long
tickStep = Int((UBound(m_timeStamps) + 1 - m_extraPoints) * m_timeLabelSpacing / ( _
m_totalWidth - m_leftMargin - m_rightMargin)) + 1
Dim timeRangeInSeconds As Double
timeRangeInSeconds = m_timeStamps(UBound(m_timeStamps)) - m_timeStamps(m_extraPoints)
Dim secondsBetweenTicks As Double
secondsBetweenTicks = timeRangeInSeconds / (m_totalWidth - m_leftMargin - m_rightMargin) * _
m_timeLabelSpacing
If secondsBetweenTicks * (UBound(m_timeStamps) + 1 - m_extraPoints) <= timeRangeInSeconds _
Then
tickStep = 1
If UBound(m_timeStamps) + 1 > 1 Then
secondsBetweenTicks = m_timeStamps(UBound(m_timeStamps)) - m_timeStamps( _
UBound(m_timeStamps) + 1 - 2)
Else
secondsBetweenTicks = 86400
End If
End If
If (secondsBetweenTicks > 360 * 86400) Or ((secondsBetweenTicks > 90 * 86400) And ( _
timeRangeInSeconds >= 720 * 86400)) Then
'yearly ticks
Call a.setMultiFormat2(cd.StartOfYearFilter(), m_yearFormat, tickStep)
ElseIf (secondsBetweenTicks >= 30 * 86400) Or ((secondsBetweenTicks > 7 * 86400) And ( _
timeRangeInSeconds >= 60 * 86400)) Then
'monthly ticks
Dim monthBetweenTicks As Long
monthBetweenTicks = Int(secondsBetweenTicks / 31 / 86400) + 1
Call a.setMultiFormat(cd.StartOfYearFilter(), m_firstMonthFormat, _
cd.StartOfMonthFilter(monthBetweenTicks), m_otherMonthFormat)
Call a.setMultiFormat2(cd.StartOfMonthFilter(), "-", 1, False)
ElseIf (secondsBetweenTicks >= 86400) Or ((secondsBetweenTicks > 6 * 3600) And ( _
timeRangeInSeconds >= 86400)) Then
'daily ticks
Call a.setMultiFormat(cd.StartOfMonthFilter(), m_firstDayFormat, cd.StartOfDayFilter( _
1, 0.5), m_otherDayFormat, tickStep)
Else
'hourly ticks
Call a.setMultiFormat(cd.StartOfDayFilter(1, 0.5), m_firstHourFormat, _
cd.StartOfHourFilter(1, 0.5), m_otherHourFormat, tickStep)
End If
End If
End Sub
'////////////////////////////////////////////////////////////////////////////
' Create tool tip format string for showing OHLC data
'////////////////////////////////////////////////////////////////////////////
Private Function getHLOCToolTipFormat()
getHLOCToolTipFormat = "title='" & getToolTipDateFormat() & " Op:{open|" & m_generalFormat & _
"}, Hi:{high|" & m_generalFormat & "}, Lo:{low|" & m_generalFormat & "}, Cl:{close|" & _
m_generalFormat & "}'"
Exit Function
End Function
'/ <summary>
'/ Add the main chart - the chart that shows the HLOC data.
'/ </summary>
'/ <param name="height">The height of the main chart in pixels.</param>
'/ <returns>An XYChart object representing the main chart created.</returns>
Public Function addMainChart(height)
Set m_mainChart = addIndicator(height)
Call m_mainChart.yAxis().setMargin(2 * m_yAxisMargin)
If m_logScale Then
Call m_mainChart.yAxis().setLogScale()
Else
Call m_mainChart.yAxis().setLinearScale()
End If
Set addMainChart = m_mainChart
Exit Function
End Function
'/ <summary>
'/ Add a candlestick layer to the main chart.
'/ </summary>
'/ <param name="upColor">The candle color for an up day.</param>
'/ <param name="downColor">The candle color for a down day.</param>
'/ <returns>The CandleStickLayer created.</returns>
Public Function addCandleStick(upColor, downColor)
Call addOHLCLabel(upColor, downColor, True)
Dim ret As Object
Set ret = m_mainChart.addCandleStickLayer(m_highData, m_lowData, m_openData, m_closeData, _
upColor, downColor)
Call ret.setHTMLImageMap("", "", getHLOCToolTipFormat())
If UBound(m_highData) + 1 - m_extraPoints > 60 Then
Call ret.setDataGap(0)
End If
If UBound(m_highData) + 1 > m_extraPoints Then
Dim expectedWidth As Long
expectedWidth = Int((m_totalWidth - m_leftMargin - m_rightMargin) / (UBound(m_highData) + _
1 - m_extraPoints))
If expectedWidth <= 5 Then
Call ret.setDataWidth(expectedWidth + 1 - expectedWidth Mod 2)
End If
End If
Set addCandleStick = ret
Exit Function
End Function
'/ <summary>
'/ Add a HLOC layer to the main chart.
'/ </summary>
'/ <param name="upColor">The color of the HLOC symbol for an up day.</param>
'/ <param name="downColor">The color of the HLOC symbol for a down day.</param>
'/ <returns>The HLOCLayer created.</returns>
Public Function addHLOC(upColor, downColor)
Call addOHLCLabel(upColor, downColor, False)
Dim ret As Object
Set ret = m_mainChart.addHLOCLayer(m_highData, m_lowData, m_openData, m_closeData)
Call ret.setColorMethod(cd.HLOCUpDown, upColor, downColor)
Call ret.setHTMLImageMap("", "", getHLOCToolTipFormat())
Call ret.setDataGap(0)
Set addHLOC = ret
Exit Function
End Function
Private Sub addOHLCLabel(upColor, downColor, candleStickMode)
Dim i As Long
i = lastIndex(m_closeData)
If i >= 0 Then
Dim openValue As Double
openValue = cd.NoValue
Dim closeValue As Double
closeValue = cd.NoValue
Dim highValue As Double
highValue = cd.NoValue
Dim lowValue As Double
lowValue = cd.NoValue
If i < UBound(m_openData) + 1 Then
openValue = m_openData(i)
End If
If i < UBound(m_closeData) + 1 Then
closeValue = m_closeData(i)
End If
If i < UBound(m_highData) + 1 Then
highValue = m_highData(i)
End If
If i < UBound(m_lowData) + 1 Then
lowValue = m_lowData(i)
End If
Dim openLabel As String
openLabel = ""
Dim closeLabel As String
closeLabel = ""
Dim highLabel As String
highLabel = ""
Dim lowLabel As String
lowLabel = ""
Dim delim As String
delim = ""
If openValue <> cd.NoValue Then
openLabel = "Op:" & formatValue(openValue, m_generalFormat)
delim = ", "
End If
If highValue <> cd.NoValue Then
highLabel = delim & "Hi:" & formatValue(highValue, m_generalFormat)
delim = ", "
End If
If lowValue <> cd.NoValue Then
lowLabel = delim & "Lo:" & formatValue(lowValue, m_generalFormat)
delim = ", "
End If
If closeValue <> cd.NoValue Then
closeLabel = delim & "Cl:" & formatValue(closeValue, m_generalFormat)
delim = ", "
End If
Dim label As String
label = openLabel & highLabel & lowLabel & closeLabel
Dim useUpColor As Boolean
useUpColor = (closeValue >= openValue)
If candleStickMode <> True Then
Dim closeChanges()
closeChanges = cd.ArrayMath(m_closeData).delta().result()
Dim lastChangeIndex As Long
lastChangeIndex = lastIndex(closeChanges)
useUpColor = (lastChangeIndex < 0)
If useUpColor <> True Then
useUpColor = (closeChanges(lastChangeIndex) >= 0)
End If
End If
Dim udcolor As Long
udcolor = downColor
If useUpColor Then
udcolor = upColor
End If
Call m_mainChart.getLegend().addKey(label, udcolor)
End If
End Sub
'/ <summary>
'/ Add a closing price line on the main chart.
'/ </summary>
'/ <param name="color">The color of the line.</param>
'/ <returns>The LineLayer object representing the line created.</returns>
Public Function addCloseLine(color)
Set addCloseLine = addLineIndicator2(m_mainChart, m_closeData, color, "Closing Price")
Exit Function
End Function
'/ <summary>
'/ Add a weight close line on the main chart.
'/ </summary>
'/ <param name="color">The color of the line.</param>
'/ <returns>The LineLayer object representing the line created.</returns>
Public Function addWeightedClose(color)
Set addWeightedClose = addLineIndicator2(m_mainChart, cd.ArrayMath(m_highData).add(m_lowData _
).add(m_closeData).add(m_closeData).div(4).result(), color, "Weighted Close")
Exit Function
End Function
'/ <summary>
'/ Add a typical price line on the main chart.
'/ </summary>
'/ <param name="color">The color of the line.</param>
'/ <returns>The LineLayer object representing the line created.</returns>
Public Function addTypicalPrice(color)
Set addTypicalPrice = addLineIndicator2(m_mainChart, cd.ArrayMath(m_highData).add(m_lowData _
).add(m_closeData).div(3).result(), color, "Typical Price")
Exit Function
End Function
'/ <summary>
'/ Add a median price line on the main chart.
'/ </summary>
'/ <param name="color">The color of the line.</param>
'/ <returns>The LineLayer object representing the line created.</returns>
Public Function addMedianPrice(color)
Set addMedianPrice = addLineIndicator2(m_mainChart, cd.ArrayMath(m_highData).add(m_lowData _
).div(2).result(), color, "Median Price")
Exit Function
End Function
'/ <summary>
'/ Add a simple moving average line on the main chart.
'/ </summary>
'/ <param name="period">The moving average period</param>
'/ <param name="color">The color of the line.</param>
'/ <returns>The LineLayer object representing the line created.</returns>
Public Function addSimpleMovingAvg(period, color)
Dim label As String
label = "SMA (" & period & ")"
Set addSimpleMovingAvg = addLineIndicator2(m_mainChart, cd.ArrayMath(m_closeData).movAvg( _
period).result(), color, label)
Exit Function
End Function
'/ <summary>
'/ Add an exponential moving average line on the main chart.
'/ </summary>
'/ <param name="period">The moving average period</param>
'/ <param name="color">The color of the line.</param>
'/ <returns>The LineLayer object representing the line created.</returns>
Public Function addExpMovingAvg(period, color)
Dim label As String
label = "EMA (" & period & ")"
Set addExpMovingAvg = addLineIndicator2(m_mainChart, cd.ArrayMath(m_closeData).expAvg(2.0 / ( _
period + 1)).result(), color, label)
Exit Function
End Function
'/ <summary>
'/ Add a triangular moving average line on the main chart.
'/ </summary>
'/ <param name="period">The moving average period</param>
'/ <param name="color">The color of the line.</param>
'/ <returns>The LineLayer object representing the line created.</returns>
Public Function addTriMovingAvg(period, color)
Dim label As String
label = "TMA (" & period & ")"
Set addTriMovingAvg = addLineIndicator2(m_mainChart, cd.ArrayMath(computeTriMovingAvg( _
m_closeData, period)).result(), color, label)
Exit Function
End Function
'/ <summary>
'/ Add a weighted moving average line on the main chart.
'/ </summary>
'/ <param name="period">The moving average period</param>
'/ <param name="color">The color of the line.</param>
'/ <returns>The LineLayer object representing the line created.</returns>
Public Function addWeightedMovingAvg(period, color)
Dim label As String
label = "WMA (" & period & ")"
Set addWeightedMovingAvg = addLineIndicator2(m_mainChart, cd.ArrayMath( _
computeWeightedMovingAvg(m_closeData, period)).result(), color, label)
Exit Function
End Function
'/ <summary>
'/ Add a parabolic SAR indicator to the main chart.
'/ </summary>
'/ <param name="accInitial">Initial acceleration factor</param>
'/ <param name="accIncrement">Acceleration factor increment</param>
'/ <param name="accMaximum">Maximum acceleration factor</param>
'/ <param name="symbolType">The symbol used to plot the parabolic SAR</param>
'/ <param name="symbolSize">The symbol size in pixels</param>
'/ <param name="fillColor">The fill color of the symbol</param>
'/ <param name="edgeColor">The edge color of the symbol</param>
'/ <returns>The LineLayer object representing the layer created.</returns>
Public Function addParabolicSAR(accInitial, accIncrement, accMaximum, symbolType, symbolSize, _
fillColor, edgeColor)
Dim isLong As Boolean
isLong = True
Dim acc As Double
acc = accInitial
Dim extremePoint As Double
extremePoint = 0
ReDim psar(UBound(m_lowData))
Dim i_1 As Long
i_1 = -1
Dim i_2 As Long
i_2 = -1
Dim i As Long
For i = 0 To UBound(m_lowData)
psar(i) = cd.NoValue
If (m_lowData(i) <> cd.NoValue) And (m_highData(i) <> cd.NoValue) Then
If (i_1 >= 0) And (i_2 < 0) Then
If m_lowData(i_1) <= m_lowData(i) Then
psar(i) = m_lowData(i_1)
isLong = True
If m_highData(i_1) > m_highData(i) Then
extremePoint = m_highData(i_1)
Else
extremePoint = m_highData(i)
End If
Else
extremePoint = m_lowData(i)
isLong = False
If m_highData(i_1) > m_highData(i) Then
psar(i) = m_highData(i_1)
Else
psar(i) = m_highData(i)
End If
End If
ElseIf (i_1 >= 0) And (i_2 >= 0) Then
If acc > accMaximum Then
acc = accMaximum
End If
psar(i) = psar(i_1) + acc * (extremePoint - psar(i_1))
If isLong Then
If m_lowData(i) < psar(i) Then
isLong = False
psar(i) = extremePoint
extremePoint = m_lowData(i)
acc = accInitial
Else
If m_highData(i) > extremePoint Then
extremePoint = m_highData(i)
acc = acc + accIncrement
End If
If m_lowData(i_1) < psar(i) Then
psar(i) = m_lowData(i_1)
End If
If m_lowData(i_2) < psar(i) Then
psar(i) = m_lowData(i_2)
End If
End If
Else
If m_highData(i) > psar(i) Then
isLong = True
psar(i) = extremePoint
extremePoint = m_highData(i)
acc = accInitial
Else
If m_lowData(i) < extremePoint Then
extremePoint = m_lowData(i)
acc = acc + accIncrement
End If
If m_highData(i_1) > psar(i) Then
psar(i) = m_highData(i_1)
End If
If m_highData(i_2) > psar(i) Then
psar(i) = m_highData(i_2)
End If
End If
End If
End If
i_2 = i_1
i_1 = i
End If
Next
Dim ret As Object
Set ret = addLineIndicator2(m_mainChart, psar, fillColor, "Parabolic SAR")
Call ret.setLineWidth(0)
Set ret = addLineIndicator2(m_mainChart, psar, fillColor, "")
Call ret.setLineWidth(0)
Call ret.getDataSet(0).setDataSymbol(symbolType, symbolSize, fillColor, edgeColor)
Set addParabolicSAR = ret
Exit Function
End Function
'/ <summary>
'/ Add a comparison line to the main price chart.
'/ </summary>
'/ <param name="data">The data series to compare to</param>
'/ <param name="color">The color of the comparison line</param>
'/ <param name="name">The name of the comparison line</param>
'/ <returns>The LineLayer object representing the line layer created.</returns>
Public Function addComparison(data, color, name)
Dim firstIndex As Long
firstIndex = m_extraPoints
Do While (firstIndex < UBound(data) + 1) And (firstIndex < UBound(m_closeData) + 1)
If (data(firstIndex) <> cd.NoValue) And (m_closeData(firstIndex) <> cd.NoValue) And (data( _
firstIndex) <> 0) And (m_closeData(firstIndex) <> 0) Then
Exit Do
End If
firstIndex = firstIndex + 1
Loop
If (firstIndex >= UBound(data) + 1) Or (firstIndex >= UBound(m_closeData) + 1) Then
Set addComparison = Nothing
Exit Function
End If
Dim scaleFactor As Double
scaleFactor = m_closeData(firstIndex) / data(firstIndex)
Dim layer As Object
Set layer = m_mainChart.addLineLayer(cd.ArrayMath(data).mul(scaleFactor).result(), _
cd.Transparent)
Call layer.setHTMLImageMap("{disable}")
Dim a As Object
Set a = m_mainChart.addAxis(cd.Right, 0)
Call a.setColors(cd.Transparent, cd.Transparent)
Call a.syncAxis(m_mainChart.yAxis(), 1 / scaleFactor, 0)
Dim ret As Object
Set ret = addLineIndicator2(m_mainChart, data, color, name)
Call ret.setUseYAxis(a)
Set addComparison = ret
Exit Function
End Function
'/ <summary>
'/ Display percentage axis scale
'/ </summary>
'/ <returns>The Axis object representing the percentage axis.</returns>
Public Function setPercentageAxis()
Dim firstClose As Double
firstClose = firstCloseValue()
If firstClose = cd.NoValue Then
Set setPercentageAxis = Nothing
Exit Function
End If
Dim axisAlign As Long
axisAlign = cd.Left
If m_axisOnRight Then
axisAlign = cd.Right
End If
Dim ret As Object
Set ret = m_mainChart.addAxis(axisAlign, 0)
Call configureYAxis(ret, 300)
Call ret.syncAxis(m_mainChart.yAxis(), 100 / firstClose)
Call ret.setRounding(False, False)
Call ret.setLabelFormat("{={value}-100|@}%")
Call m_mainChart.yAxis().setColors(cd.Transparent, cd.Transparent)
Call m_mainChart.getPlotArea().setGridAxis(Empty, ret)
Set setPercentageAxis = ret
Exit Function
End Function
'/ <summary>
'/ Add a generic band to the main finance chart. This method is used internally by other methods to add
'/ various bands (eg. Bollinger band, Donchian channels, etc).
'/ </summary>
'/ <param name="upperLine">The data series for the upper band line.</param>
'/ <param name="lowerLine">The data series for the lower band line.</param>
'/ <param name="lineColor">The color of the upper and lower band line.</param>
'/ <param name="fillColor">The color to fill the region between the upper and lower band lines.</param>
'/ <param name="name">The name of the band.</param>
'/ <returns>An InterLineLayer object representing the filled region.</returns>
Public Function addBand(upperLine, lowerLine, lineColor, fillColor, name)
Dim i As Long
i = UBound(upperLine)
If i >= UBound(lowerLine) + 1 Then
i = UBound(lowerLine)
End If
Do While i >= 0
If (upperLine(i) <> cd.NoValue) And (lowerLine(i) <> cd.NoValue) Then
name = name & ": " & formatValue(lowerLine(i), m_generalFormat) & " - " & formatValue( _
upperLine(i), m_generalFormat)
Exit Do
End If
i = i - 1
Loop
Dim layer As Object
Set layer = m_mainChart.addLineLayer2()
Call layer.addDataSet(upperLine, lineColor, name)
Call layer.addDataSet(lowerLine, lineColor)
Set addBand = m_mainChart.addInterLineLayer(layer.getLine(0), layer.getLine(1), fillColor)
Exit Function
End Function
'/ <summary>
'/ Add a Bollinger band on the main chart.
'/ </summary>
'/ <param name="period">The period to compute the band.</param>
'/ <param name="bandWidth">The half-width of the band in terms multiples of standard deviation. Typically 2 is used.</param>
'/ <param name="lineColor">The color of the lines defining the upper and lower limits.</param>
'/ <param name="fillColor">The color to fill the regional within the band.</param>
'/ <returns>The InterLineLayer object representing the band created.</returns>
Public Function addBollingerBand(period, bandWidth, lineColor, fillColor)
'Bollinger Band is moving avg +/- (width * moving std deviation)
Dim stdDev()
stdDev = cd.ArrayMath(m_closeData).movStdDev(period).mul(bandWidth).result()
Dim movAvg()
movAvg = cd.ArrayMath(m_closeData).movAvg(period).result()
Dim label As String
label = "Bollinger (" & period & ", " & bandWidth & ")"
Set addBollingerBand = addBand(cd.ArrayMath(movAvg).add(stdDev).result(), cd.ArrayMath(movAvg _
).subtract(stdDev).selectGTZ(Empty, 0).result(), lineColor, fillColor, label)
Exit Function
End Function
'/ <summary>
'/ Add a Donchian channel on the main chart.
'/ </summary>
'/ <param name="period">The period to compute the band.</param>
'/ <param name="lineColor">The color of the lines defining the upper and lower limits.</param>
'/ <param name="fillColor">The color to fill the regional within the band.</param>
'/ <returns>The InterLineLayer object representing the band created.</returns>
Public Function addDonchianChannel(period, lineColor, fillColor)
'Donchian Channel is the zone between the moving max and moving min
Dim label As String
label = "Donchian (" & period & ")"
Set addDonchianChannel = addBand(cd.ArrayMath(m_highData).movMax(period).result(), _
cd.ArrayMath(m_lowData).movMin(period).result(), lineColor, fillColor, label)
Exit Function
End Function
'/ <summary>
'/ Add a price envelop on the main chart. The price envelop is a defined as a ratio around a
'/ moving average. For example, a ratio of 0.2 means 20% above and below the moving average.
'/ </summary>
'/ <param name="period">The period for the moving average.</param>
'/ <param name="range">The ratio above and below the moving average.</param>
'/ <param name="lineColor">The color of the lines defining the upper and lower limits.</param>
'/ <param name="fillColor">The color to fill the regional within the band.</param>
'/ <returns>The InterLineLayer object representing the band created.</returns>
Public Function addEnvelop(period, range, lineColor, fillColor)
'Envelop is moving avg +/- percentage
Dim movAvg()
movAvg = cd.ArrayMath(m_closeData).movAvg(period).result()
Dim label As String
label = "Envelop (SMA " & period & " +/- " & Int(range * 100) & "%)"
Set addEnvelop = addBand(cd.ArrayMath(movAvg).mul(1 + range).result(), cd.ArrayMath(movAvg _
).mul(1 - range).result(), lineColor, fillColor, label)
Exit Function
End Function
'/ <summary>
'/ Add a volume bar chart layer on the main chart.
'/ </summary>
'/ <param name="height">The height of the bar chart layer in pixels.</param>
'/ <param name="upColor">The color to used on an 'up' day. An 'up' day is a day where
'/ the closing price is higher than that of the previous day.</param>
'/ <param name="downColor">The color to used on a 'down' day. A 'down' day is a day
'/ where the closing price is lower than that of the previous day.</param>
'/ <param name="flatColor">The color to used on a 'flat' day. A 'flat' day is a day
'/ where the closing price is the same as that of the previous day.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addVolBars(height, upColor, downColor, flatColor)
Set addVolBars = addVolBars2(m_mainChart, height, upColor, downColor, flatColor)
Exit Function
End Function
Private Function addVolBars2(c, height, upColor, downColor, flatColor)
Dim barLayer As Object
Set barLayer = c.addBarLayer2(cd.Overlay)
Call barLayer.setBorderColor(cd.Transparent)
If c Is m_mainChart Then
Call configureYAxis(c.yAxis2(), height)
Dim topMargin As Long
topMargin = c.getDrawArea().getHeight() - m_topMargin - m_bottomMargin - height + _
m_yAxisMargin
If topMargin < 0 Then
topMargin = 0
End If
Call c.yAxis2().setTopMargin(topMargin)
Call barLayer.setUseYAxis2()
End If
Dim a As Object
Set a = c.yAxis2()
If Not c Is m_mainChart Then
Set a = c.yAxis()
End If
If cd.ArrayMath(m_volData).max() < 10 Then
Call a.setLabelFormat("{value|1}" & m_volUnit)
Else
Call a.setLabelFormat("{value}" & m_volUnit)
End If
Dim closeChange()
closeChange = cd.ArrayMath(m_closeData).delta().replace(cd.NoValue, 0).result()
Dim i As Long
i = lastIndex(m_volData)
Dim label As String
label = "Vol"
If i >= 0 Then
label = label & ": " & formatValue(m_volData(i), m_generalFormat) & m_volUnit
End If
Dim upDS As Object
Set upDS = barLayer.addDataSet(cd.ArrayMath(m_volData).selectGTZ(closeChange).result(), _
upColor)
Dim dnDS As Object
Set dnDS = barLayer.addDataSet(cd.ArrayMath(m_volData).selectLTZ(closeChange).result(), _
downColor)
Dim flatDS As Object
Set flatDS = barLayer.addDataSet(cd.ArrayMath(m_volData).selectEQZ(closeChange).result(), _
flatColor)
If (i < 0) Or (closeChange(i) = 0) Or (closeChange(i) = cd.NoValue) Then
Call flatDS.setDataName(label)
ElseIf closeChange(i) > 0 Then
Call upDS.setDataName(label)
Else
Call dnDS.setDataName(label)
End If
Set addVolBars2 = barLayer
Exit Function
End Function
'/ <summary>
'/ Add a blank indicator chart to the finance chart. Used internally to add other indicators.
'/ Override to change the default formatting (eg. axis fonts, etc.) of the various indicators.
'/ </summary>
'/ <param name="height">The height of the chart in pixels.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addIndicator(height)
'create a new chart object
Dim ret As Object
Set ret = cd.XYChart(m_totalWidth, height + m_topMargin + m_bottomMargin, cd.Transparent)
Call ret.setTrimData(m_extraPoints)
If Not m_currentChart Is Nothing Then
'if there is a chart before the newly created chart, disable its x-axis, and copy
'its x-axis labels to the new chart
Call m_currentChart.xAxis().setColors(cd.Transparent, cd.Transparent)
Call ret.xAxis().copyAxis(m_currentChart.xAxis())
'add chart to MultiChart and update the total height
Call addChart(0, m_totalHeight + m_plotAreaGap, ret)
m_totalHeight = m_totalHeight + height + 1 + m_plotAreaGap
Else
'no existing chart - create the x-axis labels from scratch
Call setXLabels(ret.xAxis())
'add chart to MultiChart and update the total height
Call addChart(0, m_totalHeight, ret)
m_totalHeight = m_totalHeight + height + 1
End If
'the newly created chart becomes the current chart
Set m_currentChart = ret
'update the size
Call setSize(m_totalWidth, m_totalHeight + m_topMargin + m_bottomMargin)
'configure the plot area
Call ret.setPlotArea(m_leftMargin, m_topMargin, m_totalWidth - m_leftMargin - m_rightMargin, _
height, m_plotAreaBgColor, -1, m_plotAreaBorder).setGridColor(m_majorHGridColor, _
m_majorVGridColor, m_minorHGridColor, m_minorVGridColor)
Call ret.setAntiAlias(m_antiAlias)
'configure legend box
If m_legendFontColor <> cd.Transparent Then
Dim box As Object
Set box = ret.addLegend(m_leftMargin, m_topMargin, False, m_legendFont, m_legendFontSize)
Call box.setFontColor(m_legendFontColor)
Call box.setBackground(m_legendBgColor)
Call box.setMargin2(5, 0, 2, 1)
Call box.setSize(m_totalWidth - m_leftMargin - m_rightMargin + 1, 0)
End If
'configure x-axis
Dim a As Object
Set a = ret.xAxis()
Call a.setIndent(True)
Call a.setTickLength(2, 0)
Call a.setColors(cd.Transparent, m_xAxisFontColor, m_xAxisFontColor, m_xAxisFontColor)
Call a.setLabelStyle(m_xAxisFont, m_xAxisFontSize, m_xAxisFontColor, m_xAxisFontAngle)
'configure y-axis
Call ret.setYAxisOnRight(m_axisOnRight)
Call configureYAxis(ret.yAxis(), height)
Set addIndicator = ret
Exit Function
End Function
Private Sub configureYAxis(a, height)
Call a.setAutoScale(0, 0.05, 0)
If height < 100 Then
Call a.setTickDensity(15)
End If
Call a.setMargin(m_yAxisMargin)
Call a.setLabelStyle(m_yAxisFont, m_yAxisFontSize, m_yAxisFontColor, 0)
Call a.setTickLength(-4, -2)
Call a.setColors(cd.Transparent, m_yAxisFontColor, m_yAxisFontColor, m_yAxisFontColor)
End Sub
'/ <summary>
'/ Add a generic line indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="data">The data series of the indicator line.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="name">The name of the indicator.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addLineIndicator(height, data, color, name)
Dim c As Object
Set c = addIndicator(height)
Call addLineIndicator2(c, data, color, name)
Set addLineIndicator = c
Exit Function
End Function
'/ <summary>
'/ Add a line to an existing indicator chart.
'/ </summary>
'/ <param name="c">The indicator chart to add the line to.</param>
'/ <param name="data">The data series of the indicator line.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="name">The name of the indicator.</param>
'/ <returns>The LineLayer object representing the line created.</returns>
Public Function addLineIndicator2(c, data, color, name)
Set addLineIndicator2 = c.addLineLayer(data, color, formatIndicatorLabel(name, data))
Exit Function
End Function
'/ <summary>
'/ Add a generic bar indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="data">The data series of the indicator bars.</param>
'/ <param name="color">The color of the indicator bars.</param>
'/ <param name="name">The name of the indicator.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addBarIndicator(height, data, color, name)
Dim c As Object
Set c = addIndicator(height)
Call addBarIndicator2(c, data, color, name)
Set addBarIndicator = c
Exit Function
End Function
'/ <summary>
'/ Add a bar layer to an existing indicator chart.
'/ </summary>
'/ <param name="c">The indicator chart to add the bar layer to.</param>
'/ <param name="data">The data series of the indicator bars.</param>
'/ <param name="color">The color of the indicator bars.</param>
'/ <param name="name">The name of the indicator.</param>
'/ <returns>The BarLayer object representing the bar layer created.</returns>
Public Function addBarIndicator2(c, data, color, name)
Dim layer As Object
Set layer = c.addBarLayer(data, color, formatIndicatorLabel(name, data))
Call layer.setBorderColor(cd.Transparent)
Set addBarIndicator2 = layer
Exit Function
End Function
'/ <summary>
'/ Add an upper/lower threshold range to an existing indicator chart.
'/ </summary>
'/ <param name="c">The indicator chart to add the threshold range to.</param>
'/ <param name="layer">The line layer that the threshold range applies to.</param>
'/ <param name="topRange">The upper threshold.</param>
'/ <param name="topColor">The color to fill the region of the line that is above the
'/ upper threshold.</param>
'/ <param name="bottomRange">The lower threshold.</param>
'/ <param name="bottomColor">The color to fill the region of the line that is below
'/ the lower threshold.</param>
Public Sub addThreshold(c, layer, topRange, topColor, bottomRange, bottomColor)
Dim topMark As Object
Set topMark = c.yAxis().addMark(topRange, topColor, formatValue(topRange, m_generalFormat))
Dim bottomMark As Object
Set bottomMark = c.yAxis().addMark(bottomRange, bottomColor, formatValue(bottomRange, _
m_generalFormat))
Call c.addInterLineLayer(layer.getLine(), topMark.getLine(), topColor, cd.Transparent)
Call c.addInterLineLayer(layer.getLine(), bottomMark.getLine(), cd.Transparent, bottomColor)
End Sub
Private Function formatIndicatorLabel(name, data)
Dim i As Long
i = lastIndex(data)
If name = "" Then
formatIndicatorLabel = name
Exit Function
End If
If (name = "") Or (i < 0) Then
formatIndicatorLabel = name
Exit Function
End If
Dim ret As String
ret = name & ": " & formatValue(data(i), m_generalFormat)
formatIndicatorLabel = ret
Exit Function
End Function
'/ <summary>
'/ Add an Accumulation/Distribution indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addAccDist(height, color)
'Close Location Value = ((C - L) - (H - C)) / (H - L)
'Accumulation Distribution Line = Accumulation of CLV * volume
Dim range()
range = cd.ArrayMath(m_highData).subtract(m_lowData).result()
Set addAccDist = addLineIndicator(height, cd.ArrayMath(m_closeData).mul(2).subtract(m_lowData _
).subtract(m_highData).mul(m_volData).financeDiv(range, 0).acc().result(), color, _
"Accumulation/Distribution")
Exit Function
End Function
Private Function computeAroonUp(period)
ReDim aroonUp(UBound(m_highData))
Dim i As Long
For i = 0 To UBound(m_highData)
Dim highValue As Double
highValue = m_highData(i)
If highValue = cd.NoValue Then
aroonUp(i) = cd.NoValue
Else
Dim currentIndex As Long
currentIndex = i
Dim highCount As Long
highCount = period
Dim count As Long
count = period
Do While (count > 0) And (currentIndex >= count)
currentIndex = currentIndex - 1
Dim currentValue As Double
currentValue = m_highData(currentIndex)
If currentValue <> cd.NoValue Then
count = count - 1
If currentValue > highValue Then
highValue = currentValue
highCount = count
End If
End If
Loop
If count > 0 Then
aroonUp(i) = cd.NoValue
Else
aroonUp(i) = highCount * 100.0 / period
End If
End If
Next
computeAroonUp = aroonUp
Exit Function
End Function
Private Function computeAroonDn(period)
ReDim aroonDn(UBound(m_lowData))
Dim i As Long
For i = 0 To UBound(m_lowData)
Dim lowValue As Double
lowValue = m_lowData(i)
If lowValue = cd.NoValue Then
aroonDn(i) = cd.NoValue
Else
Dim currentIndex As Long
currentIndex = i
Dim lowCount As Long
lowCount = period
Dim count As Long
count = period
Do While (count > 0) And (currentIndex >= count)
currentIndex = currentIndex - 1
Dim currentValue As Double
currentValue = m_lowData(currentIndex)
If currentValue <> cd.NoValue Then
count = count - 1
If currentValue < lowValue Then
lowValue = currentValue
lowCount = count
End If
End If
Loop
If count > 0 Then
aroonDn(i) = cd.NoValue
Else
aroonDn(i) = lowCount * 100.0 / period
End If
End If
Next
computeAroonDn = aroonDn
Exit Function
End Function
'/ <summary>
'/ Add an Aroon Up/Down indicators chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicators.</param>
'/ <param name="upColor">The color of the Aroon Up indicator line.</param>
'/ <param name="downColor">The color of the Aroon Down indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addAroon(height, period, upColor, downColor)
Dim c As Object
Set c = addIndicator(height)
Call addLineIndicator2(c, computeAroonUp(period), upColor, "Aroon Up")
Call addLineIndicator2(c, computeAroonDn(period), downColor, "Aroon Down")
Call c.yAxis().setLinearScale(0, 100)
Set addAroon = c
Exit Function
End Function
'/ <summary>
'/ Add an Aroon Oscillator indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addAroonOsc(height, period, color)
Dim label As String
label = "Aroon Oscillator (" & period & ")"
Dim c As Object
Set c = addLineIndicator(height, cd.ArrayMath(computeAroonUp(period)).subtract(computeAroonDn( _
period)).result(), color, label)
Call c.yAxis().setLinearScale(-100, 100)
Set addAroonOsc = c
Exit Function
End Function
Private Function computeTrueRange()
Dim previousClose()
previousClose = cd.ArrayMath(m_closeData).shift().result()
Dim ret()
ret = cd.ArrayMath(m_highData).subtract(m_lowData).result()
Dim temp As Double
temp = 0
Dim i As Long
For i = 0 To UBound(m_highData)
If (ret(i) <> cd.NoValue) And (previousClose(i) <> cd.NoValue) Then
temp = Abs(m_highData(i) - previousClose(i))
If temp > ret(i) Then
ret(i) = temp
End If
temp = Abs(previousClose(i) - m_lowData(i))
If temp > ret(i) Then
ret(i) = temp
End If
End If
Next
computeTrueRange = ret
Exit Function
End Function
'/ <summary>
'/ Add an Average Directional Index indicators chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="posColor">The color of the Positive Directional Index line.</param>
'/ <param name="negColor">The color of the Negatuve Directional Index line.</param>
'/ <param name="color">The color of the Average Directional Index line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addADX(height, period, posColor, negColor, color)
'pos/neg directional movement
Dim pos As Object
Set pos = cd.ArrayMath(m_highData).delta().selectGTZ()
Dim neg As Object
Set neg = cd.ArrayMath(m_lowData).delta().mul(-1).selectGTZ()
Dim delta()
delta = cd.ArrayMath(pos.result()).subtract(neg.result()).result()
Call pos.selectGTZ(delta)
Call neg.selectLTZ(delta)
'initial value
Dim posData()
posData = pos.result()
Dim negData()
negData = neg.result()
If (UBound(posData) + 1 > 1) And (posData(1) <> cd.NoValue) And (negData(1) <> cd.NoValue) _
Then
posData(1) = (posData(1) * 2 + negData(1)) / 3
negData(1) = (negData(1) + posData(1)) / 2
Set pos = cd.ArrayMath(posData)
Set neg = cd.ArrayMath(negData)
End If
'pos/neg directional index
Dim tr()
tr = computeTrueRange()
tr = cd.ArrayMath(tr).expAvg(1.0 / period).result()
Call pos.expAvg(1.0 / period).financeDiv(tr, 0).mul(100)
Call neg.expAvg(1.0 / period).financeDiv(tr, 0).mul(100)
'directional movement index ??? what happen if division by zero???
Dim totalDM()
totalDM = cd.ArrayMath(pos.result()).add(neg.result()).result()
Dim dx As Object
Set dx = cd.ArrayMath(pos.result()).subtract(neg.result()).absolute().financeDiv(totalDM, 0 _
).mul(100).expAvg(1.0 / period)
Dim c As Object
Set c = addIndicator(height)
Dim label1 As String
label1 = "+DI (" & period & ")"
Dim label2 As String
label2 = "-DI (" & period & ")"
Dim label3 As String
label3 = "ADX (" & period & ")"
Call addLineIndicator2(c, pos.result(), posColor, label1)
Call addLineIndicator2(c, neg.result(), negColor, label2)
Call addLineIndicator2(c, dx.result(), color, label3)
Set addADX = c
Exit Function
End Function
'/ <summary>
'/ Add an Average True Range indicators chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color1">The color of the True Range line.</param>
'/ <param name="color2">The color of the Average True Range line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addATR(height, period, color1, color2)
Dim trueRange()
trueRange = computeTrueRange()
Dim c As Object
Set c = addLineIndicator(height, trueRange, color1, "True Range")
Dim label As String
label = "Average True Range (" & period & ")"
Call addLineIndicator2(c, cd.ArrayMath(trueRange).expAvg(2.0 / (period + 1)).result(), color2, _
label)
Set addATR = c
Exit Function
End Function
'/ <summary>
'/ Add a Bollinger Band Width indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="width">The band width to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addBollingerWidth(height, period, width, color)
Dim label As String
label = "Bollinger Width (" & period & ", " & width & ")"
Set addBollingerWidth = addLineIndicator(height, cd.ArrayMath(m_closeData).movStdDev(period _
).mul(width * 2).result(), color, label)
Exit Function
End Function
'/ <summary>
'/ Add a Community Channel Index indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="deviation">The distance beween the middle line and the upper and lower threshold lines.</param>
'/ <param name="upColor">The fill color when the indicator exceeds the upper threshold line.</param>
'/ <param name="downColor">The fill color when the indicator falls below the lower threshold line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addCCI(height, period, color, deviation, upColor, downColor)
'typical price
Dim tp()
tp = cd.ArrayMath(m_highData).add(m_lowData).add(m_closeData).div(3).result()
'simple moving average of typical price
Dim smvtp()
smvtp = cd.ArrayMath(tp).movAvg(period).result()
'compute mean deviation
ReDim movMeanDev(UBound(smvtp))
Dim i As Long
For i = 0 To UBound(smvtp)
Dim avg As Double
avg = smvtp(i)
If avg = cd.NoValue Then
movMeanDev(i) = cd.NoValue
Else
Dim currentIndex As Long
currentIndex = i
Dim count As Long
count = period - 1
Dim acc As Double
acc = 0
Do While (count >= 0) And (currentIndex >= count)
Dim currentValue As Double
currentValue = tp(currentIndex)
currentIndex = currentIndex - 1
If currentValue <> cd.NoValue Then
count = count - 1
acc = acc + Abs(avg - currentValue)
End If
Loop
If count > 0 Then
movMeanDev(i) = cd.NoValue
Else
movMeanDev(i) = acc / period
End If
End If
Next
Dim c As Object
Set c = addIndicator(height)
Dim label As String
label = "CCI (" & period & ")"
Dim layer As Object
Set layer = addLineIndicator2(c, cd.ArrayMath(tp).subtract(smvtp).financeDiv(movMeanDev, 0 _
).div(0.015).result(), color, label)
Call addThreshold(c, layer, deviation, upColor, -deviation, downColor)
Set addCCI = c
Exit Function
End Function
'/ <summary>
'/ Add a Chaikin Money Flow indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addChaikinMoneyFlow(height, period, color)
Dim range()
range = cd.ArrayMath(m_highData).subtract(m_lowData).result()
Dim volAvg()
volAvg = cd.ArrayMath(m_volData).movAvg(period).result()
Dim label As String
label = "Chaikin Money Flow (" & period & ")"
Set addChaikinMoneyFlow = addBarIndicator(height, cd.ArrayMath(m_closeData).mul(2).subtract( _
m_lowData).subtract(m_highData).mul(m_volData).financeDiv(range, 0).movAvg(period _
).financeDiv(volAvg, 0).result(), color, label)
Exit Function
End Function
'/ <summary>
'/ Add a Chaikin Oscillator indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addChaikinOscillator(height, color)
'first compute acc/dist line
Dim range()
range = cd.ArrayMath(m_highData).subtract(m_lowData).result()
Dim accdist()
accdist = cd.ArrayMath(m_closeData).mul(2).subtract(m_lowData).subtract(m_highData).mul( _
m_volData).financeDiv(range, 0).acc().result()
'chaikin osc = exp3(accdist) - exp10(accdist)
Dim expAvg10()
expAvg10 = cd.ArrayMath(accdist).expAvg(2.0 / (10 + 1)).result()
Set addChaikinOscillator = addLineIndicator(height, cd.ArrayMath(accdist).expAvg(2.0 / (3 + 1) _
).subtract(expAvg10).result(), color, "Chaikin Oscillator")
Exit Function
End Function
'/ <summary>
'/ Add a Chaikin Volatility indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period1">The period to smooth the range.</param>
'/ <param name="period2">The period to compute the rate of change of the smoothed range.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addChaikinVolatility(height, period1, period2, color)
Dim label As String
label = "Chaikin Volatility (" & period1 & ", " & period2 & ")"
Set addChaikinVolatility = addLineIndicator(height, cd.ArrayMath(m_highData).subtract( _
m_lowData).expAvg(2.0 / (period1 + 1)).rate(period2).subtract(1).mul(100).result(), color, _
label)
Exit Function
End Function
'/ <summary>
'/ Add a Close Location Value indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addCLV(height, color)
'Close Location Value = ((C - L) - (H - C)) / (H - L)
Dim range()
range = cd.ArrayMath(m_highData).subtract(m_lowData).result()
Set addCLV = addLineIndicator(height, cd.ArrayMath(m_closeData).mul(2).subtract(m_lowData _
).subtract(m_highData).financeDiv(range, 0).result(), color, "Close Location Value")
Exit Function
End Function
'/ <summary>
'/ Add a Detrended Price Oscillator indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addDPO(height, period, color)
Dim label As String
label = "DPO (" & period & ")"
Set addDPO = addLineIndicator(height, cd.ArrayMath(m_closeData).movAvg(period).shift(period / _
2 + 1).subtract(m_closeData).mul(-1).result(), color, label)
Exit Function
End Function
'/ <summary>
'/ Add a Donchian Channel Width indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addDonchianWidth(height, period, color)
Dim label As String
label = "Donchian Width (" & period & ")"
Set addDonchianWidth = addLineIndicator(height, cd.ArrayMath(m_highData).movMax(period _
).subtract(cd.ArrayMath(m_lowData).movMin(period).result()).result(), color, label)
Exit Function
End Function
'/ <summary>
'/ Add a Ease of Movement indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to smooth the indicator.</param>
'/ <param name="color1">The color of the indicator line.</param>
'/ <param name="color2">The color of the smoothed indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addEaseOfMovement(height, period, color1, color2)
Dim boxRatioInverted()
boxRatioInverted = cd.ArrayMath(m_highData).subtract(m_lowData).financeDiv(m_volData, 0 _
).result()
Dim result()
result = cd.ArrayMath(m_highData).add(m_lowData).div(2).delta().mul(boxRatioInverted).result()
Dim c As Object
Set c = addLineIndicator(height, result, color1, "EMV")
Dim label As String
label = "EMV EMA (" & period & ")"
Call addLineIndicator2(c, cd.ArrayMath(result).movAvg(period).result(), color2, label)
Set addEaseOfMovement = c
Exit Function
End Function
'/ <summary>
'/ Add a Fast Stochastic indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period1">The period to compute the %K line.</param>
'/ <param name="period2">The period to compute the %D line.</param>
'/ <param name="color1">The color of the %K line.</param>
'/ <param name="color2">The color of the %D line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addFastStochastic(height, period1, period2, color1, color2)
Dim movLow()
movLow = cd.ArrayMath(m_lowData).movMin(period1).result()
Dim movRange()
movRange = cd.ArrayMath(m_highData).movMax(period1).subtract(movLow).result()
Dim stochastic()
stochastic = cd.ArrayMath(m_closeData).subtract(movLow).financeDiv(movRange, 0.5).mul(100 _
).result()
Dim label1 As String
label1 = "Fast Stochastic %K (" & period1 & ")"
Dim c As Object
Set c = addLineIndicator(height, stochastic, color1, label1)
Dim label2 As String
label2 = "%D (" & period2 & ")"
Call addLineIndicator2(c, cd.ArrayMath(stochastic).movAvg(period2).result(), color2, label2)
Call c.yAxis().setLinearScale(0, 100)
Set addFastStochastic = c
Exit Function
End Function
'/ <summary>
'/ Add a MACD indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period1">The first moving average period to compute the indicator.</param>
'/ <param name="period2">The second moving average period to compute the indicator.</param>
'/ <param name="period3">The moving average period of the signal line.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="signalColor">The color of the signal line.</param>
'/ <param name="divColor">The color of the divergent bars.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addMACD(height, period1, period2, period3, color, signalColor, divColor)
Dim c As Object
Set c = addIndicator(height)
'MACD is defined as the difference between two exponential averages (typically 12/26 days)
Dim expAvg1()
expAvg1 = cd.ArrayMath(m_closeData).expAvg(2.0 / (period1 + 1)).result()
Dim macd()
macd = cd.ArrayMath(m_closeData).expAvg(2.0 / (period2 + 1)).subtract(expAvg1).result()
'Add the MACD line
Dim label1 As String
label1 = "MACD (" & period1 & ", " & period2 & ")"
Call addLineIndicator2(c, macd, color, label1)
'MACD signal line
Dim macdSignal()
macdSignal = cd.ArrayMath(macd).expAvg(2.0 / (period3 + 1)).result()
Dim label2 As String
label2 = "EXP (" & period3 & ")"
Call addLineIndicator2(c, macdSignal, signalColor, label2)
'Divergence
Call addBarIndicator2(c, cd.ArrayMath(macd).subtract(macdSignal).result(), divColor, _
"Divergence")
Set addMACD = c
Exit Function
End Function
'/ <summary>
'/ Add a Mass Index indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="upColor">The fill color when the indicator exceeds the upper threshold line.</param>
'/ <param name="downColor">The fill color when the indicator falls below the lower threshold line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addMassIndex(height, color, upColor, downColor)
'Mass Index
Dim f As Double
f = 2.0 / (10)
Dim exp9()
exp9 = cd.ArrayMath(m_highData).subtract(m_lowData).expAvg(f).result()
Dim exp99()
exp99 = cd.ArrayMath(exp9).expAvg(f).result()
Dim c As Object
Set c = addLineIndicator(height, cd.ArrayMath(exp9).financeDiv(exp99, 1).movAvg(25).mul(25 _
).result(), color, "Mass Index")
Call c.yAxis().addMark(27, upColor)
Call c.yAxis().addMark(26.5, downColor)
Set addMassIndex = c
Exit Function
End Function
'/ <summary>
'/ Add a Money Flow Index indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="range">The distance beween the middle line and the upper and lower threshold lines.</param>
'/ <param name="upColor">The fill color when the indicator exceeds the upper threshold line.</param>
'/ <param name="downColor">The fill color when the indicator falls below the lower threshold line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addMFI(height, period, color, range, upColor, downColor)
'Money Flow Index
Dim typicalPrice()
typicalPrice = cd.ArrayMath(m_highData).add(m_lowData).add(m_closeData).div(3).result()
Dim moneyFlow()
moneyFlow = cd.ArrayMath(typicalPrice).mul(m_volData).result()
Dim selector()
selector = cd.ArrayMath(typicalPrice).delta().result()
Dim posMoneyFlow()
posMoneyFlow = cd.ArrayMath(moneyFlow).selectGTZ(selector).movAvg(period).result()
Dim posNegMoneyFlow()
posNegMoneyFlow = cd.ArrayMath(moneyFlow).selectLTZ(selector).movAvg(period).add(posMoneyFlow _
).result()
Dim c As Object
Set c = addIndicator(height)
Dim label As String
label = "Money Flow Index (" & period & ")"
Dim layer As Object
Set layer = addLineIndicator2(c, cd.ArrayMath(posMoneyFlow).financeDiv(posNegMoneyFlow, 0.5 _
).mul(100).result(), color, label)
Call addThreshold(c, layer, 50 + range, upColor, 50 - range, downColor)
Call c.yAxis().setLinearScale(0, 100)
Set addMFI = c
Exit Function
End Function
'/ <summary>
'/ Add a Momentum indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addMomentum(height, period, color)
Dim label As String
label = "Momentum (" & period & ")"
Set addMomentum = addLineIndicator(height, cd.ArrayMath(m_closeData).delta(period).result(), _
color, label)
Exit Function
End Function
'/ <summary>
'/ Add a Negative Volume Index indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the signal line.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="signalColor">The color of the signal line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addNVI(height, period, color, signalColor)
ReDim nvi(UBound(m_volData))
Dim previousNVI As Double
previousNVI = 100
Dim previousVol As Double
previousVol = cd.NoValue
Dim previousClose As Double
previousClose = cd.NoValue
Dim i As Long
For i = 0 To UBound(m_volData)
If m_volData(i) = cd.NoValue Then
nvi(i) = cd.NoValue
Else
If (previousVol <> cd.NoValue) And (m_volData(i) < previousVol) And (previousClose <> _
cd.NoValue) And (m_closeData(i) <> cd.NoValue) Then
nvi(i) = previousNVI + previousNVI * (m_closeData(i) - previousClose) / _
previousClose
Else
nvi(i) = previousNVI
End If
previousNVI = nvi(i)
previousVol = m_volData(i)
previousClose = m_closeData(i)
End If
Next
Dim c As Object
Set c = addLineIndicator(height, nvi, color, "NVI")
If UBound(nvi) + 1 > period Then
Dim label As String
label = "NVI SMA (" & period & ")"
Call addLineIndicator2(c, cd.ArrayMath(nvi).movAvg(period).result(), signalColor, label)
End If
Set addNVI = c
Exit Function
End Function
'/ <summary>
'/ Add an On Balance Volume indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addOBV(height, color)
Dim closeChange()
closeChange = cd.ArrayMath(m_closeData).delta().result()
Dim upVolume()
upVolume = cd.ArrayMath(m_volData).selectGTZ(closeChange).result()
Dim downVolume()
downVolume = cd.ArrayMath(m_volData).selectLTZ(closeChange).result()
Set addOBV = addLineIndicator(height, cd.ArrayMath(upVolume).subtract(downVolume).acc( _
).result(), color, "OBV")
Exit Function
End Function
'/ <summary>
'/ Add a Performance indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addPerformance(height, color)
Dim closeValue As Double
closeValue = firstCloseValue()
If closeValue <> cd.NoValue Then
Set addPerformance = addLineIndicator(height, cd.ArrayMath(m_closeData).mul(100 / _
closeValue).subtract(100).result(), color, "Performance")
Exit Function
Else
'chart is empty !!!
Set addPerformance = addIndicator(height)
Exit Function
End If
End Function
'/ <summary>
'/ Add a Percentage Price Oscillator indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period1">The first moving average period to compute the indicator.</param>
'/ <param name="period2">The second moving average period to compute the indicator.</param>
'/ <param name="period3">The moving average period of the signal line.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="signalColor">The color of the signal line.</param>
'/ <param name="divColor">The color of the divergent bars.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addPPO(height, period1, period2, period3, color, signalColor, divColor)
Dim expAvg1()
expAvg1 = cd.ArrayMath(m_closeData).expAvg(2.0 / (period1 + 1)).result()
Dim expAvg2()
expAvg2 = cd.ArrayMath(m_closeData).expAvg(2.0 / (period2 + 1)).result()
Dim ppo As Object
Set ppo = cd.ArrayMath(expAvg2).subtract(expAvg1).financeDiv(expAvg2, 0).mul(100)
Dim ppoSignal()
ppoSignal = cd.ArrayMath(ppo.result()).expAvg(2.0 / (period3 + 1)).result()
Dim label1 As String
label1 = "PPO (" & period1 & ", " & period2 & ")"
Dim label2 As String
label2 = "EMA (" & period3 & ")"
Dim c As Object
Set c = addLineIndicator(height, ppo.result(), color, label1)
Call addLineIndicator2(c, ppoSignal, signalColor, label2)
Call addBarIndicator2(c, ppo.subtract(ppoSignal).result(), divColor, "Divergence")
Set addPPO = c
Exit Function
End Function
'/ <summary>
'/ Add a Positive Volume Index indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the signal line.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="signalColor">The color of the signal line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addPVI(height, period, color, signalColor)
'Positive Volume Index
ReDim pvi(UBound(m_volData))
Dim previousPVI As Double
previousPVI = 100
Dim previousVol As Double
previousVol = cd.NoValue
Dim previousClose As Double
previousClose = cd.NoValue
Dim i As Long
For i = 0 To UBound(m_volData)
If m_volData(i) = cd.NoValue Then
pvi(i) = cd.NoValue
Else
If (previousVol <> cd.NoValue) And (m_volData(i) > previousVol) And (previousClose <> _
cd.NoValue) And (m_closeData(i) <> cd.NoValue) Then
pvi(i) = previousPVI + previousPVI * (m_closeData(i) - previousClose) / _
previousClose
Else
pvi(i) = previousPVI
End If
previousPVI = pvi(i)
previousVol = m_volData(i)
previousClose = m_closeData(i)
End If
Next
Dim c As Object
Set c = addLineIndicator(height, pvi, color, "PVI")
If UBound(pvi) + 1 > period Then
Dim label As String
label = "PVI SMA (" & period & ")"
Call addLineIndicator2(c, cd.ArrayMath(pvi).movAvg(period).result(), signalColor, label)
End If
Set addPVI = c
Exit Function
End Function
'/ <summary>
'/ Add a Percentage Volume Oscillator indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period1">The first moving average period to compute the indicator.</param>
'/ <param name="period2">The second moving average period to compute the indicator.</param>
'/ <param name="period3">The moving average period of the signal line.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="signalColor">The color of the signal line.</param>
'/ <param name="divColor">The color of the divergent bars.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addPVO(height, period1, period2, period3, color, signalColor, divColor)
Dim expAvg1()
expAvg1 = cd.ArrayMath(m_volData).expAvg(2.0 / (period1 + 1)).result()
Dim expAvg2()
expAvg2 = cd.ArrayMath(m_volData).expAvg(2.0 / (period2 + 1)).result()
Dim pvo As Object
Set pvo = cd.ArrayMath(expAvg2).subtract(expAvg1).financeDiv(expAvg2, 0).mul(100)
Dim pvoSignal()
pvoSignal = cd.ArrayMath(pvo.result()).expAvg(2.0 / (period3 + 1)).result()
Dim label1 As String
label1 = "PVO (" & period1 & ", " & period2 & ")"
Dim label2 As String
label2 = "EMA (" & period3 & ")"
Dim c As Object
Set c = addLineIndicator(height, pvo.result(), color, label1)
Call addLineIndicator2(c, pvoSignal, signalColor, label2)
Call addBarIndicator2(c, pvo.subtract(pvoSignal).result(), divColor, "Divergence")
Set addPVO = c
Exit Function
End Function
'/ <summary>
'/ Add a Price Volumne Trend indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addPVT(height, color)
Set addPVT = addLineIndicator(height, cd.ArrayMath(m_closeData).rate().subtract(1).mul( _
m_volData).acc().result(), color, "PVT")
Exit Function
End Function
'/ <summary>
'/ Add a Rate of Change indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addROC(height, period, color)
Dim label As String
label = "ROC (" & period & ")"
Set addROC = addLineIndicator(height, cd.ArrayMath(m_closeData).rate(period).subtract(1).mul( _
100).result(), color, label)
Exit Function
End Function
Private Function RSIMovAvg(data, period)
'The "moving average" in classical RSI is based on a formula that mixes simple
'and exponential moving averages.
If period <= 0 Then
period = 1
End If
Dim count As Long
count = 0
Dim acc As Double
acc = 0
Dim i As Long
For i = 0 To UBound(data)
If Abs(data(i) / cd.NoValue - 1) > 1e-005 Then
count = count + 1
acc = acc + data(i)
If count < period Then
data(i) = cd.NoValue
Else
data(i) = acc / period
acc = data(i) * (period - 1)
End If
End If
Next
RSIMovAvg = data
Exit Function
End Function
Private Function computeRSI(period)
'RSI is defined as the average up changes for the last 14 days, divided by the
'average absolute changes for the last 14 days, expressed as a percentage.
Dim absChange()
absChange = RSIMovAvg(cd.ArrayMath(m_closeData).delta().absolute().result(), period)
Dim absUpChange()
absUpChange = RSIMovAvg(cd.ArrayMath(m_closeData).delta().selectGTZ().result(), period)
computeRSI = cd.ArrayMath(absUpChange).financeDiv(absChange, 0.5).mul(100).result()
Exit Function
End Function
'/ <summary>
'/ Add a Relative Strength Index indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="range">The distance beween the middle line and the upper and lower threshold lines.</param>
'/ <param name="upColor">The fill color when the indicator exceeds the upper threshold line.</param>
'/ <param name="downColor">The fill color when the indicator falls below the lower threshold line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addRSI(height, period, color, range, upColor, downColor)
Dim c As Object
Set c = addIndicator(height)
Dim label As String
label = "RSI (" & period & ")"
Dim layer As Object
Set layer = addLineIndicator2(c, computeRSI(period), color, label)
'Add range if given
If (range > 0) And (range < 50) Then
Call addThreshold(c, layer, 50 + range, upColor, 50 - range, downColor)
End If
Call c.yAxis().setLinearScale(0, 100)
Set addRSI = c
Exit Function
End Function
'/ <summary>
'/ Add a Slow Stochastic indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period1">The period to compute the %K line.</param>
'/ <param name="period2">The period to compute the %D line.</param>
'/ <param name="color1">The color of the %K line.</param>
'/ <param name="color2">The color of the %D line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addSlowStochastic(height, period1, period2, color1, color2)
Dim movLow()
movLow = cd.ArrayMath(m_lowData).movMin(period1).result()
Dim movRange()
movRange = cd.ArrayMath(m_highData).movMax(period1).subtract(movLow).result()
Dim stochastic As Object
Set stochastic = cd.ArrayMath(m_closeData).subtract(movLow).financeDiv(movRange, 0.5).mul(100 _
).movAvg(3)
Dim label1 As String
label1 = "Slow Stochastic %K (" & period1 & ")"
Dim label2 As String
label2 = "%D (" & period2 & ")"
Dim c As Object
Set c = addLineIndicator(height, stochastic.result(), color1, label1)
Call addLineIndicator2(c, stochastic.movAvg(period2).result(), color2, label2)
Call c.yAxis().setLinearScale(0, 100)
Set addSlowStochastic = c
Exit Function
End Function
'/ <summary>
'/ Add a Moving Standard Deviation indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addStdDev(height, period, color)
Dim label As String
label = "Moving StdDev (" & period & ")"
Set addStdDev = addLineIndicator(height, cd.ArrayMath(m_closeData).movStdDev(period).result(), _
color, label)
Exit Function
End Function
'/ <summary>
'/ Add a Stochastic RSI indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="range">The distance beween the middle line and the upper and lower threshold lines.</param>
'/ <param name="upColor">The fill color when the indicator exceeds the upper threshold line.</param>
'/ <param name="downColor">The fill color when the indicator falls below the lower threshold line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addStochRSI(height, period, color, range, upColor, downColor)
Dim rsi()
rsi = computeRSI(period)
Dim movLow()
movLow = cd.ArrayMath(rsi).movMin(period).result()
Dim movRange()
movRange = cd.ArrayMath(rsi).movMax(period).subtract(movLow).result()
Dim c As Object
Set c = addIndicator(height)
Dim label As String
label = "StochRSI (" & period & ")"
Dim layer As Object
Set layer = addLineIndicator2(c, cd.ArrayMath(rsi).subtract(movLow).financeDiv(movRange, 0.5 _
).mul(100).result(), color, label)
'Add range if given
If (range > 0) And (range < 50) Then
Call addThreshold(c, layer, 50 + range, upColor, 50 - range, downColor)
End If
Call c.yAxis().setLinearScale(0, 100)
Set addStochRSI = c
Exit Function
End Function
'/ <summary>
'/ Add a TRIX indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addTRIX(height, period, color)
Dim f As Double
f = 2.0 / (period + 1)
Dim label As String
label = "TRIX (" & period & ")"
Set addTRIX = addLineIndicator(height, cd.ArrayMath(m_closeData).expAvg(f).expAvg(f).expAvg(f _
).rate().subtract(1).mul(100).result(), color, label)
Exit Function
End Function
Private Function computeTrueLow()
'the lower of today's low or yesterday's close.
Dim previousClose()
previousClose = cd.ArrayMath(m_closeData).shift().result()
ReDim ret(UBound(m_lowData))
Dim i As Long
For i = 0 To UBound(m_lowData)
If (m_lowData(i) <> cd.NoValue) And (previousClose(i) <> cd.NoValue) Then
If m_lowData(i) < previousClose(i) Then
ret(i) = m_lowData(i)
Else
ret(i) = previousClose(i)
End If
Else
ret(i) = cd.NoValue
End If
Next
computeTrueLow = ret
Exit Function
End Function
'/ <summary>
'/ Add an Ultimate Oscillator indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period1">The first moving average period to compute the indicator.</param>
'/ <param name="period2">The second moving average period to compute the indicator.</param>
'/ <param name="period3">The third moving average period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="range">The distance beween the middle line and the upper and lower threshold lines.</param>
'/ <param name="upColor">The fill color when the indicator exceeds the upper threshold line.</param>
'/ <param name="downColor">The fill color when the indicator falls below the lower threshold line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addUltimateOscillator(height, period1, period2, period3, color, range, upColor, _
downColor)
Dim trueLow()
trueLow = computeTrueLow()
Dim buyingPressure()
buyingPressure = cd.ArrayMath(m_closeData).subtract(trueLow).result()
Dim trueRange()
trueRange = computeTrueRange()
Dim rawUO1()
rawUO1 = cd.ArrayMath(buyingPressure).movAvg(period1).financeDiv(cd.ArrayMath(trueRange _
).movAvg(period1).result(), 0.5).mul(4).result()
Dim rawUO2()
rawUO2 = cd.ArrayMath(buyingPressure).movAvg(period2).financeDiv(cd.ArrayMath(trueRange _
).movAvg(period2).result(), 0.5).mul(2).result()
Dim rawUO3()
rawUO3 = cd.ArrayMath(buyingPressure).movAvg(period3).financeDiv(cd.ArrayMath(trueRange _
).movAvg(period3).result(), 0.5).mul(1).result()
Dim c As Object
Set c = addIndicator(height)
Dim label As String
label = "Ultimate Oscillator (" & period1 & ", " & period2 & ", " & period3 & ")"
Dim layer As Object
Set layer = addLineIndicator2(c, cd.ArrayMath(rawUO1).add(rawUO2).add(rawUO3).mul(100.0 / 7 _
).result(), color, label)
Call addThreshold(c, layer, 50 + range, upColor, 50 - range, downColor)
Call c.yAxis().setLinearScale(0, 100)
Set addUltimateOscillator = c
Exit Function
End Function
'/ <summary>
'/ Add a Volume indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="upColor">The color to used on an 'up' day. An 'up' day is a day where
'/ the closing price is higher than that of the previous day.</param>
'/ <param name="downColor">The color to used on a 'down' day. A 'down' day is a day
'/ where the closing price is lower than that of the previous day.</param>
'/ <param name="flatColor">The color to used on a 'flat' day. A 'flat' day is a day
'/ where the closing price is the same as that of the previous day.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addVolIndicator(height, upColor, downColor, flatColor)
Dim c As Object
Set c = addIndicator(height)
Call addVolBars2(c, height, upColor, downColor, flatColor)
Set addVolIndicator = c
Exit Function
End Function
'/ <summary>
'/ Add a William %R indicator chart.
'/ </summary>
'/ <param name="height">The height of the indicator chart in pixels.</param>
'/ <param name="period">The period to compute the indicator.</param>
'/ <param name="color">The color of the indicator line.</param>
'/ <param name="range">The distance beween the middle line and the upper and lower threshold lines.</param>
'/ <param name="upColor">The fill color when the indicator exceeds the upper threshold line.</param>
'/ <param name="downColor">The fill color when the indicator falls below the lower threshold line.</param>
'/ <returns>The XYChart object representing the chart created.</returns>
Public Function addWilliamR(height, period, color, range, upColor, downColor)
Dim movLow()
movLow = cd.ArrayMath(m_lowData).movMin(period).result()
Dim movHigh()
movHigh = cd.ArrayMath(m_highData).movMax(period).result()
Dim movRange()
movRange = cd.ArrayMath(movHigh).subtract(movLow).result()
Dim c As Object
Set c = addIndicator(height)
Dim layer As Object
Set layer = addLineIndicator2(c, cd.ArrayMath(movHigh).subtract(m_closeData).financeDiv( _
movRange, 0.5).mul(-100).result(), color, "William %R")
Call addThreshold(c, layer, -50 + range, upColor, -50 - range, downColor)
Call c.yAxis().setLinearScale(-100, 0)
Set addWilliamR = c
Exit Function
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' As VB/COM does not support inheritance, we need to copy the API for the
' base class MultiChart here for inheritance
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub addChart(x, y, c)
Call Base.addChart(x, y, c)
End Sub
Sub setMainChart(c)
Call Base.setMainChart(c)
End Sub
Sub enableVectorOutput()
Call Base.enableVectorOutput()
End Sub
Sub setSize(width, height)
Call Base.setSize(width, height)
End Sub
Function getWidth()
getWidth = Base.getWidth()
End Function
Function getHeight()
getHeight = Base.getHeight()
End Function
Sub setBorder(color)
Call Base.setBorder(color)
End Sub
Sub setBackground(bgColor, Optional edgeColor = -1, Optional raisedEffect = 0)
Call Base.setBackground(bgColor, edgeColor, raisedEffect)
End Sub
Sub setWallpaper(img)
Call Base.setWallpaper(img)
End Sub
Sub setBgImage(img, Optional align = 5)
Call Base.setBgImage(img, align)
End Sub
Sub setRoundedFrame(Optional extColor = &HFFFFFF, Optional r1 = 10, Optional r2 = -1, Optional r3 = -1, Optional r4 = -1)
Call Base.setRoundedFrame(extColor, r1, r2, r3, r4)
End Sub
Sub setDropShadow(Optional color = &HAAAAAA, Optional offsetX = 5, Optional offsetY = &H7FFFFFFF, Optional blurRadius = 5)
Call Base.setDropShadow(color, offsetX, offsetY, blurRadius)
End Sub
Function getChartMetrics()
getChartMetrics = Base.getChartMetrics()
End Function
Sub setTransparentColor(c)
Call Base.setTransparentColor(c)
End Sub
Sub setAntiAlias(Optional antiAliasShape = True, Optional antiAliasText = 2)
Call Base.setAntiAlias(antiAliasShape, antiAliasText)
End Sub
Sub setSearchPath(path)
Call Base.setSearchPath(path)
End Sub
Function addTitle2(alignment, text, Optional font = "", Optional fontSize = 12, Optional fontcolor = &HFFFF0002, Optional bgColor = &HFF000000, Optional edgeColor = &HFF000000)
Set addTitle2 = Base.addTitle2(alignment, text, font, fontSize, fontcolor, bgColor, edgeColor)
End Function
Function addTitle(text, Optional font = "", Optional fontSize = 12, Optional fontcolor = &HFFFF0002, Optional bgColor = &HFF000000, Optional edgeColor = &HFF000000)
Set addTitle = Base.addTitle(text, font, fontSize, fontcolor, bgColor, edgeColor)
End Function
Function addLegend(x, y, Optional vertical = True, Optional font = "", Optional fontSize = 10)
Set addLegend = Base.addLegend(x, y, vertical, font, fontSize)
End Function
Function getLegend()
Set getLegend = Base.getLegend()
End Function
Function getDrawArea()
Set getDrawArea = Base.getDrawArea()
End Function
Function addText(x, y, text, Optional font = "", Optional fontSize = 8, Optional fontcolor = &HFFFF0002, Optional alignment = 7, Optional angle = 0, Optional vertical = False)
Set addText = Base.addText(x, y, text, font, fontSize, fontcolor, alignment, angle, vertical)
End Function
Function addLine(x1, y1, x2, y2, Optional color = &HFFFF0001, Optional lineWidth = 1)
Set addLine = Base.addLine(x1, y1, x2, y2, color, lineWidth)
End Function
Function addTable(x, y, alignment, col, row)
Set addTable = Base.addTable(x, y, alignment, col, row)
End Function
Sub setColor(paletteEntry, color)
Call Base.setColor(paletteEntry, color)
End Sub
Sub setColors(colors)
Call Base.setColors(colors)
End Sub
Sub setColors2(paletteEntry, colors)
Call Base.setColors2(paletteEntry, colors)
End Sub
Function getColor(paletteEntry)
getColor = Base.getColor(paletteEntry)
End Function
Function halfColor()
halfColor = Base.halfColor()
End Function
Function adjustBrightness(c, brightness)
adjustBrightness = Base.adjustBrightness(c, brightness)
End Function
Function autoColor()
autoColor = Base.autoColor()
End Function
Function dashLineColor(color, patternCode)
dashLineColor = Base.dashLineColor(color, patternCode)
End Function
Function gradientColor(startX, startY, endX, endY, startColor, endColor)
gradientColor = Base.gradientColor(startX, startY, endX, endY, startColor, endColor)
End Function
Function gradientColor2(c, Optional angle = 90, Optional scale1 = 1, Optional startX = 0, Optional startY = 0)
gradientColor2 = Base.gradientColor2(c, angle, scale1, startX, startY)
End Function
Function linearGradientColor(startX, startY, endX, endY, startColor, endColor, Optional periodic = False)
linearGradientColor = Base.linearGradientColor(startX, startY, endX, endY, startColor, endColor, periodic)
End Function
Function linearGradientColor2(startX, startY, endX, endY, c, Optional periodic = False)
linearGradientColor2 = Base.linearGradientColor2(startX, startY, endX, endY, c, periodic)
End Function
Function radialGradientColor(cx, cy, rx, ry, startColor, endColor, Optional periodic = False)
radialGradientColor = Base.radialGradientColor(cx, cy, rx, ry, startColor, endColor, periodic)
End Function
Function radialGradientColor2(cx, cy, rx, ry, c, Optional periodic = False)
radialGradientColor2 = Base.radialGradientColor2(cx, cy, rx, ry, c, periodic)
End Function
Function patternColor(c, h, Optional startX, Optional startY)
patternColor = Base.patternColor(c, h, startX, startY)
End Function
Function patternColor2(fileName, Optional startX = 0, Optional startY = 0)
patternColor2 = Base.patternColor2(fileName, startX, startY)
End Function
Sub setDefaultFonts(normal, Optional bold, Optional italic, Optional boldItalic)
Call Base.setDefaultFonts(normal, bold, italic, boldItalic)
End Sub
Sub setFontTable(index, font)
Call Base.setFontTable(index, font)
End Sub
Sub setNumberFormat(Optional thousandSeparator = "~", Optional decimalPointChar = ".", Optional signChar = "-")
Call Base.setNumberFormat(thousandSeparator, decimalPointChar, signChar)
End Sub
Sub setMonthNames(names)
Call Base.setMonthNames(names)
End Sub
Sub setWeekDayNames(names)
Call Base.setWeekDayNames(names)
End Sub
Sub setAMPM(AM, PM)
Call Base.setAMPM(AM, PM)
End Sub
Sub layout()
Call Base.layout()
End Sub
Function makeChart(fileName)
makeChart = Base.makeChart(fileName)
End Function
Function makeChart2(format)
makeChart2 = Base.makeChart2(format)
End Function
Function makeChart3()
Set makeChart3 = Base.makeChart3()
End Function
Function makePicture() As IPicture
Set makePicture = Base.makePicture()
End Function
Function makeSession(sess, id, Optional imageType = 0)
makeSession = Base.makeSession(sess, id, imageType)
End Function
Function makeTmpFile(dirname, Optional imageType = 0, Optional timeout = 600)
makeTmpFile = Base.makeTmpFile(dirname, imageType, timeout)
End Function
Function getHTMLImageMap(url, Optional queryFormat, Optional extraAttr, Optional offsetX, Optional offsetY)
getHTMLImageMap = Base.getHTMLImageMap(url, queryFormat, extraAttr, offsetX, offsetY)
End Function
Sub addExtraField(texts)
Call Base.addExtraField(texts)
End Sub
Sub addExtraField2(numbers)
Call Base.addExtraField2(numbers)
End Sub
Function addLegend2(x, y, noOfCols, Optional font = "", Optional fontHeight = 10)
Set addLegend2 = Base.addLegend2(x, y, noOfCols, font, fontHeight)
End Function
Function formatValue(value, formatString)
formatValue = Base.formatValue(value, formatString)
End Function
Function layoutLegend()
Set layoutLegend = Base.layoutLegend()
End Function
Function getAbsOffsetX()
getAbsOffsetX = Base.getAbsOffsetX()
End Function
Function getAbsOffsetY()
getAbsOffsetY = Base.getAbsOffsetY()
End Function
Function initDynamicLayer()
Set initDynamicLayer = Base.initDynamicLayer()
End Function
Sub removeDynamicLayer()
Call Base.removeDynamicLayer()
End Sub
Function getJsChartModel(Optional options = "")
getJsChartModel = Base.getJsChartModel(options)
End Function