# Public and for release, CBEC v3.2.06 Build 4231+ [29th September, 2025] # # Copyright(c) Ivyware Pty Ltd 2018-25 (all rights reserved) # MELBOURNE, VICTORIA, AUSTRALIA, 3000 # # This file is provided as-is by Ivyware. No claims are made as # to fitness for any particular purpose. No warranties of any kind # are expressed or implied. The recipient agrees to determine # applicability of information provided. # # Ivyware hereby grants the right to freely use the information # supplied in this file for the creation of Python Advisor and Scanner # scripts supporting the Chartboard Application, and to make copies of # this file in any form for internal or external distribution as long as # this notice remains attached. # # No waranty or suitability for purpose is implied. # # Chartboard Extension Classes (CBEC) for Python Advisor and Scanner # Automation scripts # NOTES: Set of aggregation classes based on Chartboard python scripting # extension functions. Advisor and Scanner environments common. # Download latest version from # https://www.ivyware.com.au/PythonScripts/PythonCBEC.pyw # : The supporting TestPythonCBEC.pyw script is provided as both a test # and sample to run over your charts. Exposes most of the Chartboard # callbacks that can be used from the Advisor and Scanner scripts. # Download latest version from # https://www.ivyware.com.au/PythonScripts/TestPythonCBEC.pyw # : Advisor and Scanner scripts run under functionally separate Chartboard # environments (CViewTab's). For this reason Advisor scripts are # allocated the python extension .pya and Scanner scripts # are allocated the python extension .pys Both can reference # this PythonCBEC file # : Requirement is for python 3.8 to be installed # : Can be enhanced as circumstances dictate. However, it should be # be renamed given each successive Chartboard release over-writes this # file. # ***: CBEC under development and subject to change without notice*** # import string import sys from tkinter.tix import INTEGER from xml.dom.pulldom import SAX2DOM import P2Draw import P2Model import P2Series import P2Seriesob import P2Chart import P2Stack # Only referenced from Advisor scripts (*.pya) import P2Scanner # Only referenced from Scanner scripts (*.pys) import P2View import P2Root import P2Helpers import ctypes # An included library with Python install. from datetime import datetime ###################### # Constants - Period Units or Bar Interval (Chartboard internals) PUNITS_Default: int = 0 PUNITS_Year: int = 1 PUNITS_Quarter: int = 2 PUNITS_Month: int = 3 PUNITS_Week: int = 4 PUNITS_Day: int = 5 ###################### # DSeriesob base class # NOTES: Some DSeries support the automatic fitting of DSeries objects # according to the calculated value. Examples include "Harmonics" # and "Reversals" # : Charts support multiple DSeries and hence it is therefore possible # for Charts to support multiple DSeries object types. Refer OHLCvs Charts. # : Usually generated via DSeries.Factory() # : Base class and derivatives usable from both Advisor and Scanner # environments class DSeriesob: def __init__ ( self, hDSeriesob, sTypeob, hRefob, sRefVerb ): self.hDSeriesob = hDSeriesob # Reference handle for this DSeriesob self.sTypeob: str = sTypeob # Type of DSeriesob 'Harmonics', 'Reversals' etc #self.hDSeriesob = P2Series.GetObject(self.hSeries, self.sTypeob, hRefob, sRefVerb ) # Validity of contained DSeriesob def IsEmpty ( self ) -> bool: if self.hDSeriesob == 0 : return True return False # Select both raw and calculated values from DSeriesob # NOTES: NULL return flags no-data or request out of range def GetValue_d(self, sValueName) -> float: return P2Seriesob.GetValue_d(self.hDSeriesob, sValueName) def GetValue_i(self,sValueName) -> int: return P2Seriesob.GetValue_i(self.hDSeriesob,sValueName) def GetValue_b(self,sValueName) -> bool: return P2Seriesob.GetValue_b(self.hDSeriesob,sValueName) def GetValue_s(self,sValueName) -> str: return P2Seriesob.GetValue_s(self.hDSeriesob,sValueName) def SetParam_i(self,sParamName,iParam) -> int: return P2Seriesob.SetParam_i(self.hDSeriesob,sParamName,iParam) def SetConfig_i(self,sConfigName,iValue) -> int: return P2Seriesob.SetConfig_i(self.hDSeriesob,sConfigName,iValue) # # DSeries Harmonic object class class DSeriesobHarmonic(DSeriesob): def __init__ ( self, hDSeriesob, hRefob, sRefVerb ): super().__init__ ( hDSeriesob, 'Harmonics', hRefob, sRefVerb ) self.Sync() # Synchronise Harmonic Object parameters def Sync ( self ): self.dKvalue = 0 #P2Series.GetParam_d(self.hDSeries,'Kvalue') self.iSMAperiods = 0 #P2Series.GetParam_i(self.hDSeries,'SMAperiods') return # # DSeries Reversals object class class DSeriesobReversal(DSeriesob): def __init__ ( self, hDSeriesob, hRefob, sRefVerb ): super().__init__ ( hDSeriesob, 'Reversals', hRefob, sRefVerb ) self.Sync() # Synchronise Reversal Object parameters def Sync ( self ): self.iEMAperiods = 0 # P2Series.GetParam_i(self.hDSeriesob,'EMAperiods') return ###################### # DSeries base class # NOTES: Multiple DSeries may exist on a single chart each containing its # own unique variant of the displayed data. Each chart indicator. # overlay etc is usually supported by a DSeries that can be referenced # : Usually generated via DSeries.Factory() # : Base class and derivatives usable from both Advisor and Scanner # environnments. # :'hChart' is the Chartboard handle for the parent chart of this DSeries # :'sDSeriesName' is the name of the DSeries class DSeries: def __init__ ( self, hChart, sDSeriesName ): self.hChart = hChart self.sDSeriesName: str = sDSeriesName self.sDSeriesType: str = P2Chart.DSeriesType(self.hChart,self.sDSeriesName) self.hDSeries = P2Chart.DSeriesOpen(self.hChart, self.sDSeriesName) self.nPaintEoD: int = P2Series.Getenvar_i(self.hDSeries,'PaintEoD') self.nBarCount: int = P2Series.BarCount(self.hDSeries, 0 ) # Check if nominated DSeries exists for nominated chart def Exists ( self ): if P2Chart.DSeriesExists(self.oChart.sChartName, self.sDSeriesName) == 'exists': return True return False def PaintEoD(self,bPaintEoD): self.nPaintEoD = P2Series.Setenvar_i(self.hDSeries,'PaintEoD',bPaintEoD) # Select both raw and calculated values from DSeries # NOTES: GetValue_i(sValueName,ePunits,nBoFset) returns an integer value # passed parameters. NULL return flags no-data or request out of range # :'sValueName' is the name of the value to be retrieved # :'sParamName' is the name of the parameter to be set or retrieved # :'ePUnits' is the period units for the value to be retrieved # :'nBoFset' is the bar offset from the current DSeries cursor position # # GetValue_d(sValueName,ePUnits,nBoFset) -> float: # sValueName :'Open' - Raw market Open value # 'High' - Raw market High value # 'Low' - Raw market Low value # 'Close' - Raw market Close value # 'Volume' - Raw market Volume value # 'DATE' - Dataset market Date, both datetime and COleDateTime formats # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position def GetValue_d(self,sValueName,ePUnits,nBoFset=int(0)) -> float: return P2Series.GetValue_d(self.hDSeries,sValueName,ePUnits,nBoFset) def GetValue_dt(self,sValueName,ePUnits,nBoFset=int(0)) -> datetime: return P2Series.GetValue_dt(self.hDSeries,sValueName,ePUnits,nBoFset) # Get calculated integer value reltive to the current DSeries cursor def GetValue_i(self,sValueName,ePUnits,nBoFset) -> int: return P2Series.GetValue_i(self.hDSeries,sValueName,ePUnits,nBoFset) def GetObject(self,sObjectType,ePUnits,hRefObject,sObjectVerb): return P2Series.GetObject(self.hDSeries,sObjectType,ePUnits,hRefObject,sObjectVerb) # Get calculation integer paremeter value from DSeries def GetParam_i(self,sParamName) -> int: return P2Series.GetParam_i(self.hDSeries,sParamName) # Set calculation integer paremeter value for DSeries def SetParam_i(self,sParamName,iParam) -> int: return P2Series.SetParam_i(self.hDSeries,sParamName,iParam) def SetConfig_i(self,sConfigName,iValue) -> int: return P2Series.SetConfig_i(self.hDSeries,sConfigName,iValue) # Manage Automation shade bars # NOTES: Either activates or clears nominated DSeries shade bar. # : Period shade bars can be used to manage state and toggle display def PYCB_ShadeBarUpdate(self,ePUnits,nOffset,iState): P2Series.PYCB_ShadeBarUpdate(self.hDSeries,ePUnits,nOffset,iState) return def PYCB_ShadeBarSelect(self,ePUnits,iOffset): return P2Series.PYCB_ShadeBarSelect(self.hDSeries,ePUnits) def PYCB_ShadeBarClear(self,ePUnits): P2Series.PYCB_ShadeBarClear(self.hDSeries,ePUnits) return # Workspace environment related variables # NOTES: Used to interact with the workspace at an environmental, # visual or summary level independant of DSeries calculations etc def Getenvar_i(self,sEnvarname,iEnvarvalue) -> int: return P2Series.Getenvar_i(self.hDSeries,sEnvarname) def Getenvar_s(self,sEnvarname,iEnvarvalue) -> str: return P2Series.Getenvar_s(self.hDSeries,sEnvarname) def Setenvar_i(self,sEnvarname,iValue) -> int: P2Series.Setenvar_i(self.hDSeries,sEnvarname,iValue) def Setenvar_s(self,sEnvarname,sValue): P2Series.Setenvar_s(self.hDSeries,sEnvarname,sValue) # # BB DSeries class - Bollinger Bands, ChartOHLCvs overlay # NOTES: Bollinger Bands are a volatility indicator that consists of a # middle band (SMA) and two outer bands (standard deviations from the # middle band). They are used to identify overbought and oversold # conditions in the market. # : Refer CRoot->CView->CStackOHLCvs->ChartBB.DSeriesFactory('BB') # for DSeriesBB object creation path. class DSeriesBB(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise BB parameters # NOTES: 'Kvalue' is the number of standard deviations used to calculate BB # : 'SMAperiods' is the number of periods used to calculate the SMA def Sync ( self ): self.dKvalue: float = P2Series.GetParam_d(self.hDSeries,'Kvalue') self.iSMAperiods: int = P2Series.GetParam_i(self.hDSeries,'SMAperiods') # DSeries extensions # GetParam_i(sParamName,iParam) -> int: # sParamName :'SMAperiods' - number of periods used to calculate the SMA # GetParam_d(sParamName,dParam) -> float # sParamName :'KValue' - number of standard deviations used to calculate BB's # GetValue_i(sValueName,ePUnits,nBoFset) -> int: # sValueName :'n/a' - not applicable # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # GetValue_d(sValueName,ePUnits,nBoFset) -> float: # sValueName :'BBUpper' - Upper Bollinger Band value # 'BBMiddle'- Middle Bollinger Band value # 'BBLower' - Lower Bollinger Band value # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # # CCI DSeries class - Commodity Channel Index # NOTES: CCI is a momentum-based oscillator that measures the deviation of # the price from its average. It is used to identify overbought and # oversold conditions in the market. # : Refer CRoot->CView->CStackOHLCvs->ChartCCI.DSeriesFactory('CCI') # for DSeriesCCI object creation path. class DSeriesCCI(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise CCI parameters # NOTES: 'CCIperiods' is the number of periods used to calculate the CCI def Sync ( self ): self.iCCIperiods: int = P2Series.GetParam_i(self.hDSeries,'CCIperiods') return # DSeries extensions # GetParam_i(sParamName,iParam) -> int: # sParamName :'CCIperiods' - number of periods used to calculate the CCI # GetParam_d(sParamName,dParam) -> float # sParamName 'n/a' - not applicable # GetValue_i(sValueName,ePUnits,nBoFset) -> int: # sValueName :'n/a' - not applicable # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # GetValue_d(sValueName,ePUnits,nBoFset) -> float: # sValueName :'CCI' - CCI value # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # # Chaikin DSeries class - Chaikin Oscillator # NOTES: Chaikin Oscillator is a volume-based indicator that measures the # difference between the 3-day and 10-day exponential moving averages # of the Accumulation/Distribution Line. It is used to identify # potential trend reversals and confirm price movements. # : Refer CRoot->CView->CStackOHLCvs->ChartChaikin.DSeriesFactory('Chaikin') # for DSeriesChaikin object creation path. class DSeriesChaikin(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise Chaikin parameters # NOTES: DSeriesChaikin.GetParam_i(self.hDSeries,sParamName) # 'FASTperiods' is the number of periods used to calculate the fast EMA # 'SLOWperiods' is the number of periods used to calculate the slow EMA def Sync ( self ): self.iFASTperiods: int = P2Series.GetParam_i(self.hDSeries,'FASTperiods') self.iSLOWperiods: int = P2Series.GetParam_i(self.hDSeries,'SLOWperiods') return # # Chandelier DSeries class - Short and Long exit strategies, ChartOHLCvs overlay # NOTES: Chandelier is a volatility-based exit strategy that uses the Average True # Range (ATR) to determine the exit points for a trade. # : Refer CRoot->CView->CStackOHLCvs->ChartChandelier.DSeriesFactory('Chandelier') # for DSeriesChandelier object creation path. class DSeriesChandelier(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise unique Chandelier parameters # NOTES: 'SHORTperiods' is the number of periods used to calculate the short exit # : 'LONGperiods' is the number of periods used to calculate the long exit # : 'SHORTmultATR' is the multiplier used to calculate the short exit # : 'LONGmultATR' is the multiplier used to calculate the long exit def Sync ( self ): self.iSHORTperiods: int = P2Series.GetParam_i(self.hDSeries,'SHORTperiods') self.iLONGperiods : int = P2Series.GetParam_i(self.hDSeries,'LONGperiods') self.dSHORTmultATR: float = P2Series.GetParam_d(self.hDSeries,'SHORTmultATR') self.dLONGmultATR: float = P2Series.GetParam_d(self.hDSeries,'LONGmultATR') return # # CMF DSeries class - Chaikin Money Flow # NOTES: CMF is a volume-based indicator that measures the buying and selling pressure # in the market. It is calculated by multiplying the volume by the # Accumulation/Distribution Line and then dividing it by the total volume. # : It is used to identify potential trend reversals and confirm price movements. # : Refer CRoot->CView->CStackOHLCvs->ChartCMF.DSeriesFactory('CMF') # for DSeriesCMF object creation path. class DSeriesCMF(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise CMF parameters def Sync ( self ): self.iCMFperiods: int = P2Series.GetParam_i(self.hDSeries,'CMFperiods') return # # Coppock DSeries class - Coppock Indicator # NOTES: Coppock is a momentum-based indicator that measures the rate of change # of the price over a specified period. It is used to identify potential # trend reversals and confirm price movements. # : It is calculated by taking the rate of change of the price over a # specified period and then applying a weighted moving average to it. # : Refer CRoot->CView->CStackOHLCvs->ChartCoppock.DSeriesFactory('Coppock') # for DSeriesCoppock object creation path. class DSeriesCoppock(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise unique Coppock parameters def Sync ( self ): self.iROCAperiods: int = P2Series.GetParam_i(self.hDSeries,'ROCAperiods') self.iROCBperiods: int = P2Series.GetParam_i(self.hDSeries,'ROCBperiods') self.iWMAperiods: int = P2Series.GetParam_i(self.hDSeries,'WMAperiods') return # # EFI DSeries class - Elder Ray or Force Index # NOTES: Elder Ray is a volume-based indicator that measures the buying and selling # pressure in the market. It is calculated by taking the difference between # the price and the exponential moving average (EMA) of the price over a # specified period. It is used to identify potential trend reversals and # confirm price movements. # : It is also known as the Force Index and is used to measure the strength # of a trend. The Elder Ray consists of two lines: the Bull Power line and # the Bear Power line. The Bull Power line is the difference between the # price and the EMA of the price over a specified period, while the Bear # Power line is the difference between the price and the EMA of the price # over a specified period. # : Refer CRoot->CView->CStackOHLCvs->ChartEFI.DSeriesFactory('EFI') # for DSeriesEFI object creation path. class DSeriesEFI(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise EFI parameters def Sync ( self ): self.iEFIperiods: int = P2Series.GetParam_i(self.hDSeries,'EFIperiods') return # # EhlerFT DSeries class - Ehlers Fisher Transform (EhlerFT) # NOTES: Ehlers Fisher Transform is a technical indicator that transforms # the price data into a Gaussian distribution. It is used to identify # potential trend reversals and confirm price movements. The Ehlers # Fisher Transform is a variation of the Fisher Transform that uses # a different calculation method to transform the price data. # : It is calculated by taking the difference between the price and the # exponential moving average (EMA) of the price over a specified period # and then applying a Fisher Transform to it. The Fisher Transform # is a mathematical function that transforms the price data into a # Gaussian distribution. # : Refer CRoot->CView->CStackOHLCvs->ChartEhlerFT.DSeriesFactory('EhlerFT') # for DSeriesEhlerFt object creation path. class DSeriesEhlerFT(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise EhlerFT parameters def Sync ( self ): self.iEhlerFTperiods: int = P2Series.GetParam_i(self.hDSeries,'EhlerFTperiods') self.iSignalperiods: int = P2Series.GetParam_i(self.hDSeries,'Signalperiods') return # # EMAnnn DSeries class - Exponential moving average # NOTES: Name format EMAnnn[y|q|m|w|d] #class DSeriesEMAnnn(DSeries): # def __init__ ( self, hChart, sDSeriesName ): # super().__init__ ( hChart, sDSeriesName ) # self.Sync() # # Synchronise EMAnnn data sets # def Sync ( self ): # self.iEMAperiods = P2Series.GetParam_i ( self.hDSeries, "EMAperiods" ) # self.ePUnits = P2Series.GetParam_i ( self.hDSeries, "PUnits" ) # return # # DPO DSeries class - Detrended Price Oscillator # NOTES: Detrended Price Oscillator (DPO) is a technical indicator that # measures the difference between the price and a moving average of the # price over a specified period. It is used to identify potential trend # reversals and confirm price movements. The DPO is calculated by taking # the difference between the price and a moving average of the price # over a specified period and then applying a detrending function to it. # : The detrending function is used to remove the trend from the price data # and to make it easier to identify potential trend reversals. The DPO # is a variation of the Moving Average Convergence Divergence (MACD) # indicator that uses a different calculation method to detrend the price # data. # : Refer CRoot->CView->CStackOHLCvs->ChartDPO.DSeriesFactory('DPO') # for DSeriesDPO object creation path. class DSeriesDPO(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise DPO parameters def Sync ( self ): self.iDPOperiods = P2Series.GetParam_i(self.hDSeries,'DPOperiods') return # # Ichimoku DSeries class - Ichimoku Cloud, ChartOHLCvs overlay # NOTES: Ichimoku Cloud is a technical indicator that consists of five lines: # Tenkan-sen, Kijun-sen, Senkou Span A, Senkou Span B, and Chikou Span. # It is used to identify potential trend reversals and confirm price # movements. The Ichimoku Cloud is a comprehensive indicator that provides # a complete picture of the market by combining multiple indicators into # a single chart. It is used to identify potential trend reversals and # confirm price movements by providing a complete picture of the market. # : The Ichimoku Cloud is calculated by taking the average of the highest # and lowest prices over a specified period and then applying a # moving average to it. The Tenkan-sen is the average of the highest and # lowest prices over a specified period, while the Kijun-sen is the average # of the highest and lowest prices over a longer period. The Senkou Span A # is the average of the Tenkan-sen and Kijun-sen, while the Senkou Span B # is the average of the highest and lowest prices over a longer period. # The Chikou Span is the closing price of the current period shifted back # by a specified number of periods. # : It is used to identify potential trend reversals and confirm price # movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartIchimoku.DSeriesFactory('Ichimoku') # for DSeriesIchimoku object creation path. class DSeriesIchimoku(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise Ichimoku parameters def Sync ( self ): self.iTenkanperiods: int = P2Series.GetParam_i(self.hDSeries,'Tenkanperiods') self.iKijunperiods: int = P2Series.GetParam_i(self.hDSeries,'Kijunperiods') self.iSenkouperiods: int = P2Series.GetParam_i(self.hDSeries,'Senkouperiods') self.iChikouperiods: int = P2Series.GetParam_i(self.hDSeries,'Chikouperiods') return # # KAMA DSeries class - Kaufmans Adaptive Moving Average, ChartOHLCvs overlay # NOTES: KAMA is a technical indicator that adapts to the volatility of the market # by adjusting the length of the moving average based on the price # movement. It is used to identify potential trend reversals and confirm # price movements. The KAMA is calculated by taking the difference between # the price and the exponential moving average (EMA) of the price over a # specified period and then applying a Kaufman Adaptive Moving Average # (KAMA) to it. # The KAMA is a variation of the Moving Average Convergence # Divergence (MACD) indicator that uses a different calculation method to # adapt to the volatility of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartKAMA.DSeriesFactory('KAMA') # for DSeriesKAMA object creation path. class DSeriesKAMA(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise KAMA parameters def Sync ( self ): self.iERperiods: int = P2Series.GetParam_i(self.hDSeries,'ERperiods') self.iFASTperiods: int = P2Series.GetParam_i(self.hDSeries,'FASTperiods') self.iSLOWperiods: int = P2Series.GetParam_i(self.hDSeries,'SLOWperiods') return # # Keltner DSeries class - Keltner Channels, ChartOHLCvs overlay # NOTES: Keltner Channels are a volatility-based indicator that consists of a # middle band (Exponential Moving Average) and two outer bands (Average # True Range). They are used to identify overbought and oversold # conditions in the market. The Keltner Channels are calculated by taking # the Exponential Moving Average (EMA) of the price over a specified # period and then applying the Average True Range (ATR) to it. The # Keltner Channels are a variation of the Bollinger Bands that uses a # different calculation method to determine the outer bands. # : The Keltner Channels are used to identify potential trend reversals and # confirm price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartKeltner.DSeriesFactory('Keltner') # for DSeriesKeltner object creation path. class DSeriesKeltner(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise Keltner parameters def Sync ( self ): self.iEMAperiods: int = P2Series.GetParam_i(self.hDSeries,'EMAperiods') self.iATRperiods: int = P2Series.GetParam_i(self.hDSeries,'ATRperiods') self.dATRoffset: float= P2Series.GetParam_d(self.hDSeries,'ATRoffset') return # # KST DSeries class - Pring's Know Sure Thing # NOTES: KST is a momentum-based oscillator that measures the rate of change # of the price over a specified period. It is used to identify potential # trend reversals and confirm price movements. The KST is calculated by # taking the rate of change of the price over a specified period and # then applying a weighted moving average to it. The KST is a variation # of the Moving Average Convergence Divergence (MACD) indicator that uses # a different calculation method to measure the rate of change of the # price over a specified period. # : Refer CRoot->CView->CStackOHLCvs->ChartKST.DSeriesFactory('KST') # for DSeriesKST object creation path. class DSeriesKST(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise KST parameters def Sync ( self ): self.iROC1periods: int = P2Series.GetParam_i(self.hDSeries,'ROC1periods') self.iROC2periods: int = P2Series.GetParam_i(self.hDSeries,'ROC2periods') self.iROC3periods: int = P2Series.GetParam_i(self.hDSeries,'ROC3periods') self.iROC4periods: int = P2Series.GetParam_i(self.hDSeries,'ROC4periods') self.iSMA1periods: int = P2Series.GetParam_i(self.hDSeries,'SMA1periods') self.iSMA2periods: int = P2Series.GetParam_i(self.hDSeries,'SMA2periods') self.iSMA3periods: int = P2Series.GetParam_i(self.hDSeries,'SMA3periods') self.iSMA4periods: int = P2Series.GetParam_i(self.hDSeries,'SMA4periods') self.iSignalperiods: int = P2Series.GetParam_i(self.hDSeries,'Signalperiods') return # DSeries extensions # GetParam_i(sParamName,iParam) -> int: # sParamName :'ROC1periods' - Number of periods used to calculate the first Rate of Change # sParamName :'ROC2periods' - Number of periods used to calculate the second Rate of Change # sParamName :'ROC3periods' - Number of periods used to calculate the third Rate of Change # sParamName :'ROC4periods' - Number of periods used to calculate the fourth Rate of Change # sParamName :'SMA1periods' - Number of periods used to calculate the first SMA # sParamName :'SMA2periods' - Number of periods used to calculate the second SMA # sParamName :'SMA3periods' - Number of periods used to calculate the third SMA # sParamName :'SMA4periods' - Number of periods used to calculate the fourth SMA # sParamName :'Signalperiods' - Number of periods used to calculate the signal line # GetParam_d(sParamName,dParam) -> float # sParamName :'n/a' - not applicable # GetValue_i(sValueName,ePUnits,nBoFset) -> int: # sValueName :'BoS' - Buy(1) or Sell(-1) signal # 'BoSage' - Buy(1) or Sell(-1) signal age in ePUnits # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # GetValue_d(sValueName,ePUnits,nBoFset) -> float: # sValueName :'KST' - Calaculated KST value # 'KSTsignal' - Calculated KST signal line value # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # # MACD DSeries class - Moving Average Convergence Divergence # NOTES: MACD is a momentum-based oscillator that measures the difference # between two exponential moving averages (EMAs) of the price over a # specified period. It is used to identify potential trend reversals # and confirm price movements. The MACD is calculated by taking the # difference between the 12-day EMA and the 26-day EMA of the price # and then applying a 9-day EMA to the result. The MACD is a variation # of the Moving Average Convergence Divergence (MACD) indicator that uses # a different calculation method to measure the difference between two # exponential moving averages (EMAs) of the price over a specified period. # : Refer CRoot->CView->CStackOHLCvs->ChartMACD.DSeriesFactory('MACD') # for DSeriesMACD object creation path. class DSeriesMACD(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise MACD parameters def Sync ( self ): self.iEMA1periods: int = P2Series.GetParam_i(self.hDSeries,'EMA1periods') self.iEMA2periods: int = P2Series.GetParam_i(self.hDSeries,'EMA2periods') self.iSignalperiods: int = P2Series.GetParam_i(self.hDSeries,'Signalperiods') return # DSeries extensions # GetParam_i(sParamName) -> int # sParamName :'EMA1periods' - number of periods used to calculate the first EMA # :'EMA2periods' - number of periods used to calculate the second EMA # :'Signalperiods' - number of periods used to calculate the signal line # GetParam_d(sParamName) -> float # sParamName :'n/a' - not applicable # GetValue_i(sValueName,ePUnits,nBoFset) -> int # sValueName :'BoS' - Buy(1) or Sell(-1) signal # 'BoSage' - Buy(1) or Sell(-1) signal age in ePUnits # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # GetValue_d(sValueName,ePUnits,nBoFset) -> float # sValueName :'MACD' - MACD value # 'MACDsignal' - MACD signal line value # 'MACDiff' - MACD/MACDsignal difference value # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # # MAMA DSeries class - Ehlers MESA Adaptive Moving Average, ChartOHLCvs overlay # NOTES: MAMA is a technical indicator that adapts to the volatility of the market # by adjusting the length of the moving average based on the price # movement. It is used to identify potential trend reversals and confirm # price movements. The MAMA is calculated by taking the difference between # the price and the exponential moving average (EMA) of the price over a # specified period and then applying a MESA Adaptive Moving Average # (MAMA) to it. The MAMA is a variation of the Moving Average Convergence # Divergence (MACD) indicator that uses a different calculation method to # adapt to the volatility of the market. # : The MAMA is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartMAMA.DSeriesFactory('MAMA') # for DSeriesMAMA object creation path. class DSeriesMAMA(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise MAMA parameters def Sync ( self ): self.dFastLimit: float = P2Series.GetParam_d(self.hDSeries,'FastLimit') self.dSlowLimit: float = P2Series.GetParam_d(self.hDSeries,'SlowLimit') return # # MFI DSeries class - Money Flow Index # NOTES: MFI is a volume-based oscillator that measures the buying and selling # pressure in the market. It is calculated by taking the difference # between the price and the exponential moving average (EMA) of the # price over a specified period and then applying a Money Flow Index # (MFI) to it. The MFI is a variation of the Moving Average Convergence # Divergence (MACD) indicator that uses a different calculation method to # measure the buying and selling pressure in the market. # : The MFI is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # NOTES: Refer CRoot->CView->CStackOHLCvs->ChartMFI.DSeriesFactory('MFI') # for DSeriesMFI object creation path. class DSeriesMFI(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise MFI data sets def Sync ( self ): self.iMFIperiods: int= P2Series.GetParam_i ( self.hDSeries, "MFIperiods" ) self.iOBought: int = P2Series.GetParam_i ( self.hDSeries, "OBought" ) self.iOSold: int = P2Series.GetParam_i ( self.hDSeries, "OSold" ) return # # MSA DSeries class - Momentum Structural Analysis # NOTES: MSA is a technical indicator that measures the momentum of the price # movement by comparing the current price to the previous price over a # specified period. It is used to identify potential trend reversals # and confirm price movements. The MSA is calculated by taking the # difference between the current price and the previous price over a # specified period and then applying a Momentum Structural Analysis # (MSA) to it. The MSA is a variation of the Moving Average Convergence # Divergence (MACD) indicator that uses a different calculation method to # measure the momentum of the price movement by comparing the current # price to the previous price over a specified period. # : Refer CRoot->CView->CStackOHLCvs->ChartMSA.DSeriesFactory('MSA') # for DSeriesMSA object creation path. class DSeriesMSA(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise MSA data sets def Sync ( self ): self.iMSAperiods: int= P2Series.GetParam_i ( self.hDSeries, "MSAperiods" ) return # # OBV DSeries class - On Balance Volume # NOTES: OBV is a volume-based indicator that measures the buying and selling # pressure in the market. It is calculated by taking the difference # between the price and the exponential moving average (EMA) of the # price over a specified period and then applying an On Balance Volume # (OBV) to it. The OBV is a variation of the Moving Average Convergence # Divergence (MACD) indicator that uses a different calculation method to # measure the buying and selling pressure in the market. # : Refer CRoot->CView->CStackOHLCvs->ChartOBV.DSeriesFactory('OBV') # for DSeriesOBV object creation path. class DSeriesOBV(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise OBV data sets def Sync ( self ): return # # OHLCvs DSeries class - Open, High, Low, Close class DSeriesOHLCvs(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise OHLCvs data sets def Sync ( self ): return # # Donchian DSeries class - Donchian Price Channels, ChartOHLCvs overlay # NOTES: Donchian Channels are a volatility-based indicator that consists of # two outer bands (highest high and lowest low) and a middle band # (average of the highest high and lowest low). They are used to # identify overbought and oversold conditions in the market. The # Donchian Channels are calculated by taking the highest high and # lowest low over a specified period and then applying a moving average # to it. The Donchian Channels are a variation of the Bollinger Bands # that uses a different calculation method to determine the outer bands. # : The Donchian Channels are used to identify potential trend reversals # and confirm price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartDonchian.DSeriesFactory('Donchian') # for DSeriesDonchian object creation path. class DSeriesDonchian(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise PChan data sets def Sync ( self ): self.iPCperiods: int = P2Series.GetParam_i ( self.hDSeries, "PCperiods" ) return # # PBars DSeries class - Price Variation Bars # NOTES: Refer CRoot->CView->CStackOHLCvs->ChartPBars.DSeriesFactory('PBars') # for DSeriesPBars object creation path. class DSeriesPBars(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise PBars data sets def Sync ( self ): return # # PFigure DSeries class - Primary Point and Figure DSeries for ChartPFigure # in CStackPFigure # NOTES: PFigure is a price-based indicator that consists of a series of # price levels that are used to identify potential trend reversals # and confirm price movements. It is used to identify potential trend # reversals and confirm price movements by providing a complete picture # of the market. The PFigure is calculated by taking the price levels # over a specified period and then applying a PFigure to it. The PFigure # is a variation of the Moving Average Convergence Divergence (MACD) # indicator that uses a different calculation method to measure the # price levels over a specified period. # NOTES: Refer CRoot->CView->CStackPFigure->ChartPFigure.DSeriesFactory('PFigure') # for DSeriesPFigure object creation path. CalcType_PanF_TRADITIONAL: int = 1 CalcType_PanF_MANUAL: int = 2 CalcType_PanF_PERCENT: int = 3 class DSeriesPFigure(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise PFigure data sets def Sync ( self ): self.iCalcType: int = P2Series.GetParam_i ( self.hDSeries, "CalcType" ) return # # PMO DSeries class - Price Momentum Oscillator # NOTES: PMO is a momentum-based oscillator that measures the rate of change # of the price over a specified period. It is used to identify potential # trend reversals and confirm price movements. The PMO is calculated by # taking the rate of change of the price over a specified period and # then applying a Price Momentum Oscillator (PMO) to it. The PMO is a # variation of the Moving Average Convergence Divergence (MACD) indicator # that uses a different calculation method to measure the rate of change # of the price over a specified period. # : The PMO is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartPMO.DSeriesFactory('PMO') # for DSeriesPMO object creation path. class DSeriesPMO(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise PMO data sets def Sync ( self ): self.iPMO1periods: int = P2Series.GetParam_i ( self.hDSeries, "PMO1periods" ) self.iPMO2periods: int = P2Series.GetParam_i ( self.hDSeries, "PMO2periods" ) self.iEMAperiods: int = P2Series.GetParam_i ( self.hDSeries, "EMAperiods" ) return # # PPO DSeries class - Percentage Volume Oscillator ## NOTES: PPO is a momentum-based oscillator that measures the rate of change # of the price over a specified period. It is used to identify potential # trend reversals and confirm price movements. The PPO is calculated by # taking the rate of change of the price over a specified period and # then applying a Percentage Price Oscillator (PPO) to it. The PPO is a # variation of the Moving Average Convergence Divergence (MACD) indicator # that uses a different calculation method to measure the rate of change # of the price over a specified period. # : The PPO is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartPPO.DSeriesFactory('PPO') # for DSeriesPPO object creation path. class DSeriesPPO(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise PPO data sets def Sync ( self ): self.iEMA1periods: int = P2Series.GetParam_i(self.hDSeries,'EMA1periods') self.iEMA2periods: int = P2Series.GetParam_i(self.hDSeries,'EMA2periods') self.iSignalperiods: int = P2Series.GetParam_i(self.hDSeries,'Signalperiods') # DSeries extensions # GetParam_i(sParamName) -> int # sParamName :'EMA1periods' - number of periods used to calculate the first EMA # :'EMA2periods' - number of periods used to calculate the second EMA # :'Signalperiods' - number of periods used to calculate the signal line # GetParam_d(sParamName) -> float # sParamName :'n/a' - not applicable # GetValue_i(sValueName,ePUnits,nBoFset) -> int # sValueName :'BoS' - Buy(1) or Sell(-1) signal # 'BoSage' - Buy(1) or Sell(-1) signal age in ePUnits # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # GetValue_d(sValueName,ePUnits,nBoFset) -> float # sValueName :'PPO' - Calculated PPO value # 'PPOsignal' - Calculated PPO signal line value # 'PPOiff' - PPO/PPOsignal difference value # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # # PVO DSeries class - Percentage Volume Oscillator # NOTES: PVO is a volume-based oscillator that measures the rate of change # of the volume over a specified period. It is used to identify potential # trend reversals and confirm price movements. The PVO is calculated by # taking the rate of change of the volume over a specified period and # then applying a Percentage Volume Oscillator (PVO) to it. The PVO is a # variation of the Moving Average Convergence Divergence (MACD) indicator # that uses a different calculation method to measure the rate of change # of the volume over a specified period. # : The PVO is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartPVO.DSeriesFactory('PVO') # for DSeriesPVO object creation path. class DSeriesPVO(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise PVO data sets def Sync ( self ): self.iHIperiods: int = P2Series.GetParam_i ( self.hDSeries, "HIperiods" ) self.iLOperiods: int = P2Series.GetParam_i ( self.hDSeries, "LOperiods" ) self.iPVOperiods: int = P2Series.GetParam_i ( self.hDSeries, "PVOperiods" ) return # # ROC DSeries class - Rate of Change # NOTES: ROC is a momentum-based oscillator that measures the rate of change # of the price over a specified period. It is used to identify potential # trend reversals and confirm price movements. The ROC is calculated by # taking the rate of change of the price over a specified period and # then applying a Rate of Change (ROC) to it. The ROC is a variation # of the Moving Average Convergence Divergence (MACD) indicator that uses # a different calculation method to measure the rate of change of the # price over a specified period. # : The ROC is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartROC.DSeriesFactory('ROC') # for DSeriesROC object creation path. class DSeriesROC(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise ROC data sets def Sync ( self ): self.iROCperiods: int = P2Series.GetParam_i ( self.hDSeries, "ROCperiods" ) return # # EMAnnn DSeries class - Exponential moving average, ChartOHLCvs overlay # NOTES: Name format EMAnnn[y|q|m|w|d] # NOTES: EMAnnn is a technical indicator that adapts to the volatility of the market # by adjusting the length of the moving average based on the price # movement. It is used to identify potential trend reversals and confirm # price movements. The EMAnnn is calculated by taking the difference between # the price and the exponential moving average (EMA) of the price over a # specified period and then applying an Exponential Moving Average # (EMAnnn) to it. # : Refer CRoot->CView->CStackOHLCvs->ChartOHLCvs.DSeriesEMAnnnFactory(nEMAperiods,ePUnits) # for DSeriesEMAnnn object creation path. # 'nEMAPeriods' is the number of periods for the EMA, and # 'ePUnits' is the period units as per PUNITS_Year=1, PUNITS_Quarter=2, # PUNITS_Month=3, PUNITS_Week=4, PUNITS_Day=5 def MakeDSeriesEMAname (nEMAperiods,ePUnits): #f"{num:0{length}d}" if ePUnits == 5 : return f"EMA{nEMAperiods:0{3}d}d" if ePUnits == 4 : return f"EMA{nEMAperiods:0{3}d}w" if ePUnits == 3 : return f"EMA{nEMAperiods:0{3}d}m" if ePUnits == 2 : return f"EMA{nEMAperiods:0{3}d}q" if ePUnits == 1 : return f"EMA{nEMAperiods:0{3}d}y" return f"EMA{nEMAperiods:0{3}d}?" class DSeriesEMAnnn(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise EMAnnn data sets def Sync ( self ): self.iEMAperiods: int = P2Series.GetParam_i ( self.hDSeries, "EMAperiods" ) self.ePUnits: int = P2Series.GetParam_i ( self.hDSeries, "PUnits" ) return # # SMAnnn DSeries class - Simple moving average, ChartOHLCvs overlay # NOTES: Name format SMAnnn[y|q|m|w|d] # : Refer CRoot->CView->CStackOHLCvs->ChartOHLCvs.DSeriesSMAnnnFactory(nSMAperiods,ePUnits) # for DSeriesSMAnnn object creation path. # 'nSMAPeriods' is the number of periods for the SMA, and # 'ePUnits' is the period units as per PUNITS_Year=1, PUNITS_Quarter=2, # PUNITS_Month=3, PUNITS_Week=4, PUNITS_Day=5 def MakeDSeriesSMAname (nSMAperiods,ePUnits): #f"{num:0{length}d}" if ePUnits == 5 : return f"SMA{nSMAperiods:0{3}d}d" if ePUnits == 4 : return f"SMA{nSMAperiods:0{3}d}w" if ePUnits == 3 : return f"SMA{nSMAperiods:0{3}d}m" if ePUnits == 2 : return f"SMA{nSMAperiods:0{3}d}q" if ePUnits == 1 : return f"SMA{nSMAperiods:0{3}d}y" return f"SMA{nSMAperiods:0{3}d}?" class DSeriesSMAnnn(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise SMAnnn data sets def Sync ( self ): self.iSMAperiods: int = P2Series.GetParam_i ( self.hDSeries, "SMAperiods" ) self.ePUnits: int = P2Series.GetParam_i ( self.hDSeries, "PUnits" ) return # # RSI DSeries class - Relative Strength Index # NOTES: RSI is a momentum-based oscillator that measures the speed and change # of price movements. It is used to identify overbought and oversold # conditions in the market. The RSI is calculated by taking the average # of the gains and losses over a specified period and then applying a # Relative Strength Index (RSI) to it. # : Refer CRoot->CView->CStackOHLCvs->ChartRSI.DSeriesFactory('RSI') # for DSeriesRSI object creation path. class DSeriesRSI(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise RSI data sets def Sync ( self ): self.iRSIperiods: int = P2Series.GetParam_i ( self.hDSeries, "RSIperiods" ) self.iOBought: int = P2Series.GetParam_i ( self.hDSeries, "OBought" ) self.iOSold: int = P2Series.GetParam_i ( self.hDSeries, "OSold" ) self.iOSold: int = DSeries.GetParam_i ( self, "OSold" ) return # DSeries extensions # GetParam_i(sParamName) -> int # sParamName :'RSIperiods' - number of periods used to calculate the RSI # :'OBought' - Overbought threshold level # :'OSold' - Oversold threshold level # GetParam_d(sParamName) float # sParamName :'n/a' - not applicable # GetValue_i(sValueName,ePUnits,nBoFset) returns an integer value # sValueName :'n/a' - not applicable # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # GetValue_d(sValueName,ePUnits,nBoFset) float: # # sValueName :'RSI' - RSI value # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # # SLOPE DSeries class - Linear Regression oscillator (SLOPE) # NOTES: Refer CRoot->CView->CStackOHLCvs->ChartSLOPE.DSeriesFactory('SLOPE') # for DSeriesSLOPE object creation path. class DSeriesSLOPE(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise SLOPE data sets def Sync ( self ): self.iPeriodsLINEAR: int = P2Series.GetParam_i ( self.hDSeries, "PeriodsLINEAR" ) self.iPeriodsPOLY2: int = P2Series.GetParam_i ( self.hDSeries, "PeriodsPOLY2" ) self.iPeriodsSAVITZKY: int = P2Series.GetParam_i ( self.hDSeries, "PeriodsSAVITZKY" ) self.iSmoothPeriods: int = P2Series.GetParam_i ( self.hDSeries, "SmoothPeriods" ) self.iSmoothEoD: int = P2Series.GetParam_i ( self.hDSeries, "SmoothEoD" ) return # # StochRSI DSeries class - Stohastics RSI # NOTES: StochRSI is a momentum-based oscillator that measures the speed and # change of price movements relative to the Relative Strength Index (RSI). # It is used to identify overbought and oversold conditions in the market. # The StochRSI is calculated by taking the RSI and applying a stochastic # oscillator to it. The StochRSI is a variation of the Moving Average # Convergence Divergence (MACD) indicator that uses a different calculation # method to measure the speed and change of price movements relative to # the RSI. # : The StochRSI is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartStochRSI.DSeriesFactory('StochRSI') # for DSeriesStochRSI object creation path. class DSeriesStochRSI(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise StochRSI data sets def Sync ( self ): self.iStochRSIperiods: int = P2Series.GetParam_i ( self.hDSeries, "StochRSIperiods" ) self.dOBought: float = P2Series.GetParam_d ( self.hDSeries, "OBought" ) self.dOSold: float = P2Series.GetParam_d ( self.hDSeries, "OSold" ) return # # SAR DSeries class - Parabolic Stop and Reverse, ChartOHLCvs overlay # NOTES: SAR is a trend-following indicator that is used to identify potential # trend reversals and confirm price movements. It is calculated by taking # the difference between the price and the exponential moving average (EMA) # of the price over a specified period and then applying a Parabolic Stop # and Reverse (SAR) to it. # : Refer CRoot->CView->CStackOHLCvs->ChartOHLCvs.DSeriesFactory('SAR') # for DSeriesSAR object creation path. class DSeriesSAR(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise SAR data sets def Sync ( self ): self.dAF: float = P2Series.GetParam_d ( self.hDSeries, "AF" ) self.dAFmax: float= P2Series.GetParam_d ( self.hDSeries, "AFmax" ) return # # STO DSeries class # NOTES: STO is a momentum-based oscillator that measures the speed and change # of price movements. It is used to identify overbought and oversold # conditions in the market. The STO is calculated by taking the average # of the gains and losses over a specified period and then applying a # Stochastic Oscillator (STO) to it. # : The STO is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # NOTES: Refer CRoot->CView->CStackOHLCvs->ChartSTO.DSeriesFactory('TDMA') # for DSeriesTDMA object creation path. class DSeriesSTO(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise STO data sets def Sync ( self ): self.iKperiods: int = P2Series.GetParam_i ( self.hDSeries, "Kperiods" ) self.iDperiods: int = P2Series.GetParam_i ( self.hDSeries, "Dperiods" ) self.iXperiods: int = P2Series.GetParam_i ( self.hDSeries, "Xperiods" ) return # # STDEV DSeries class - Volatility or Standard Deviation # NOTES: STDEV is a volatility-based indicator that measures the standard # deviation of the price over a specified period. It is used to identify # potential trend reversals and confirm price movements. The STDEV is # calculated by taking the standard deviation of the price over a # specified period and then applying a Standard Deviation (STDEV) to it. # : The STDEV is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartSTDEV.DSeriesFactory('STDEV') # for DSeriesSTDEV object creation path. class DSeriesSTDEV(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise STDEV data sets def Sync ( self ): self.iSTDEVperiods: int = P2Series.GetParam_i ( self.hDSeries, "STDEVperiods" ) return # # Shorts DSeries class # NOTES: Refer CRoot->CView->CStackOHLCvs->ChartShorts.DSeriesFactory('Shorts') # for DSeriesShorts object creation path, or # : Refer CRoot->CView->CStackPFigure->ChartShorts.DSeriesFactory('Shorts') # for DSeriesShorts object creation path. class DSeriesShorts(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise Shorts data sets def Sync ( self ): return # # TDMA DSeries class - Tom Demark Moving Average I, ChartOHLCvs overlay # NOTES: TDMA is a technical indicator that adapts to the volatility of the market # by adjusting the length of the moving average based on the price # movement. It is used to identify potential trend reversals and confirm # price movements. The TDMA is calculated by taking the difference between # the price and the exponential moving average (EMA) of the price over a # specified period and then applying a Tom Demark Moving Average (TDMA) to it. # : The TDMA is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartTDMA.DSeriesFactory('TDMA') # for DSeriesTDMA object creation path. class DSeriesTDMA(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise TDMA parameters def Sync ( self ): self.iLBperiodsI: int = P2Series.GetParam_i(self.hDSeries,'LBperiodsI') self.iAveragePeriodsI: int = P2Series.GetParam_i(self.hDSeries,'AveragePeriodsI') self.iExtendPeriodsI: int = P2Series.GetParam_i(self.hDSeries,'ExtendPeriodsI') return # # TDemark DSeries class - Tom Demark, ChartOHLCvs overlay # NOTES: TDemark is a technical indicator that adapts to the volatility of the market # by adjusting the length of the moving average based on the price # movement. It is used to identify potential trend reversals and confirm # price movements. The TDemark is calculated by taking the difference between # the price and the exponential moving average (EMA) of the price over a # specified period and then applying a Tom Demark (TDemark) to it. # : The TDemark is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartOHLCvs.DSeriesFactory('TDemark') # for DSeriesTDemark object creation path. class DSeriesTDemark(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise TDemark parameters def Sync ( self ): self.iLBperiods: int = P2Series.GetParam_i(self.hDSeries,'LBperiods') self.iSetupPeriods: int = P2Series.GetParam_i(self.hDSeries,'SetupPeriods') self.iCountdownLBperiods: int = P2Series.GetParam_i(self.hDSeries,'CountdownLBperiods') self.iCountdownPeriods: int = P2Series.GetParam_i(self.hDSeries,'CountdownPeriods') self.iComboLBperiods: int = P2Series.GetParam_i(self.hDSeries,'ComboLBperiods') self.iComboPeriods: int = P2Series.GetParam_i(self.hDSeries,'ComboPeriods') return # # TRIX DSeries class - Triple Smoothed Exponential Moving Average # NOTES: TRIX is a momentum-based oscillator that measures the rate of change # of the price over a specified period. It is used to identify potential # trend reversals and confirm price movements. The TRIX is calculated by # taking the rate of change of the price over a specified period and # then applying a Triple Smoothed Exponential Moving Average (TRIX) to it. # : The TRIX is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartATR.DSeriesFactory('TRIX') # for DSeriesTRIX object creation path. class DSeriesTRIX(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise TRIX data sets def Sync ( self ): self.iEMAperiods: int = P2Series.GetParam_i ( self.hDSeries, "EMAperiods" ) self.iSignalperiods: int = P2Series.GetParam_i ( self.hDSeries, "Signalperiods" ) return # DSeries extensions # GetParam_i(sParamName) -> int # sParamName :'EMAperiods' - Number of periods used to calculate the EMA # :'Signalperiods' - number of periods used to calculate the signal line # GetParam_d(sParamName) -> float # sParamName :'n/a' - not applicable # GetValue_i(sValueName,ePUnits,nBoFset) -> int # sValueName :'BoS' - Buy(1) or Sell(-1) signal # 'BoSage' - Buy(1) or Sell(-1) signal age in ePUnits # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # GetValue_d(sValueName,ePUnits,nBoFset) -> float # sValueName :'TRIX' - Calculated TRIX value # 'TRIXsignal' - Calculated TRIX signal line value # 'TRIXdiff' - TRIX/TRIXsignal difference value # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # # TSI DSeries class - True Strength Index # NOTES: TSI is a momentum-based oscillator that measures the rate of change # of the price over a specified period. It is used to identify potential # trend reversals and confirm price movements. The TSI is calculated by # taking the rate of change of the price over a specified period and # then applying a True Strength Index (TSI) to it. # : The TSI is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # NOTES: Refer CRoot->CView->CStackOHLCvs->ChartTSI.DSeriesFactory('TSI') # for DSeriesTSI object creation path. class DSeriesTSI(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise TSI data sets def Sync ( self ): self.iPC1periods: int = P2Series.GetParam_i ( self.hDSeries, "PC1periods" ) self.iPC2periods: int = P2Series.GetParam_i ( self.hDSeries, "PC2periods" ) self.iSignalperiods: int = P2Series.GetParam_i ( self.hDSeries, "Signalperiods" ) return # DSeries extensions # GetParam_i(sParamName) -> int # sParamName :'PC1periods' - Number of periods used to calculate the first price change # :'PC2periods' - Number of periods used to calculate the second price change # :'Signalperiods' - number of periods used to calculate the signal line # GetParam_d(sParamName) -> float # sParamName :'n/a' - not applicable # GetValue_i(sValueName,ePUnits,nBoFset) -> int # sValueName :'BoS' - Buy(1) or Sell(-1) signal # 'BoSage' - Buy(1) or Sell(-1) signal age in ePUnits # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # GetValue_d(sValueName,ePUnits,nBoFset) -> float # sValueName :'TSI' - Calculated TSI value # 'TSIsignal' - Calculated TSI signal line value # 'TSIdiff' - TSI/TSIsignal difference value # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # # ADX DSeries class - Average Directional Index # NOTES: ADX is a trend-following indicator that is used to identify the strength # of a trend in the market. It is calculated by taking the difference # between the price and the exponential moving average (EMA) of the price # over a specified period and then applying an Average Directional Index (ADX) # to it. # : Refer CRoot->CView->CStackOHLCvs->ChartATR.DSeriesFactory('ATR') # for DSeriesATR object creation path. class DSeriesADX(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise ADX data sets def Sync ( self ): self.iADXperiods: int = P2Series.GetParam_i ( self.hDSeries, "ADXperiods" ) return # # ATR DSeries class - Average True Range # NOTES: ATR is a volatility-based indicator that measures the average true range # of the price over a specified period. It is used to identify potential # trend reversals and confirm price movements. The ATR is calculated by # taking the average true range of the price over a specified period and # then applying an Average True Range (ATR) to it. # : The ATR is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : The ATR is calculated by taking the average true range of the price # over a specified period and then applying an Average True Range (ATR) # to it. The ATR is a variation of the Moving Average Convergence Divergence # : Refer CRoot->CView->CStackOHLCvs->ChartATR.DSeriesFactory('ATR') # for DSeriesATR object creation path. class DSeriesATR(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise ATR data sets def Sync ( self ): self.iATRperiods: int = P2Series.GetParam_i ( self.hDSeries, "ATRperiods" ) return # # Aroon DSeries class # NOTES: Aroon is a trend-following indicator that is used to identify potential # trend reversals and confirm price movements. It is calculated by taking # the difference between the price and the exponential moving average (EMA) # of the price over a specified period and then applying an Aroon (Aroon) # to it. # : The Aroon is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartAroon.DSeriesFactory('Aroon') # for DSeriesAroon object creation path. class DSeriesAroon(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise Aroon data sets def Sync ( self ): self.iAroonperiods: int = P2Series.GetParam_i ( self.hDSeries, "Aroonperiods" ) return # DSeries extensions # GetParam_i(sParamName) -> int: # sParamName :'Aroonperiods' - Number of periods used to calculate the Aroon # GetParam_d(sParamName) -> float: # sParamName :'n/a' - not applicable # GetValue_i(sValueName,ePUnits,nBoFset) -> int: # sValueName :'BoS' - Buy(1) or Sell(-1) signal # 'BoSage' - Buy(1) or Sell(-1) signal age in ePUnits # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # GetValue_d(sValueName,ePUnits,nBoFset) -> float # sValueName :'AroonHi' - Aroon High value # :'AroonLo' - Aroon Low value # :'AroonDiff' - Aroon Difference value # ePUnits : PUNITS_Day, PUNITS_Week, PUNITS_Month etc # nBOFset : Bar offset(in ePUnits) from the current DSeries cursor position # # Reversal DSeries class - Reversal Patterns, OHLCvs Chart overlay # NOTES: Reversal Patterns are a set of technical indicators that are used to # identify potential trend reversals and confirm price movements. They # are based on the concept of price action and are used to identify # potential trend reversals by looking for specific patterns in the price # action. # : The Reversal Patterns are used to identify potential trend reversals # and confirm price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartOHLCvs.DSeriesFactory('Reversal') # for DSeriesReversal object creation path. # : Based on internal Chartboard Reversal Patterns. Not a complete # list, only those that are supported by Chartboard # : Allocated types have an internal Chartboard dependancy RPType_BULL_NONE = 0 RPType_BULL_Enable = (1<<0) RPType_BULL_ENGULFING = (1<<1) RPType_BULL_HAMMER = (1<<2) RPType_BULL_PIERCING = (1<<3) RPType_BULL_MORNING_STAR = (1<<4) RPType_BULL_3WHITE_SOLDIERS = (1<<5) RPType_BULL_WHITE_MARUBOZU = (1<<6) RPType_BULL_3INSIDE_UP = (1<<7) RPType_BULL_HARAMI = (1<<8) RPType_BULL_ABANDONED_BABY = (1<<9) RPType_BULL_INVERTED_HAMMER = (1<<10) RPType_BULL_3OUTSIDE_UP = (1<<11) RPType_BULL_MATCHING_LOW = (1<<12) RPType_BULL_DELIBERATION = (1<<13) RPType_BULL_TRISTAR = (1<<14) RPType_BULL_SQUEEZE_ALERT = (1<<15) RPType_BULL_3GAPDOWN = (1<<16) RPType_BULL_HOMING_PIGEON = (1<<17) RPMask_BULLs_NONE = 0 RPMask_BULLs = (RPType_BULL_Enable|RPType_BULL_ENGULFING|RPType_BULL_HAMMER |RPType_BULL_PIERCING|RPType_BULL_MORNING_STAR|RPType_BULL_3WHITE_SOLDIERS |RPType_BULL_WHITE_MARUBOZU|RPType_BULL_3INSIDE_UP|RPType_BULL_HARAMI |RPType_BULL_ABANDONED_BABY|RPType_BULL_INVERTED_HAMMER|RPType_BULL_3OUTSIDE_UP |RPType_BULL_MATCHING_LOW|RPType_BULL_DELIBERATION|RPType_BULL_TRISTAR |RPType_BULL_SQUEEZE_ALERT|RPType_BULL_3GAPDOWN|RPType_BULL_HOMING_PIGEON) RPType_BEAR_NONE = 0 RPType_BEAR_Enable = (1<<0) RPType_BEAR_ENGULFING = (1<<1) RPType_BEAR_HANGING_MAN = (1<<2) RPType_BEAR_DARK_CLOUD_COVER = (1<<3) RPType_BEAR_EVENING_STAR = (1<<4) RPType_BEAR_3BLACK_CROWS = (1<<5) RPType_BEAR_BLACK_MARUBOZU = (1<<6) RPType_BEAR_3INSIDE_DOWN = (1<<7) RPType_BEAR_HARAMI = (1<<8) RPType_BEAR_SHOOTING_STAR = (1<<9) RPType_BEAR_ABANDONED_BABY = (1<<10) RPType_BEAR_3OUTSIDE_DOWN = (1<<11) RPType_BEAR_MATCHING_HIGH = (1<<12) RPType_BEAR_DELIBERATION = (1<<13) RPType_BEAR_TRISTAR = (1<<14) RPType_BEAR_SQUEEZE_ALERT = (1<<15) RPType_BEAR_3GAPUP = (1<<16) RPType_BEAR_DESCENDING_HAWK = (1<<17) RPMask_BEARs_NONE = 0 RPMask_BEARs = (RPType_BEAR_Enable|RPType_BEAR_ENGULFING|RPType_BEAR_HANGING_MAN |RPType_BEAR_DARK_CLOUD_COVER|RPType_BEAR_EVENING_STAR|RPType_BEAR_3BLACK_CROWS |RPType_BEAR_BLACK_MARUBOZU|RPType_BEAR_3INSIDE_DOWN|RPType_BEAR_HARAMI |RPType_BEAR_SHOOTING_STAR|RPType_BEAR_ABANDONED_BABY|RPType_BEAR_3OUTSIDE_DOWN |RPType_BEAR_MATCHING_HIGH|RPType_BEAR_DELIBERATION|RPType_BEAR_TRISTAR |RPType_BEAR_SQUEEZE_ALERT|RPType_BEAR_3GAPUP|RPType_BEAR_DESCENDING_HAWK) class DSeriesReversals(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise Reversals data parameters def Sync ( self ): return # Use DSeriesob.IsNull() method to check for validity def ReversalobFactory(self,ePUnits,hRefob,sObjectVerb): hDSeriesob = DSeries.GetObject(self,'Reversals',ePUnits,hRefob,sObjectVerb) return DSeriesobReversal(hDSeriesob,hRefob,sObjectVerb) # # Harmonics DSeries class - Harmonics Patterns, ChartOHLCvs overlay # NOTES: Refer CRoot->CView->CStackOHLCvs->ChartOHLCvs.DSeriesFactory('Harmonics') # for DSeriesHarmonics object creation path. # : Based on internal Chartboard Harmonics Patterns. Not a complete # list, only those that are supported by Chartboard # : Allocated types have an internal Chartboard dependancy HPType_BULL_NONE: int = 0 HPType_BULL_Enable: int = (1<<0) HPType_BULL_GARTLEY: int = (1<<1) HPType_BULL_BUTTERFLY: int = (1<<2) HPType_BULL_BAT: int = (1<<3) HPType_BULL_CRAB: int = (1<<4) HPType_BULL_SHARK: int = (1<<5) HPType_BULL_CYPHER = (1<<6) HPType_BULL_ABeCD: int = (1<<7) HPType_BULL_PATTERN50: int = (1<<8) HPType_BULL_HaS: int = (1<<9) HPMask_BULLs_NONE: int = 0 HPMask_BULLs: int = (HPType_BULL_Enable |HPType_BULL_GARTLEY|HPType_BULL_BUTTERFLY|HPType_BULL_BAT |HPType_BULL_CRAB|HPType_BULL_SHARK|HPType_BULL_CYPHER |HPType_BULL_ABeCD|HPType_BULL_ABeCD|HPType_BULL_PATTERN50 |HPType_BULL_HaS) HPType_BEAR_NONE: int = 0 HPType_BEAR_Enable: int = (1<<0) HPType_BEAR_GARTLEY: int = (1<<1) HPType_BEAR_BUTTERFLY: int = (1<<2) HPType_BEAR_BAT: int = (1<<3) HPType_BEAR_CRAB: int = (1<<4) HPType_BEAR_SHARK: int = (1<<5) HPType_BEAR_CYPHER: int = (1<<6) HPType_BEAR_ABeCD: int = (1<<7) HPType_BEAR_PATTERN50: int = (1<<8) HPType_BEAR_HaS: int = (1<<9) HPMask_BEARs_NONE: int = 0 HPMask_BEARs: int = (HPType_BEAR_Enable |HPType_BEAR_GARTLEY|HPType_BEAR_BUTTERFLY|HPType_BEAR_BAT |HPType_BEAR_CRAB|HPType_BEAR_SHARK|HPType_BEAR_CYPHER |HPType_BEAR_ABeCD|HPType_BEAR_ABeCD|HPType_BEAR_PATTERN50 |HPType_BEAR_HaS) class DSeriesHarmonics(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise Harmonics data parameters def Sync ( self ): self.iHPTypesMask: int = P2Series.GetParam_i ( self.hDSeries, "HPTypesMask" ) self.dZigZagXApc: float = P2Series.GetParam_d ( self.hDSeries, "ZigZagXApc" ) self.dBullishOSpc: float = P2Series.GetParam_d ( self.hDSeries, "BullishOSpc" ) self.dBearishOSpc: float = P2Series.GetParam_d ( self.hDSeries, "BearishOSpc" ) return # Use DSeriesob.IsNull() method to check for validity def HarmonicobFactory(self,ePUnits,hRefob,sObjectVerb): hDSeriesob = DSeries.GetObject(self,'Harmonics',ePUnits,hRefob,sObjectVerb) return DSeriesobHarmonic(hDSeriesob,hRefob,sObjectVerb) # # VTX DSeries class - VORTEX indicator # NOTES: VTX is a trend-following indicator that is used to identify potential # trend reversals and confirm price movements. It is calculated by taking # the difference between the price and the exponential moving average (EMA) # of the price over a specified period and then applying a Vortex (VTX) # to it. # : The VTX is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : VTX is a trend-following indicator that is used to identify potential # trend reversals and confirm price movements. It is calculated by taking # the difference between the price and the exponential moving average (EMA) # of the price over a specified period and then applying a Vortex (VTX) # to it. # : Refer CRoot->CView->CStackOHLCvs->ChartVTX.DSeriesFactory('VTX') # for DSeriesVTX object creation path. class DSeriesVTX(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise VTX data sets def Sync ( self ): self.iVTXperiods: int = P2Series.GetParam_i ( self.hDSeries, "VTXperiods" ) return # # Volume DSeries class - Volume indicator # NOTES: Refer CRoot->CView->CStackOHLCvs->ChartVolume.DSeriesFactory('Volume') # for DSeriesVolume object creation path, or # : Refer CRoot->CView->CStackPFigure->ChartVolume.DSeriesFactory('Volume') # for DSeriesVolume object creation path. class DSeriesVolume(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise Volume data sets def Sync ( self ): return # # Williams DSeries class - Williams %R Momentum indicator # NOTES: Williams %R is a momentum-based oscillator that measures the speed and # change of price movements relative to the highest high and lowest low # over a specified period. It is used to identify overbought and oversold # conditions in the market. The Williams %R is calculated by taking the # difference between the highest high and the lowest low over a specified # period and then applying a Williams %R (WmR) to it. # : The Williams %R is used to identify potential trend reversals and confirm # price movements by providing a complete picture of the market. # : Refer CRoot->CView->CStackOHLCvs->ChartZigZag.DSeriesFactory('WmR') # for DSeriesWmR object creation path. class DSeriesWmR(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise WmR data sets def Sync ( self ): self.iWmRperiods: int = P2Series.GetParam_i ( self.hDSeries, 'WmRperiods' ) return # # ZigZag DSeries class - High and Low limits overlay # NOTES: Refer CRoot->CView->CStackOHLCvs->ChartZigZag.DSeriesFactory('ZigZag') # for DSeriesZigZag object creation path. class DSeriesZigZag(DSeries): def __init__ ( self, hChart, sDSeriesName ): super().__init__ ( hChart, sDSeriesName ) self.Sync() # Synchronise ZigZag parameters def Sync ( self ): self.dPercent: float = P2Series.GetParam_d(self.hDSeries,'Percent') return #################### # Chart base class # NOTES: Multiple charts may exist in a chart stack # : Usually generated via CStack.ChartFactory() # : Base class and derivatives usable from both Advisor and Scanner # environnments. class Chart: def __init__ ( self, hCStack, sChartName ): self.hCStack = hCStack self.sChartName: str = sChartName self.hChart = P2Stack.ChartOpen(hCStack,sChartName) self.nPaintEoD: int = P2Chart.Getenvar_i(self.hChart,'PaintEoD') # Check if nominated Chart exists with stack def DSeriesExists(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) == 'exists': return True else: return False def PaintEoD(self,bPaintEoD): self.nPaintEoD: int = P2Chart.Setenvar_i(self.hChart,'PaintEoD',bPaintEoD) # Manage period shade bars (vertical shaded bars of period width) # NOTES: Direct access to internal DSeriesCTA shade bar. # : Charts within a CStack are automatically assigned a single # DSeriesCTA def PYCB_ShadeBarUpdate(self,ePUnits,nBoFset,eSBType,iState): return P2Chart.PYCB_ShadeBarUpdate(self.hChart,ePUnits,nBoFset,eSBType,iState) def PYCB_ShadeBarSelect(self,ePUnits,nBoFset,eSBType): return P2Chart.PYCB_ShadeBarSelect(self.hChart,ePUnits,nBoFset,eSBType) # Create DSeries instances and Prerequisites def Prerequisites(self,sDSeriesType): return P2Chart.Prerequisites(self.hChart,sDSeriesType) return None # # ADX Chart class - Average Directional Index # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('ADX') for ChartADX object creation path class ChartADX(Chart): def __init__(self, hCStack, sChartName): super().__init__(hCStack, sChartName) ## Create DSeries instances supported by ADX def DSeriesFactory(self, sDSeriesName): if P2Chart.DSeriesExists(self.hChart, sDSeriesName) != 'exists': raise ValueError(f"DSeries: {sDSeriesName} does not exist within Chart: {self.sChartName}") if P2Chart.DSeriesType(self.hChart, sDSeriesName) == 'ADX': return DSeriesADX(self.hChart, sDSeriesName) raise TypeError(f"DSeries: {sDSeriesName} not supported by Chart: {self.sChartName}") ## Synchronise ADX environment with Chartboard container def Sync(self): pass # ATR Chart class - Average True Range # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('ATR') for ChartATR object creation path class ChartATR(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'ATR': return DSeriesATR(self.hChart,sDSeriesName) raise TypeError(f"DSeries: {sDSeriesName} not supported by Chart: {self.sChartName}") # Synchronise ATR data sets def Sync ( self ): return # # Aroon Chart class - Aroon Indicator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('Aroon') for ChartAroon object creation path class ChartAroon(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Aroon': return DSeriesAroon(self.hChart,sDSeriesName) raise TypeError(f"DSeries: {sDSeriesName} not supported by Chart: {self.sChartName}") # Synchronise Aroon data sets def Sync ( self ): return # # CCI Chart class - Commodity Channel Index # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('CCI') for ChartCCI object creation path class ChartCCI(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'CCI': return DSeriesCCI(self.hChart,sDSeriesName) raise TypeError(f"DSeries: {sDSeriesName} not supported by Chart: {self.sChartName}") # Synchronise CCI data sets def Sync ( self ): return # # Chaikin Chart class - Chaikin Oscillator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('Chaikin') for ChartChaikin object creation path class ChartChaikin(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Chaikin': return DSeriesChaikin(self.hChart,sDSeriesName) raise TypeError(f"DSeries: {sDSeriesName} not supported by Chart: {self.sChartName}") # Synchronise Chaikin data sets def Sync ( self ): return # # CMF Chart class - Chaikin Money Flow # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('CMF') for ChartCMF object creation path class ChartCMF(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'CMF': return DSeriesCMF(self.hChart,sDSeriesName) raise TypeError(f"DSeries: {sDSeriesName} not supported by Chart: {self.sChartName}") # Synchronise CMF data sets def Sync ( self ): return # # Coppock Chart class - Coppock Indicator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('Coppock') for ChartCoppock object creation path class ChartCoppock(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Coppock': return DSeriesCoppock(self.hChart,sDSeriesName) raise TypeError(f"DSeries: {sDSeriesName} not supported by Chart: {self.sChartName}") # Synchronise Coppock data sets def Sync ( self ): return # # EFI Chart class - Elder Ray or Force Index # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('EFI') for ChartEFI object creation path class ChartEFI(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'EFI': return DSeriesEFI(self.hChart,sDSeriesName) raise TypeError(f"DSeries: {sDSeriesName} not supported by Chart: {self.sChartName}") # Synchronise EFI data sets def Sync ( self ): return # # EhlerFT Chart class - Ehlers Fisher Transform (EhlerFT) # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('EhlerFT') for ChartEhlerFT object creation path class ChartEhlerFT(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'EhlerFT': return DSeriesEhlerFT(self.hChart,sDSeriesName) print('DSeries: ' + sDSeriesName + ' not supported by Chart: ' + self.sChartName ) return None # Synchronise EhlerFT data sets def Sync ( self ): return # # DPO Chart class - Detrended Price Oscillator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('DPO') for ChartDPO object creation path class ChartDPO(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'DPO': return DSeriesDPO(self.hChart,sDSeriesName) print('DSeries: ' + sDSeriesName + ' not supported by Chart: ' + self.sChartName ) return None # Synchronise DPO data sets def Sync ( self ): return # # OHLCvs Chart class - Open High Low Close volume, shorts # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('OHLCvs') for ChartOHLCvs object creation path class ChartOHLCvs(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : print ('DSeries: ' + sDSeriesName + ' does not exist within Chart: ' + self.sChartName) return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'OHLCvs': return DSeriesOHLCvs(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'OHLC': return DSeriesOHLCvs(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'BB': return DSeriesBB(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'KAMA': return DSeriesKAMA(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'MAMA': return DSeriesMAMA(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Reversals': return DSeriesReversals(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'SAR': return DSeriesSAR(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Keltner': return DSeriesKeltner(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Ichimoku': return DSeriesIchimoku(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Donchian': return DSeriesDonchian(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Coppock': return DSeriesCoppock(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'SMAnnn': return DSeriesSMAnnn(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'EMAnnn': return DSeriesEMAnnn(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Harmonics': return DSeriesHarmonics(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Chandelier': return DSeriesChandelier(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'TDMAI-A': return DSeriesTDMA(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'TDMAI-B': return DSeriesTDMA(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'TDMAI-C': return DSeriesTDMA(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'TDemark': return DSeriesTDemark(self.hChart,sDSeriesName) if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'ZigZag': return DSeriesZigZag(self.hChart,sDSeriesName) print( 'DSeries: ' + sDSeriesName + ' not supported by Chart: ' + self.sChartName ) return None def DSeriesSMAnnnFactory(self,nSMAperiods,ePUnits): sDSeriesSMAname = MakeDSeriesSMAname(nSMAperiods,ePUnits) P2Chart.Prerequisites ( self.hChart, sDSeriesSMAname ) if P2Chart.DSeriesExists(self.hChart,sDSeriesSMAname) != 'exists' : print ('DSeries: ' + sDSeriesSMAname + ' does not exist within Chart: ' + self.sChartName) return None return DSeriesSMAnnn(self.hChart,sDSeriesSMAname) def DSeriesEMAnnnFactory(self,nEMAperiods,ePUnits): sDSeriesEMAname = MakeDSeriesEMAname(nEMAperiods,ePUnits) P2Chart.Prerequisites ( self.hChart, sDSeriesEMAname ) if P2Chart.DSeriesExists(self.hChart,sDSeriesEMAname) != 'exists' : print ('DSeries: ' + sDSeriesEMAname + ' does not exist within Chart: ' + self.sChartName) return None return DSeriesEMAnnn(self.hChart,sDSeriesEMAname) # Synchronise OHLCvs data sets def Sync ( self ): return # # PFigure Chart class - Point and Figure chart # NOTES: Refer CRoot->CView->CStackPFigure.ChartFactory('PFigure') for ChartPFigure object creation path class ChartPFigure(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : print ('DSeries: ' + sDSeriesName + ' does not exist within Chart: ' + self.sChartName) return None print( 'DSeries: ' + sDSeriesName + ' not supported by Chart: ' + self.sChartName ) return None # Synchronise PFigure data sets def Sync ( self ): return # # KST Chart class - Pring's Know Sure Thing # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('KST') for ChartKST object creation path class ChartKST(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : print('DSeriesKST does not exist') print('DSeries: ' + sDSeriesName + ' does not exist within Chart: ' + self.sChartName) return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'KST': return DSeriesKST(self.hChart,sDSeriesName) print('ChartKST failure') print ('DSeries: '+sDSeriesName+' not supported by Chart: '+self.sChartName) return None # Synchronise KST data sets def Sync ( self ): return # # MACD Chart class - Moving Average Convergence Divergence # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('MACD') for ChartMACD object creation path class ChartMACD(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : print('DSeriesMACD does not exist') print('DSeries: ' + sDSeriesName + ' does not exist within Chart: ' + self.sChartName) return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'MACD': return DSeriesMACD(self.hChart,sDSeriesName) print('ChartMACD failure') print ('DSeries: '+sDSeriesName+' not supported by Chart: '+self.sChartName) return None # Synchronise MACD data sets def Sync ( self ): return # # MFI Chart class - Money Flow Index # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('MFI') for ChartMFI object creation path class ChartMFI(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'MFI': return DSeriesMFI(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise MFI data sets def Sync ( self ): return # # MSA Chart class - Momentum Structural Analysis # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('MSA') for ChartMSA object creation path class ChartMSA(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : print('DSeriesMSA does not exist') print('DSeries: ' + sDSeriesName + ' does not exist within Chart: ' + self.sChartName) return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'MSA': return DSeriesMSA(self.hChart,sDSeriesName) print('ChartMSA failure') print ('DSeries: '+sDSeriesName+' not supported by Chart: '+self.sChartName) return None # Synchronise MSA data sets def Sync ( self ): return # # OBV Chart class - On Balance Volume # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('OBV') for ChartOBV object creation path class ChartOBV(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'OBV': return DSeriesOBV(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise OBV data sets def Sync ( self ): return # # PBars Chart class - Price Variation Bars # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('PBars') for ChartPBars object creation path class ChartPBars(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'PBars': return DSeriesPBars(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise PBars data sets def Sync ( self ): return # # PMO Chart class - Price Momentum Oscillator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('PMO') for ChartPMO object creation path class ChartPMO(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'PMO': return DSeriesPMO(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise PMO data sets def Sync ( self ): return # # PPO Chart class - Percentage Price Oscillator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('PPO') for ChartPPO object creation path # : MACD equivalent but uses Percentage Price Oscillator class ChartPPO(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'PPO': return DSeriesPPO(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise PPO data sets def Sync ( self ): return # # PVO Chart class - Price Volume Oscillator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('PVO') for ChartPVO object creation path class ChartPVO(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'PVO': return DSeriesPVO(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise PVO data sets def Sync ( self ): return # # ROC Chart class - Rate of Change # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('ROC') for ChartROC object creation path class ChartROC(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'ROC': return DSeriesROC(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise ROC data sets def Sync ( self ): return # # RSI Chart class - Relative Strength Index # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('RSI') for ChartRSI object creation path class ChartRSI(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'RSI': return DSeriesRSI(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise RSI data sets def Sync ( self ): return # # SLOPE Chart class - SLOPE indicator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('SLOPE') for ChartSLOPE object creation path class ChartSLOPE(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'SLOPE': return DSeriesSLOPE(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise SLOPE data sets def Sync ( self ): return # # StochRSI Chart class - Stochastic Relative Strength Index # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('StochRSI') for ChartStochRSI object creation path class ChartStochRSI(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'StochRSI': return DSeriesStochRSI(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise StochRSI data sets def Sync ( self ): return # # STO Chart class - Stochastic Oscillator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('STO') for ChartSTO object creation path class ChartSTO(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'STO': return DSeriesSTO(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise STO data sets def Sync ( self ): return # # STDEV Chart class - Standard Deviation # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('STDEV') for ChartSTDEV object creation path class ChartSTDEV(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'STDEV': return DSeriesSTDEV(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise STDEV data sets def Sync ( self ): return # # Shorts Chart class - Shorts Indicator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('Shorts') for ChartShorts # object creation path, or # : Refer CRoot->CView->CStackPFigure.ChartFactory('Shorts') for ChartShorts # object creation path class ChartShorts(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Shorts': return DSeriesShorts(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise Shorts data sets def Sync ( self ): return # # TRIX Chart class - Triple Exponential Moving Average # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('TRIX') for ChartTRIX object creation path class ChartTRIX(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'TRIX': return DSeriesTRIX(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise TRIX data sets def Sync ( self ): return # # TSI Chart class - True Strength Index # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('TSI') for ChartTSI object creation path class ChartTSI(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'TSI': return DSeriesTSI(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise TSI data sets def Sync ( self ): return # # VTX Chart class - VORTEX Indicator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('VTX') for ChartVTX object creation path class ChartVTX(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'VTX': return DSeriesVTX(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise VTX data sets def Sync ( self ): return # # Volume Chart class - Volume Indicator # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('Volume') for ChartVolume # object creation path # : Refer CRoot->CView->CStackPFigure.ChartFactory('Volume') for ChartVolume # object creation path class ChartVolume(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'Volume': return DSeriesVolume(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise Volume data sets def Sync ( self ): return # # WmR Chart class - Williams %R # NOTES: Refer CRoot->CView->CStackOHLCvs.ChartFactory('WmR') for ChartWmR object creation path class ChartWmR(Chart): def __init__ ( self, hCStack, sChartName ): super().__init__ ( hCStack, sChartName ) def DSeriesFactory(self,sDSeriesName): if P2Chart.DSeriesExists(self.hChart,sDSeriesName) != 'exists' : assert 0, "DSeries: " + sDSeriesName + " does not exist within Chart: " + self.sChartName return None if P2Chart.DSeriesType(self.hChart,sDSeriesName) == 'WmR': return DSeriesWmR(self.hChart,sDSeriesName) assert 0, "DSeries: " + sDSeriesName + " not supported by Chart: " + self.sChartName return None # Synchronise WmR data sets def Sync ( self ): return #################### # CStack base class # NOTES: Adjusts according to referenced View tab type # : Reference view tab under which script activated as 'this' # : Base class and derivatives usable from both Advisor chart stack # environments environnments only. Otherwise run-time error generated # : Allocated types have an internal Chartboard dependancy SBTYPE_Bullish: int = 0 # Bullish shade bar type SBTYPE_OBought: int = 1 # Over bought SBTYPE_Sell: int = 2 # Sell SBTYPE_Bearish: int = 3 # Bearish SBTYPE_OSold: int = 4 # Over sold SBTYPE_Buy: int = 5 # Buy class CStack: def __init__(self,hCView): self.hCView = hCView # Parent CView reference handle self.hCStack = P2View.OpenCStack(hCView) # Reference handle for this CStack self.sStackType: str = P2Stack.StackType(self.hCStack) # OHLCvs or PFigure self.sPUnits: str = P2Stack.Getenvar_s(self.hCStack,'PUnits') # YEAR=1, QUARTER=2, MONTH=3, WEEK=4, DAY=5 self.nPUnits: int = P2Stack.Getenvar_i(self.hCStack,'PUnits') self.nPaintEoD: int = P2Stack.Getenvar_i(self.hCStack,'PaintEoD') # self.sStockCode: str = P2Stack.StockCode(self.hCStack) # MSFT, TSLA, GDX, etc. # Synchronise CStack data sets def Sync ( self ): return # CStack operations def ChartExists(self,sChartname): return P2Stack.ChartSummary(self.hCStack,sChartname) == 'exists' def Rewind(self): return P2Stack.Rewind(self.hCStack) def Step(self,ePUnits,nBoFset): return P2Stack.Step(self.hCStack,ePUnits,nBoFset) # Shade bars def PYCB_ShadeBarUpdate(self,ePUnits,nBoFset,eSBType,iValue): return P2Stack.CA_Update(self.hCStack,ePUnits,nBoFset,eSBType,iValue) def PYCB_ShadeBarClear(self,ePUnits): P2Stack.PYCB_ShadeBarClear(self.hCStack,ePUnits) return def PYCB_ShadeBarMask(self,ePUnits,wMask): P2Stack.PYCB_ShadeBarMask(self.hCStack,ePUnits,wMask) return def isCategory(self,sStackType) -> bool: if CStack.sStackType == sStackType: return False return True def PaintEoD(self,bPaintEoD): self.nPaintEoD = P2Stack.Setenvar_i(self.hCStack,'PaintEoD',bPaintEoD) return # Create chart instances and Prerequisites def Prerequisites(self,sChartType): return P2Stack.Prerequisites(self.hCStack,Chart=sChartType) def ChartCreate(self,sChartype): if P2Stack.ChartSummary(self.hCStack,sChartName) != 'nochart' : assert 0, "Category: " + sChartName + " already exists within CStack" return None return P2Stack.ChartCreate(self.hCStack,sChartName) def CategoryFactory(self): if self.sStackType == 'OHLCvs': return CStackOHLCvs(self) if self.sStackType == 'OHLC': return CStackOHLCvs(self) if self.sStackType == 'PFigure' or self.sStackType == 'PFigure': return CStackPFigure(self) assert 0, "Category: " + type + " not supported by CStack (OHLCvs or PFigure)" # Properties def PeriodUnits(self): self.sPUnits: str = P2Stack.Getenvar_s(self.hCStack,'PUnits') self.nPUnits: int = P2Stack.Getenvar_i(self.hCStack,'PUnits') return self.sPUnits; # aka Stepping period # Sets the period units (1, 2, 3, 4, 5) for the CStack def SetPUnits(self,ePUnits) -> int: P2Stack.Setenvar_i(self.hCStack,'PUnits',ePUnits) self.sPUnits: str = P2Stack.Getenvar_s(self.hCStack,'PUnits') self.nPUnits: int = P2Stack.Getenvar_i(self.hCStack,'PUnits') return self.nPUnits; # Exposes contained primarly stock code def StockCode(self) -> str: return self.sStockCode def DATE(self): return P2Stack.DATE(self.hCStack); # Checks for CStackOHLCvs type def IsOHLCvs(self): return self.sStackType == 'OHLCvs' # Checks for PFigure CStack type def IsPFigure(self): return self.sStackType == 'PFigure' # Workspace environment related variables # NOTES: Used to interact with the workspace at an environmental, # visual or summary level independant of DSeries calculations etc def Getenvar_i(self,sEnvarname) -> int: return P2Stack.Getenvar_i(self.hCStack,sEnvarname) def Getenvar_d(self,sEnvarname) -> float: return P2Stack.Getenvar_d(self.hCStack,sEnvarname) def Getenvar_dt(self,sEnvarname) -> datetime: return P2Stack.Getenvar_dt(self.hCStack,sEnvarname) # Environment settings def Setenvar_i(self,sEnvarname,iEnvar): P2Stack.Setenvar_i(self.hCStack,sEnvarname,iEnvar) # # CStackOHLCvs class (Open-High-Low-Close type chart stack) # NOTES: Must be supported by referenced environment class CStackOHLCvs(CStack): def __init__ (self,hCView): super().__init__(hCView) self.Sync() # Synchronise CStackOHLCvs environment # CStack.Getenvar_dt(sEnvarName) # 'ModelBegin' - Start date for modelling # 'ModelEnd' - End date for modelling def Sync ( self ): self.dtModelBegin: datetime = CStack.Getenvar_dt(self,'ModelBegin') self.dtModelEnd: datetime = CStack.Getenvar_dt(self,'ModelEnd') self.nModelBegin: float = CStack.Getenvar_d(self, 'ModelBegin') self.nModelEnd: float = CStack.Getenvar_d(self, 'ModelEnd') self.bModelLimitsEoD: int = CStack.Getenvar_i(self,'ModelLimitsEoD') return # Chart operations def ChartSummary(self,sChartName): return CStack.ChartExists(self,sChartName) # Generate chart instances def ChartFactory(self,sChartName): if P2Stack.ChartSummary(self.hCStack,sChartName) != 'exists' : print('Chart: ' + sChartName + ' does not exist within CStackOHLCvs') return None if P2Stack.ChartType(self.hCStack,sChartName) == 'OHLCvs': print('ChartFactory: Create ChartOHLCvs') return ChartOHLCvs(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'OHLC': print('ChartFactory: Create ChartOHLC') return ChartOHLCvs(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'CCI': return ChartCCI(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'Chaikin': return ChartChaikin(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'CMF': return ChartCMF(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'Coppock': return ChartCoppock(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'EhlerFT': return ChartEhlerFT(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'EFI': return ChartEFI(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'DPO': return ChartDPO(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'KST': return ChartKST(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'MACD': return ChartMACD(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'MFI': return ChartMFI(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'MSA': return ChartMSA(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'OBV': return ChartOBV(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'PBars': return ChartPBars(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'PMO': return ChartPMO(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'PPO': return ChartPPO(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'PVO': return ChartPVO(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'ROC': return ChartROC(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'RSI': return ChartRSI(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'SLOPE': return ChartSLOPE(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'StochRSI': return ChartStochRSI(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'STDEV': return ChartSTDEV(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'STO': return ChartSTO(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'Shorts': return ChartShorts(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'TRIX': return ChartTRIX(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'ADX': return ChartADX(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'ATR': return ChartATR(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'Aroon': return ChartAroon(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'TSI': return ChartTSI(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'Volume': return ChartVolume(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'VTX': return ChartVTX(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'WmR': return ChartWmR(self.hCStack,sChartName) print('Chart: ' + sChartName + ' not supported by CStackOHLCvs') return None # Generate modelling instance # NOTES: Requires an existing Modelling Attachment to act as results repository # : Logically models MUST be run against a chart stack def ModelFactory(self,sAttachmentName): if P2Model.AttachmentSummary(sAttachmentName) != 'exists' : print('Modelling Attachment: ' + sAttachmentName + ' does not exist within workspace') return None print ( 'ModelFactory oCStack.sStockCode:' + self.sStockCode ) return Model(self,sAttachmentName) # # CStackPFigure class (Point and Figure chart stack category) # NOTES: Must be supported by referenced environment, concept under # development class CStackPFigure(CStack): def __init__(self): super().__init__() # Synchronise CStackPFigure data sets def Sync ( self ): return # Chart operations def ChartSummary(self,sChartName): return CStack.ChartExists(self,sChartName) # Generate chart instances def ChartFactory(self,sChartName): if P2Stack.ChartSummary(self.hCStack,sChartName) != 'exists' : print('Chart: ' + sChartName + ' does not exist within CStackPFigure (PFigure only)') return None if P2Stack.ChartType(self.hCStack,sChartName) == 'PFigure': return ChartPFigure(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'Shorts': return ChartShorts(self.hCStack,sChartName) if P2Stack.ChartType(self.hCStack,sChartName) == 'Volume': return ChartVolume(self.hCStack,sChartName) print('Chart: ' + sChartName + ' not supported by CStackPFigure (PFigure only)') return None #################### # CScanner base class # NOTES: Adjusts according to referenced View tab # : Reference view tab under which script activated as 'this' # : Base class and derivatives usable from both stock scanner # environments environnments only. Otherwise run-time error generated # : Allocated types have an internal Chartboard dependancy SBTYPE_Bullish = 0 # Bullish shade bar type SBTYPE_OBought = 1 # Over bought SBTYPE_Sell = 2 # Sell SBTYPE_Bearish = 3 # Bearish SBTYPE_OSold = 4 # Over sold SBTYPE_Buy = 5 # Buy class CScanner: def __init__(self,hCView): self.hCView = hCView # Parent CView reference handle self.hCScanner = P2View.OpenCScanner(hCView) # Reference handle for this CScanner self.sCScanType: str = P2Scanner.CScanType(self.hCScanner) # CScanOHLCvs or CScanPFigure self.sPUnits: str = P2Scanner.Getenvar_s(self.hCScanner,'PUnits') # YEAR=1, QUARTER=2, MONTH=3, WEEK=4, DAY=5 self.nPUnits: int = P2Scanner.Getenvar_i(self.hCScanner,'PUnits') self.nPaintEoD: int = P2Scanner.Getenvar_i(self.hCScanner,'PaintEoD') # self.sStockCode: str = P2Scanner.StockCode(self.hCScanner) self.dRefDATE: float = P2Scanner.Getenvar_d(self.hCScanner,'RefDATE'); self.dtRefDATE: datetime = P2Scanner.Getenvar_dt(self.hCScanner,'RefDATE'); self.nLBPeriods: int = P2Scanner.Getenvar_i(self.hCScanner,'LBPeriods') # Synchronise Scanner data sets def Sync ( self ): return # CScanner cursor operations def Rewind(self): return P2Scanner.Rewind(self.hCScanner) def FastForward(self): return P2Scanner.FastForward(self.hCScanner) def Step(self,ePUnits,nBoFset): return P2Scanner.Step(self.hCScanner,ePUnits,nBoFset) def SetCursorPos(self,nDATE,ePUnits) -> float: return P2Scanner.SetCursorPos(self.hCScanner,nDATE,ePUnits) def GetCursorPos(self,ePUnits) -> float: return P2Scanner.GetCursorPos(self.hCScanner) def GetDSetDATE(self,sDATEname,ePUnits) -> float: return P2Scanner.GetDSetDATE(self.hCScanner,sDATEname,ePUnits) # Create chart instances and Prerequisites def ChartExists(self,sChartname): return P2Scanner.ChartSummary(self.hCScanner,sChartname) == 'exists' def Prerequisites(self,sChartType): return P2Scanner.Prerequisites(self.hCScanner,Chart=sChartType) def isCategory(self,sCScannerType): if CScanner.sCScannerType == sCScannerType: return False return True def ChartCreate(self,sChartype): if P2Scanner.ChartSummary(self.hCScanner,sChartName) != 'nochart' : assert 0, "Chart: " + sChartName + " already exists within CStack" return None return P2Scanner.ChartCreate(self.hCScanner,sChartName) # Create descendant CStack and CScan instances def CStackFactory(self): print ( "CScanOHLCvs.CStackFactory Entry" ) if self.sCScanType == 'CScanOHLCvs': return CStackOHLCvs(self.hCScanner) if self.sCScanType == 'CScanPFigure': return CStackPFigure(self.hCScanner) assert 0, "CStackFactory: " + type + " not supported by CView (OHLCvs, PFigure)" # Results def SetSelected(self,bSelect): P2Scanner.ES_Selected(self.hCScanner,bSelect) return # Properties def Refresh(self): self.nPUnits: int = P2Scanner.Getenvar_i(self.hCScanner,'PUnits') self.sPUnits: str = P2Scanner.Getenvar_s(self.hCScanner,'PUnits') self.sStockCode: str = P2Scanner.StockCode(self.hCScanner) self.nLBPeriods: int = P2Scanner.Getenvar_i(self.hCScanner,'LBPeriods') return def PeriodUnits(self): return self.sPUnits; # aka Stepping period def StockCode(self) -> str: return self.sStockCode #def DATE(self): # return P2Scanner.DATE(self.hCScanner); def IsOHLCvs(self): if self.sCScannerType == 'OHLCvs': return 1 return 0 def IsPFigure(self): if self.sCScannerType == 'PFigure': return 1 return 0 # Environment settings def Setenvar_i(self,sEnvarname,iValue) -> int: P2Scanner.Setenvar_i(self.hCScanner,sEnvarname,iValue) self.Refresh() def Setenvar_s(self,sEnvarname,sValue) -> str: P2Scanner.Setenvar_s(self.hCScanner,sEnvarname,sValue) self.Refresh() def Getenvar_d(self,sEnvarname,sValue) -> float: P2Scanner.Getenvar_s(self.hCScanner,sEnvarname) def Getenvar_dt(self,sEnvarname,sValue) -> datetime: P2Scanner.Getenvar_dt(self.hCScanner,sEnvarname) # # CScanOHLCvs class (Open-High-Low-Close type chart scanner) # NOTES: Must be supported by referenced environment. Generates non # visual chart stacks and then exposes the calculated parameters # to your custom scanning algorithms class CScanOHLCvs(CScanner): def __init__ (self,hCView): super().__init__(hCView) # Synchronise CScanOHLCvs data sets def Sync ( self ): return # Chart operations def ChartSummary(self,sCScanname): return CScanner.ChartExists(self,sCScanname) # Generate chart instances def ChartFactory(self,sChartName): if P2Scanner.ChartSummary(self.hCScanner,sChartName) != 'exists' : print('Chart: ' + sChartName + ' does not exist within CScanOHLC') return None if P2Scanner.ChartType(self.hCScanner,sChartName) == 'OHLCvs': return ChartOHLCvs(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'OHLC': return ChartOHLCvs(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'CCI': return ChartCCI(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'Chaikin': return ChartChaikin(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'CMF': return ChartCMF(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'Coppock': return ChartCoppock(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'EhlerFT': return ChartEhlerFT(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'EFI': return ChartEFI(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'DPO': return ChartDPO(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'KST': return ChartKST(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'MACD': return ChartMACD(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'MFI': return ChartMFI(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'MSA': return ChartMSA(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'OBV': return ChartOBV(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'PBars': return ChartPBars(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'PMO': return ChartPMO(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'PPO': return ChartPPO(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'PVO': return ChartPVO(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'ROC': return ChartROC(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'RSI': return ChartRSI(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'SLOPE': return ChartSLOPE(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'StochRSI': return ChartStochRSI(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'STDEV': return ChartSTDEV(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'STO': return ChartSTO(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'Shorts': return ChartShorts(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'TRIX': return ChartTRIX(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'ADX': return ChartADX(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'ATR': return ChartATR(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'Aroon': return ChartAroon(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'TSI': return ChartTSI(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'Volume': return ChartVolume(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'VTX': return ChartVTX(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'WmR': return ChartWmR(self.hCScanner,sChartName) print('Chart: ' + sChartName + ' not supported by CScanOHLCvs') return None # # CScanPFigure class (Point and Figure chart scanner) # NOTES: Must be supported by referenced environment. Generates non # visual chart stacks and then exposes the calculated parameters # to your custom scanning algorithms # : Under development class CScanPFigure(CScanner): def __init__ (self,sCWndParent,sCScannername): super().__init__(sCWndParent,sCScannername) #def __init__ ( self,sCScanname ): # super().__init__(sCScanname) # Synchronise CSannerPFigure data sets def Sync ( self ): return # Chart operations def ChartSummary(self,sCScanname): return CScanner.ChartExists(self,sCScanname) # Generate chart instances def ChartFactory(self,sChartName): if P2Scanner.ChartSummary(self.hCScanner,sChartName) != 'exists' : print('Chart: ' + sChartName + ' does not exist within CScanPFigure') return None if P2Scanner.ChartType(self.hCScanner,sChartName) == 'PFigure': return ChartPFigure(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'Volume': return ChartVolume(self.hCScanner,sChartName) if P2Scanner.ChartType(self.hCScanner,sChartName) == 'Shorts': return ChartShorts(self.hCScanner,sChartName) print('Chart: ' + sChartName + ' not supported by CScanPFigure') return None #################### # CView base class # NOTES: Adjusts according to referenced View tab # : Reference view tab under which script activated as 'this' # : Base class and derivatives usable from all View Tab environments # : Allocated types have an internal Chartboard dependancy class CView: def __init__(self,sCViewname): #self.sCWndParent: str = sCWndParent self.sCViewname: str = sCViewname self.hCView = P2View.Open(sCViewname) self.sCViewType: str = P2View.TabbedViewType(self.hCView) #self.sPUnits: str = P2View.Getenvar_s(self.hCView,'PUnits') #self.nPUnits: int = P2View.Getenvar_i(self.hCView,'PUnits') #self.nPaintEoD: int = P2View.Getenvar_i(self.hCView,'PaintEoD') # Synchronise CView data sets def Sync ( self ): return # CView operations # Create descendant CStack and CScan instances def CStackFactory(self): print ( "CView.CStackFactory Entry" ) if self.sCViewType == 'OHLCvs': oCStackOHLCvs = CStackOHLCvs(self.hCView) return oCStackOHLCvs if self.sCViewType == 'PFigure': return CStackPFigure('CView','this') assert 0, "CStackFactory: " + type + " not supported by CView (OHLCvs, PFigure)" def CScanFactory(self): print ( "CView.CScanFactory Entry" ) if self.sCViewType == 'CScanOHLCvs': oCScanOHLCvs = CScanOHLCvs(self.hCView) return oCScanOHLCvs if self.sCViewType == 'CScanPFigure': return CScanPFigure(self.hCView) assert 0, "CScanFactory: " + type + " not supported by CView (ScamOHLCvs, ScanPFigure)" # Properties def PaintEoD(self,bPaintEoD): self.nPaintEoD = P2View.Setenvar_i(self.hCView,'PaintEoD',bPaintEoD) def PUnits(self): self.sPUnits: str = P2View.Getenvar_s(self.hCView,'PUnits') self.nPUnits: int = P2View.Getenvar_i(self.hCView,'PUnits') return self.sPUnits; # aka Stepping period def SetPUnits(self,ePUnits) -> int: P2View.Setenvar_i(self.hCView,'PUnits',ePUnits) self.sPUnits: str = P2View.Getenvar_s(self.hCView,'PUnits') self.nPUnits: int = P2View.Getenvar_i(self.hCView,'PUnits') return self.nPUnits; def IsCViewOHLCvs(self): if self.sCViewType == 'OHLCvs': return 1 return 0 def IsCViewPFigure(self): if self.sCViewType == 'PFigure': return 1 return 0 def IsCScanOHLCvs(self): if self.sCViewType == 'CScanOHLCvs': return 1 return 0 def IsCScanPFigure(self): if self.sCViewType == 'CScanPFigure': return 1 return 0 #################### # CRoot base class # NOTES: Parent of all subsequent CBEC-CView descendants (Stack, CScanner) # : Valid in both Chart Stack and Stock Scanning environments # : Base class and derivatives usable from both Advisor and # Scanner environnments. class CRoot: def __init__(self): print ( 'CRoot.__init__ doneas' ) self.Sync() # Synchronise Root data parameters def Sync ( self ): self.sVersionCBEC: str = '3.2.04' # Version of PythonCBEC.pyw self.sVersion: str = P2Root.Getenvar_s('Version') # Version of Chartboard self.nBuildCBEC: int = 3204 # Build of PythonCBEC.pyw self.nBuild: int = P2Root.Getenvar_i('Build') # Build of Chartboard return # CView Factory - Create instance from existing view tabs # NOTES: Exclusively used on existing visual tab Views # : Use 'This' to reference CView from which script has been run # : Subsequently the return CView can be used to retrieve properties # and generate specific type instance def CViewFactory(self,sCViewname): return CView ( sCViewname ) #sCViewType = CRoot.CWndType(self,'CViewTabs',sCViewname) #if sCViewType == 'CViewOHLCvs': # return CView('CViewTabs',sCViewname) #if sCViewType == 'CViewPFigure': # return CView('CViewTabs',sCViewname) #if sCViewType == 'CViewScanner': # return CView('CViewTabs',sCViewname) #raise TypeError(f"CViewTabs." + sCViewname + " not supported CView[OHLCvs|PFigure|Scanner]") # CStack Factories - Create Chart Stack for designated category # NOTES: Exclusively used on existing visual chart stacks # : Use 'This' to reference CStack from which script has been run #def CStackFactory(self,sCWndParent,sCStackname): # sStackType = CRoot.CWndType(self,sCWndParent,sCStackname) # hCStack = P2Stack.Open(sCWndParent,sCStackname) # if sStackType == 'CStackOHLCvs': # return CStackOHLC(sCWndParent,sCStackname) # if sStackType == 'CStackPFigure': # return CStackPFigure(sCWndParent,sCStackname) # assert 0, "CStack type: " + sStackType + " not supported CStack[OHLCvs|PFigure]" # CScanner Factories - Create scanner for destignated category # NOTES: Exclusively used for scanning through non-visual datasets # : Use 'This' to reference CScanner from which script has been run def CScannerFactory(self,sCWndParent,sCScannername): sScannerType = CRoot.CWndType(self,sCWndParent,sCScannername) #hCScanner = P2Scanner.Open(sCWndParent,sCScannername) if sScannerType == 'CScanOHLCvs': return CScanOHLCvs(sCWndParent,sCScannername) if sScannerType == 'CScanPFigure': return CScanPFigure(sCWndParent,sCScannername) assert 0, "CScanner type: " + sScannerType + " not supported CScanner[OHLCvs|PFigure]" # Properties def Instance(): return P2Root.Instance() # Instance or pass number def CWndType(self,sCWndParent,sCWndChild): return P2Root.CWndType(sCWndParent,sCWndChild) #################### # Draw base class class Draw: def __init__ ( self, oDrawChart, oDrawDSeries ): self.oChart = oDrawChart self.oDSeries = oDrawDSeries # Synchronise Draw data sets def Sync ( self ): return # Check if nominated Chart exists with stack def Exists ( self ): if P2Chart.DSeries(self.oChart.sChartName) == 'exists': return 1 else: return 0 # # Draw chart tag class DrawTag(Draw): def __init__ ( self, oDrawChart, oDrawDSeries ): super().__init__ ( oDrawChart, oDrawDSeries ) # Synchronise DrawTag data sets def Sync ( self ): return # Check if nominated Chart exists with stack def Exists ( self ): if P2Chart.DSeries(self.oChart.sChartName) == 'exists': return 1 else: return 0 # Perform Draw operation def DoDrawTag ( self, ePUnits, sTag, sTagMessage ): print ( 'Chartname:' + self.oChart.sChartName ) print ( 'Tag:' + sTag ) print ( 'TagMessage:' + sTagMessage) P2Draw.AttachTag(self.oChart.hChart,ePUnits,sTag,sTagMessage) #################### # Modelling base class (Modelling only, not actual trades) (UNDER DEVELOPMENT) # NOTES: Parent of all subsequent "ModelTrade" descendants # : Valid in CStack environments only, restricted to CStack domain # : Modelling 'Attachment' MUST have been pre-loaded in Chartboard # Refer Ribbon Bar >> WS Attachments >> Modelling further details # : Multiple "Model" and/or 'Attachment' instances may exist class Model: def __init__ ( self, oCStack, sAttachmentName ): self.oCStack = oCStack self.sAttachmentName: str = sAttachmentName self.hAttachment: int = P2Model.AttachmentOpen(sAttachmentName) # Synchronise Model data sets def Sync ( self ): return # Generate ModelTrade instances # NOTES: sUserDefinedTag allows for multiple unique ModelTrade instances # for the same Account def ModelTradeFactory(self,sAccountName,sUserDefinedTag): if P2Model.AccountSummary(self.hAttachment,sAccountName) != 'exists' : print('Account: ' + sAccountName + ' does not exist within Attachment ' + self.sAttachmentName ) return None return ModelTrade(self,sAccountName,sUserDefinedTag) # # Model trade class (Modelling only, not actual trades) (UNDER DEVELOPMENT) # NOTES: Restricted by parent "Model", "StockCode" and "UserDefinedTag" # which is usually unique to a particular modelling script # : Defined Account MUST already exist # : Multiple "ModelTrade" instances may exist TMARKUP_NONE: int = 0; # None, clear previous etc TMARKUP_SELL: int = (1<<1); TMARKUP_BUY: int = (1<<2); TMARKUP_OPEN: int = (1<<3); TMARKUP_CLOSED: int = (1<<4); TMARKUP_MATCHED: int = (1<<5); TMARKUP_PENDING: int = (1<<6); TMARKUP_SUMMARY: int = (1<<9); # Summary for all trades class ModelTrade: def __init__ ( self, oModel, sAccountName, sUserDefinedTag ): self.oModel = oModel self.oCStack = oModel.oCStack self.hAccount = P2Model.AccountOpen(oModel.hAttachment,sAccountName,self.oCStack.sStockCode,sUserDefinedTag) self.sUserDefinedTag: str = sUserDefinedTag self.sStockCode: str = oModel.oCStack.sStockCode # Synchronise ModelTrade data sets def Sync ( self ): return # Perform modelled trade with preset parameters # NOTES: Trades may dropped via CleanupTrades() or manually through Chartboard # modelled trade context menu. Details may be viewed through the # grid properties associated with each trade. def BuyQuantity ( self, dDATE, dQuantity, dPrice ): P2Model.BuyQuantity( self.hAccount,dDATE,dQuantity,dPrice ) def BuyValue ( self, dDATE, dValue, dPrice ): P2Model.BuyValue( self.hAccount,dDATE,dValue,dPrice ) def SellQuantity ( self, dDATE, dQuantity, dPrice ): P2Model.SellQuantity( self.hAccount,dDATE,dQuantity,dPrice ) def SellValue ( self, dDATE, dValue ): P2Model.SellValue( self.hAccount,dDATE,dValue ) # Cleanup previous modelled trades # NOTES: Identified via 'Attachment' and "sStockCode" this object relates # to and then internal "sUserDefinedTag" def CleanupTrades ( self ): P2Model.Cleanup(self.hAccount,self.sUserDefinedTag) # Select both raw and calculated values from Model # NOTES: None return flags no-data or request out of range # : Supported sValueName's = 'Quantity', 'Value' def GetValue_d(self,sValueName) -> float: return P2Model.GetValue_d(self.hAccount,sValueName) # Markup modelled trades on Chart(s) # NOTES: Modelled trades persist after completion and/or displacement of # script and as such may be managed manually via the [Markups>>Modelling] # context menu item for the respective Charts in stack. # : Trades displayed through this sequence will only persist for the # life cycle of the orginating script. # : Any legacy modelled trades for the account will also be displayed def MarkupTrades ( self, oChart, uiTradeTypes ): P2Model.Markups ( self.hAccount, oChart.hChart, uiTradeTypes )