+
+ inlineScript(); ?>
+
+
+
diff --git a/library/Application/Form/Command.php b/library/Application/Form/Command.php
new file mode 100644
index 0000000..4bd8f89
--- /dev/null
+++ b/library/Application/Form/Command.php
@@ -0,0 +1,87 @@
+setName('commande');
+ $this->setAction('/report/cmd');
+ $this->setMethod('post');
+ $this->addElement('hidden', 'cmdId', array(
+ 'required' => true,
+ )
+ );
+ $this->addElement('hidden', 'siren', array(
+ 'required' => true,
+ )
+ );
+ $this->addElement('text', 'email', array(
+ 'filters' => array('StringTrim'),
+ 'validators' => array('EmailAddress'),
+ 'label' => 'Email',
+ 'Description' => '',
+ 'required' => true,
+ )
+ );
+ $this->addElement('text', 'rs', array(
+ 'filters' => array('StringTrim'),
+ 'label' => 'Raison Sociale',
+ 'Description' => '',
+ 'required' => true,
+ )
+ );
+ $this->addElement('text', 'nom', array(
+ 'filters' => array('StringTrim'),
+ 'label' => 'Nom',
+ 'Description' => '',
+ 'required' => true,
+ )
+ );
+ $this->addElement('text', 'prenom', array(
+ 'filters' => array('StringTrim'),
+ 'label' => 'Prénom',
+ 'Description' => '',
+ 'required' => true,
+ )
+ );
+ $this->addElement('text', 'adresse', array(
+ 'filters' => array('StringTrim'),
+ 'label' => 'Adresse',
+ 'Description' => '',
+ 'required' => true,
+ )
+ );
+ $this->addElement('text', 'cp', array(
+ 'filters' => array('StringTrim'),
+ 'label' => 'Code Postal',
+ 'Description' => '',
+ 'required' => true,
+ )
+ );
+ $this->addElement('text', 'ville', array(
+ 'filters' => array('StringTrim'),
+ 'label' => 'Ville',
+ 'Description' => '',
+ 'required' => true,
+ )
+ );
+ $this->addElement('text', 'tel', array(
+ 'filters' => array('StringTrim'),
+ 'label' => 'Téléphone',
+ 'Description' => '',
+ 'required' => true,
+ )
+ );
+ $this->addElement('text', 'mobile', array(
+ 'filters' => array('StringTrim'),
+ 'label' => ' Téléphone Mobile',
+ 'Description' => '',
+ 'required' => false,
+ )
+ );
+ $this->addElement('submit', 'submit',array(
+ 'label' => 'Commander',
+ 'ignore' => true,
+ )
+ );
+ }
+}
\ No newline at end of file
diff --git a/library/Scores/Finance/Liasse.php b/library/Scores/Finance/Liasse.php
new file mode 100644
index 0000000..19a4729
--- /dev/null
+++ b/library/Scores/Finance/Liasse.php
@@ -0,0 +1,236 @@
+ 1,
+ 'K' => 1000,
+ 'M' => 1000000,
+ );
+
+ public function __construct($liasse, $unit = 'K')
+ {
+ $this->div = $this->unit[$unit];
+ $this->setData($liasse);
+ }
+
+ protected function setData($data)
+ {
+ $this->info = array(
+ 'dateFraicheBilan' => $data->DATE_FRAICHE_BILAN,
+ 'dateCloture' => $data->DATE_CLOTURE,
+ 'dateCloturePre' => $data->DATE_CLOTURE_PRE,
+ 'dureeMois' => $data->DUREE_MOIS,
+ 'dureeMoisPre' => $data->DUREE_MOIS_PRE,
+ 'monnaie' => $data->MONNAIE,
+ 'monnaieOri' => $data->MONNAIE_ORI,
+ 'monnaieLivUnite' => $data->MONNAIE_LIV_UNITE,
+ 'consolide' => $data->CONSOLIDE,
+ 'source' => $data->SOURCE,
+ );
+
+ //Affectaction des postes
+ foreach ($data->POSTES->item as $element){
+ if (in_array($element->id, array(
+ 'YP', 'YP1', '376', // Effectifs 2033 et 2050
+ 'M2G', 'M2H', // Autres effectifs
+ 'ZK', 'ZK1', // Taux
+ 'IJ', 'JG', 'JH', 'JJ', 'ZR', // pour holding/ste mere
+ 'XP' //numero de centre de gestion agréé
+ )))
+ {
+ $this->postes[$element->id] = number_format($element->val, 0, '', ' ');
+ } else {
+ $this->postes[$element->id] = $this->dMontant($element->val);
+ }
+ }
+
+ //Transformation Simplifié en Normal
+ if ( $data->CONSOLIDE == 'S'){
+ $this->postes = $this->bilanSimplifie2Normal($this->postes);
+ }
+ }
+
+ public function getInfo($key)
+ {
+ return $this->info[$key];
+ }
+
+ public function getPostes()
+ {
+ return $this->postes;
+ }
+
+ protected function dMontant($montant)
+ {
+ return number_format($montant/$this->div, 0, '', ' ');
+ }
+
+ function bilanSimplifie2Normal($bilanRS)
+ {
+ $tabBS2BN = array(
+ 'AH'=>'010',
+ 'AI'=>'012',
+ 'AI1'=>'013',
+ 'AJ'=>'014',
+ 'AK'=>'016',
+ 'AK1'=>'017',
+ 'AT'=>'028',
+ 'AU'=>'030',
+ 'AU1'=>'031',
+ 'BH'=>'040',
+ 'BI'=>'042',
+ 'BI1'=>'043',
+ 'BJ'=>'044',
+ 'BK'=>'048',
+ 'BK1'=>'049',
+ 'BL'=>'050',
+ 'BM'=>'052',
+ 'BM1'=>'053',
+ 'BT'=>'060',
+ 'BU'=>'062',
+ 'BU1'=>'063',
+ 'BV'=>'064',
+ 'BW'=>'066',
+ 'BW1'=>'067',
+ 'BX'=>'068',
+ 'BY'=>'070',
+ 'BY1'=>'071',
+ 'BZ'=>'072',
+ 'CA'=>'074',
+ 'CA1'=>'075',
+ 'CD'=>'080',
+ 'CE'=>'082',
+ 'CE1'=>'083',
+ 'CF'=>'084',
+ 'CG'=>'086',
+ 'CG1'=>'087',
+ 'CH'=>'092',
+ 'CI'=>'094',
+ 'CI1'=>'095',
+ 'CJ'=>'096',
+ 'CK'=>'098',
+ 'CK1'=>'099',
+ 'CO'=>'110',
+ '1A'=>'112',
+ '1A1'=>'113',
+ 'DA'=>'120',
+ 'DC'=>'124',
+ 'DD'=>'126',
+ 'DF'=>'130',
+ 'DG'=>'132',
+ 'DH'=>'134',
+ 'DI'=>'136',
+ 'DK'=>'140',
+ 'DL'=>'142',
+ 'DR'=>'154',
+ 'DP'=>'154',
+ 'DU'=>'156',
+ 'DV'=>'169',
+ 'DW'=>'164',
+ 'DX'=>'166',
+ 'EA'=>'172-169',
+ 'EB'=>'174',
+ 'EC'=>'176',
+ 'EE'=>'180',
+ 'EH'=>'156-195',
+ 'FA'=>'210-209',
+ 'FB'=>'209',
+ 'FC'=>'210',
+ 'FD'=>'214-215',
+ 'FE'=>'215',
+ 'FF'=>'214',
+ 'FH'=>'217',
+ 'FI'=>'218',
+ 'FK'=>'209+215+217',
+ 'FL'=>'210+214+218',
+ 'FM'=>'222',
+ 'FN'=>'224',
+ 'FO'=>'226',
+ 'FQ'=>'230',
+ 'FR'=>'232',
+ 'FS'=>'234',
+ 'FT'=>'236',
+ 'FU'=>'238',
+ 'FV'=>'240',
+ 'FW'=>'242',
+ 'FX'=>'244',
+ 'FY'=>'250',
+ 'FZ'=>'252',
+ 'GA'=>'254',
+ 'GE'=>'262',
+ 'GF'=>'264',
+ 'GG'=>'270',
+ 'GP'=>'280',
+ 'GU'=>'294',
+ 'GW'=>'270+280+294',
+ 'HD'=>'290',
+ 'HH'=>'300',
+ 'HI'=>'290-300',
+ 'HK'=>'306',
+ 'HL'=>'232+280+290',
+ 'HM'=>'264+294+300+306',
+ 'HN'=>'310',
+ 'YY'=>'374',
+ 'YZ'=>'378',
+ 'YP'=>'376',
+
+ //@todo : Traiter N-1
+
+
+ );
+
+ $bilanRN=array();
+ foreach ($tabBS2BN as $posteRN => $formule) {
+ if (preg_match('/\+|\-/', $formule)) {
+ $tabTmp=preg_split('/\+|\-/', $formule, -1, PREG_SPLIT_OFFSET_CAPTURE);
+ //$bilanRN[$posteRN]=0;
+ $scalc='';
+ foreach ($tabTmp as $i=>$tab) {
+ if ($i==0) {
+ $bilanRN[$posteRN]=$bilanRS[$tab[0]];
+ $scalc.=$bilanRS[$tab[0]];
+ }
+ else {
+ $signe=$formule[$tab[1]-1];
+ $scalc.=$signe;
+ if ($signe=='+') $bilanRN[$posteRN]+=$bilanRS[$tab[0]];
+ elseif ($signe=='-') $bilanRN[$posteRN]-=$bilanRS[$tab[0]];
+ $scalc.=$bilanRS[$tab[0]];
+ }
+ }
+ $bilanRN[$posteRN]=$bilanRN[$posteRN];
+ }
+ else $bilanRN[$posteRN]=$bilanRS[$formule];
+ }
+ if ($bilanRS['240']<>0) {
+ $bilanRN['BL']=$bilanRS['050'];
+ $bilanRN['BM']=$bilanRS['052'];
+ } else {
+ $bilanRN['BN']=$bilanRS['050'];
+ $bilanRN['BO']=$bilanRS['052'];
+ }
+
+ if ($bilanRS['070']<>0 || $bilanRS['074']<>0 || $bilanRS['052']<>0 || $bilanRS['062']<>0)
+ $bilanRN['GC']=$bilanRS['256'];
+ elseif ($bilanRS['070']==0 && $bilanRS['074']==0 && $bilanRS['052']==0 && $bilanRS['062']==0 && $bilanRS['254']<>0)
+ $bilanRN['GD']=$bilanRS['256'];
+
+ if ($bilanRS['584']<>0) {
+ $bilanRN['HB']=$bilanRS['584'];
+ $bilanRN['HA']=$bilanRS['290']-$bilanRS['584'];
+ } else
+ $bilanRN['HA']=$bilanRS['290'];
+
+ if ($bilanRS['582']<>0) {
+ $bilanRN['HF']=$bilanRS['582'];
+ $bilanRN['HE']=$bilanRS['582']-$bilanRS['300'];
+ } else
+ $bilanRN['HE']=$bilanRS['300'];
+
+ return $bilanRN;
+ }
+}
\ No newline at end of file
diff --git a/library/Scores/Finance/Liasse/XLS.php b/library/Scores/Finance/Liasse/XLS.php
new file mode 100644
index 0000000..f38a61d
--- /dev/null
+++ b/library/Scores/Finance/Liasse/XLS.php
@@ -0,0 +1,126 @@
+ '.xls',
+ 'Excel2007' => '.xlsx',
+ );
+ protected $assoc = array();
+ protected $values = array();
+
+ /**
+ *
+ * Enter description here ...
+ * @param string $modele
+ * Nom du modèle
+ * @param string $mode
+ * Type de fichier excel pour l'ecriture (Excel5 | Excel2007)
+ */
+ public function __construct($modele = '', $mode = 'Excel5')
+ {
+ $c = Zend_Registry::get('config');
+ $this->path = $c->profil->path->files . '/';
+ if (!is_dir($this->path)){
+ mkdir($this->path);
+ }
+ $this->modele = $modele;
+ if (empty($this->modele)){
+ $this->modele = 'bdf_liasse_template';
+ }
+ $this->mode = $mode;
+ }
+
+ public function dataModel($siren, $raisonSociale, $values)
+ {
+ switch($this->modele)
+ {
+ case 'bdf_liasse_template':
+ //Ajout champs spéciaux
+ $values['TEXTE_SIRET'] = 'Siret : '.$siren;
+ $values['TEXTE_RS'] = 'Société : '.$raisonSociale;
+ $values['TEXTE_DATEN'] = 'Date de clôture : le ' .
+ substr($values['DATE_CLOTURE'],6,2) . '/' .
+ substr($values['DATE_CLOTURE'],4,2) . '/' .
+ substr($values['DATE_CLOTURE'],0,4) .
+ ' sur ' . $values['DUREE_MOIS'] . ' mois';
+ break;
+ //Bilan Normal Cerfa
+ case 'liasse_2050':
+ $values['TEXTE_SIRET'] = $siren;
+ $values['TEXTE_RS'] = $raisonSociale;
+ $values['TEXTE_DATEN'] =
+ substr($values['DATE_CLOTURE'],6,2) . '/' .
+ substr($values['DATE_CLOTURE'],4,2) . '/' .
+ substr($values['DATE_CLOTURE'],0,4);
+ $values['TEXTE_DATEN1'] =
+ substr($values['DATE_CLOTURE_PRE'],6,2) . '/' .
+ substr($values['DATE_CLOTURE_PRE'],4,2) . '/' .
+ substr($values['DATE_CLOTURE_PRE'],0,4);
+ $values['TEXTE_DUREEN'] = $values['DUREE_MOIS'];
+ $values['TEXTE_DUREEN1'] = $values['DUREE_MOIS_PRE'];
+ break;
+ //Bilan Simplifié Cerfa
+ case 'liasse_2033':
+ $values['TEXTE_SIRET'] = $siren;
+ $values['TEXTE_RS'] = $raisonSociale;
+ $values['TEXTE_DATEN'] =
+ substr($values['DATE_CLOTURE'],6,2) . '/' .
+ substr($values['DATE_CLOTURE'],4,2) . '/' .
+ substr($values['DATE_CLOTURE'],0,4);
+ $values['TEXTE_DATEN1'] =
+ substr($values['DATE_CLOTURE_PRE'],6,2) . '/' .
+ substr($values['DATE_CLOTURE_PRE'],4,2) . '/' .
+ substr($values['DATE_CLOTURE_PRE'],0,4);
+ $values['TEXTE_DUREEN'] = $values['DUREE_MOIS'];
+ $values['TEXTE_DUREEN1'] = $values['DUREE_MOIS_PRE'];
+ break;
+ }
+
+ //Association
+ $dataAssoc = parse_ini_file(realpath(dirname(__FILE__)).'/models/'.$this->modele.'.ini', true);
+ $assoc = array();
+ foreach($dataAssoc as $sheet => $dataCell)
+ {
+ foreach($dataCell as $key => $cell)
+ {
+ $assoc[$key] = array($sheet, $cell);
+ }
+ }
+ $this->assoc = $assoc;
+ $this->values = $values;
+ }
+
+ public function dataFile($file)
+ {
+ require_once 'Vendors/phpexcel/PHPExcel.php';
+ $objPHPexcel = PHPExcel_IOFactory::load(realpath(dirname(__FILE__)).'/models/'.$this->modele.'.xls');
+ foreach( $this->assoc as $key => $position )
+ {
+ $sheet = $position[0];
+ $cell = $position[1];
+ if (array_key_exists($key, $this->values))
+ {
+ $objWorksheet = $objPHPexcel->getSheet($sheet);
+ $objWorksheet->getCell($cell)->setValue($this->values[$key]);
+ }
+ /*
+ else
+ {
+ $objWorksheet = $objPHPexcel->getSheet($sheet);
+ $objWorksheet->getCell($cell)->setValue('_');
+ //echo "La clé $key n'a pas de valeur! ";
+ }
+ */
+ }
+ $objPHPexcel->setActiveSheetIndex(0);
+ $objWriter = PHPExcel_IOFactory::createWriter($objPHPexcel, $this->mode);
+ $objWriter->save($this->path.'/'.$file);
+ }
+
+
+
+}
+?>
\ No newline at end of file
diff --git a/library/Scores/Finance/Liasse/models/bdf_liasse_template.ini b/library/Scores/Finance/Liasse/models/bdf_liasse_template.ini
new file mode 100644
index 0000000..cd07bd7
--- /dev/null
+++ b/library/Scores/Finance/Liasse/models/bdf_liasse_template.ini
@@ -0,0 +1,400 @@
+[0]
+AA = "C5"
+AB = "C6"
+AC = "E6"
+AD = "C7"
+AE = "E7"
+AF = "C8"
+AG = "E8"
+AH = "C9"
+AI = "E9"
+AJ = "C10"
+AK = "E10"
+AL = "C11"
+AM = "E11"
+AN = "C12"
+AO = "E12"
+AP = "C13"
+AQ = "E13"
+AR = "C14"
+AS = "E14"
+AT = "C15"
+AU = "E15"
+AV = "C16"
+AW = "E16"
+AX = "C17"
+AY = "E17"
+CS = "C18"
+CT = "E18"
+CU = "C19"
+CV = "E19"
+BB = "C20"
+BC = "E20"
+BD = "C21"
+BE = "E21"
+BF = "C22"
+BG = "E22"
+BH = "C23"
+BI = "E23"
+BJ = "C24"
+BK = "E24"
+BL = "C25"
+BM = "E25"
+BN = "C26"
+BO = "E26"
+BP = "C27"
+BQ = "E27"
+BR = "C28"
+BS = "E28"
+BT = "C29"
+BU = "E29"
+BV = "C30"
+BW = "E30"
+BX = "C31"
+BY = "E31"
+BZ = "C32"
+CA = "E32"
+CB = "C33"
+CC = "E33"
+CD = "C34"
+CE = "E34"
+CF = "C35"
+CG = "E35"
+CH = "C36"
+CI = "E36"
+CJ = "C37"
+CK = "E37"
+CL = "C38"
+CM = "C39"
+CN = "C40"
+CO = "C41"
+1A = "E41"
+TEXTE_SIRET = "A1"
+TEXTE_RS = "A2"
+TEXTE_DATEN = "A3"
+
+[1]
+DA = "C5"
+DB = "C6"
+DC = "C7"
+DD = "C8"
+DE = "C9"
+DF = "C10"
+DG = "C11"
+DH = "C12"
+DI = "C13"
+DJ = "C14"
+DK = "C15"
+DL = "C16"
+DM = "C17"
+DN = "C18"
+DO = "C19"
+DP = "C20"
+DQ = "C21"
+DR = "C22"
+DS = "C23"
+DT = "C24"
+DU = "C25"
+DV = "C26"
+DW = "C27"
+DX = "C28"
+DY = "C29"
+DZ = "C30"
+EA = "C31"
+EB = "C32"
+EC = "C33"
+ED = "C34"
+EE = "C35"
+1B = "C37"
+1C = "C38"
+1D = "C39"
+1E = "C40"
+EF = "C41"
+EJ = "C42"
+EG = "C43"
+EH = "C44"
+EI = "C45"
+
+[2]
+FA = "C7"
+FB = "E7"
+FC = "G7"
+FD = "C8"
+FE = "E8"
+FF = "G8"
+FG = "C9"
+FH = "E9"
+FI = "G9"
+FJ = "C10"
+FK = "E10"
+FL = "G10"
+FM = "G11"
+FN = "G12"
+FO = "G13"
+FP = "G14"
+FQ = "G14"
+FR = "G16"
+FS = "G17"
+FT = "G18"
+FU = "G19"
+FV = "G20"
+FW = "G21"
+FX = "G22"
+FY = "G23"
+FZ = "G24"
+GA = "G25"
+GB = "G27"
+GC = "G28"
+GD = "G29"
+GE = "G30"
+GF = "G31"
+GG = "G32"
+GH = "G33"
+GI = "G34"
+GJ = "G35"
+GK = "G36"
+GL = "G37"
+GM = "G38"
+GN = "G39"
+GO = "G40"
+GP = "G41"
+GQ = "G42"
+GR = "G43"
+GS = "G44"
+GT = "G45"
+GU = "G46"
+GV = "G47"
+GW = "G48"
+HA = "G49"
+HB = "G50"
+HC = "G51"
+HD = "G52"
+HE = "G53"
+HF = "G54"
+HG = "G55"
+HH = "G56"
+HI = "G57"
+HJ = "G58"
+HK = "G59"
+HL = "G60"
+HM = "G61"
+HN = "G62"
+HO = "G63"
+HY = "G64"
+1G = "G66"
+HP = "G67"
+HQ = "G69"
+1H = "G70"
+1J = "G71"
+1K = "G72"
+HX = "G73"
+
+[3]
+ZE = "D5"
+YQ = "D8"
+YR = "D9"
+YS = "D10"
+YT = "D11"
+YU = "D13"
+YV = "D15"
+ZJ = "D17"
+YW = "D18"
+9Z = "D19"
+YX = "D20"
+YY = "D21"
+YZ = "D22"
+ZA = "D23"
+0B = "D24"
+0S = "D25"
+YP = "D27"
+
+[4]
+3T = "D5"
+3U = "D6"
+3V = "D7"
+3W = "D8"
+3X = "D9"
+IA = "D10"
+IE = "D11"
+IJ = "D12"
+3Y = "D13"
+3Z = "D14"
+4A = "D15"
+4E = "D16"
+4J = "D17"
+4N = "D18"
+4T = "D19"
+4X = "D20"
+5B = "D21"
+5F = "D22"
+5L = "D23"
+5R = "D24"
+5V = "D25"
+5Z = "D26"
+6A = "D27"
+6E = "D28"
+02 = "D29"
+9U = "D30"
+06 = "D31"
+6N = "D32"
+6T = "D33"
+6X = "D34"
+7B = "D35"
+7C = "D36"
+TA = "F5"
+TD = "F6"
+TG = "F7"
+TJ = "F8"
+TM = "F9"
+IB = "F10"
+IF = "F11"
+IK = "F12"
+TP = "F13"
+TS = "F14"
+4B = "F15"
+4F = "F16"
+4K = "F17"
+4P = "F18"
+4U = "F19"
+4Y = "F20"
+5C = "F21"
+5H = "F22"
+5M = "F23"
+5S = "F24"
+5W = "F25"
+TV = "F26"
+6B = "F27"
+6F = "F28"
+03 = "F29"
+9V = "F30"
+07 = "F31"
+6P = "F32"
+6U = "F33"
+6Y = "F34"
+TY = "F35"
+UB = "F36"
+UE = "F37"
+UG = "F38"
+UJ = "F39"
+TB = "H5"
+TE = "H6"
+TH = "H7"
+TK = "H8"
+TN = "H9"
+IC = "H10"
+IG = "H11"
+IL = "H12"
+TQ = "H13"
+TT = "H14"
+4C = "H15"
+4G = "H16"
+4L = "H17"
+4R = "H18"
+4V = "H19"
+4Z = "H20"
+5D = "H21"
+5J = "H22"
+5N = "H23"
+5T = "H24"
+5X = "H25"
+TW = "H26"
+6C = "H27"
+6G = "H28"
+04 = "H29"
+9W = "H30"
+08 = "H31"
+6R = "H32"
+6V = "H33"
+6Z = "H34"
+TZ = "H35"
+UC = "H36"
+UF = "H37"
+UH = "H38"
+UK = "H39"
+TC = "J5"
+TF = "J6"
+TI = "J7"
+TL = "J8"
+TO = "J9"
+ID = "J10"
+IH = "J11"
+IM = "J12"
+TR = "J13"
+TU = "J14"
+4D = "J15"
+4H = "J16"
+4M = "J17"
+4S = "J18"
+4W = "J19"
+5A = "J20"
+5E = "J21"
+5K = "J22"
+5P = "J23"
+5U = "J24"
+5Y = "J25"
+TX = "J26"
+6D = "J27"
+6H = "J28"
+05 = "J29"
+9X = "J30"
+09 = "J31"
+6S = "J32"
+6W = "J33"
+7A = "J34"
+UA = "J35"
+UD = "J36"
+10 = "J40"
+
+[5]
+UQ = "E11"
+UL = "G6"
+UP = "G7"
+UT = "G8"
+VA = "G9"
+UX = "G10"
+UU = "G11"
+UY = "G12"
+UZ = "G13"
+VM = "G14"
+VB = "G15"
+VN = "G16"
+VP = "G17"
+VC = "G18"
+VR = "G19"
+VS = "G20"
+VT = "G21"
+VD = "G22"
+VE = "G23"
+VF = "G24"
+UM = "I6"
+UR = "I7"
+UV = "I8"
+VU = "I21"
+UN = "K6"
+US = "K7"
+UW = "K8"
+VV = "K21"
+7Y = "E27"
+7Z = "E28"
+VG = "E29"
+VH = "E30"
+8A = "E31"
+8B = "E32"
+8C = "E33"
+8D = "E34"
+8E = "E35"
+VW = "E36"
+VX = "E37"
+VQ = "E38"
+8J = "E39"
+VI = "E40"
+8K = "E41"
+SZ = "E42"
+8L = "E43"
+VY = "E44"
+VZ = "G44"
+VZ3 = "H44"
+VZ4 = "I44"
+VJ = "E45"
+VK = "E46"
+VL = "K45"
\ No newline at end of file
diff --git a/library/Scores/Finance/Liasse/models/bdf_liasse_template.xls b/library/Scores/Finance/Liasse/models/bdf_liasse_template.xls
new file mode 100644
index 0000000..8e3a15d
Binary files /dev/null and b/library/Scores/Finance/Liasse/models/bdf_liasse_template.xls differ
diff --git a/library/Scores/Finance/Liasse/models/liasse_2033.ini b/library/Scores/Finance/Liasse/models/liasse_2033.ini
new file mode 100644
index 0000000..4a7dd06
--- /dev/null
+++ b/library/Scores/Finance/Liasse/models/liasse_2033.ini
@@ -0,0 +1,352 @@
+;2033 ACTIF PASSIF
+[0]
+TEXTE_SIRET = "D6"
+TEXTE_RS = "F4"
+TEXTE_DATEN = "W10"
+TEXTE_DATEN1 = "Z10"
+TEXTE_DUREEN = "G7"
+TEXTE_DUREEN1 = "S7"
+010 = "K12"
+014 = "K13"
+028 = "K14"
+040 = "K15"
+044 = "K16"
+050 = "K17"
+060 = "K18"
+064 = "K19"
+068 = "K20"
+072 = "K21"
+080 = "K22"
+084 = "K23"
+088 = "K24"
+092 = "K25"
+096 = "K26"
+110 = "K27"
+012 = "Q12"
+016 = "Q13"
+030 = "Q14"
+042 = "Q15"
+048 = "Q16"
+052 = "Q17"
+062 = "Q18"
+066 = "Q19"
+070 = "Q20"
+074 = "Q21"
+082 = "Q22"
+086 = "Q23"
+090 = "Q24"
+094 = "Q25"
+098 = "Q26"
+112 = "Q27"
+013 = "W12"
+017 = "W13"
+031 = "W14"
+043 = "W15"
+049 = "W16"
+053 = "W17"
+063 = "W18"
+067 = "W19"
+071 = "W20"
+075 = "W21"
+083 = "W22"
+087 = "W23"
+091 = "W24"
+095 = "W25"
+099 = "W26"
+113 = "W27"
+120 = "W29"
+124 = "W30"
+126 = "W31"
+130 = "W32"
+132 = "W33"
+134 = "W34"
+136 = "W35"
+140 = "W36"
+142 = "W37"
+154 = "W38"
+156 = "W39"
+164 = "W40"
+166 = "W41"
+172 = "W42"
+174 = "W43"
+176 = "W44"
+180 = "W45"
+195 = "Z46"
+182 = "Z47"
+184 = "Z48"
+N00 = "Z12"
+N01 = "Z13"
+N02 = "Z14"
+N03 = "Z15"
+N04 = "Z16"
+N05 = "Z17"
+N06 = "Z18"
+N07 = "Z19"
+N08 = "Z20"
+N09 = "Z21"
+N10 = "Z22"
+N11 = "Z23"
+N12 = "Z24"
+N13 = "Z25"
+N14 = "Z26"
+N15 = "Z27"
+N16 = "Z29"
+N17 = "Z30"
+N18 = "Z31"
+N19 = "Z32"
+N20 = "Z33"
+N21 = "Z34"
+N22 = "Z35"
+N23 = "Z36"
+N24 = "Z37"
+N25 = "Z38"
+N26 = "Z39"
+N27 = "Z40"
+N28 = "Z41"
+N29 = "Z42"
+N30 = "Z43"
+N31 = "Z44"
+N32 = "Z45"
+
+;2033 CDR
+[1]
+209 = "R8"
+215 = "R9"
+217 = "R10"
+24B = "K20"
+24A = "U20"
+243 = "R21"
+259 = "R26"
+247 = "H40"
+248 = "V40"
+981 = "U41"
+344 = "I42"
+346 = "T42"
+381 = "D48"
+382 = "T48"
+374 = "H49"
+376 = "S49"
+378 = "H50"
+210 = "AA8"
+214 = "AA9"
+218 = "AA10"
+222 = "AA11"
+224 = "AA12"
+226 = "AA13"
+230 = "AA14"
+232 = "AA15"
+234 = "AA16"
+236 = "AA17"
+238 = "AA18"
+240 = "AA19"
+242 = "AA20"
+244 = "AA21"
+250 = "AA22"
+252 = "AA23"
+254 = "AA24"
+256 = "AA25"
+262 = "AA26"
+264 = "AA27"
+270 = "AA28"
+280 = "AA29"
+290 = "AA30"
+294 = "AA31"
+300 = "AA32"
+306 = "AA33"
+310 = "AA34"
+312 = "AA35"
+316 = "AA36"
+318 = "AA37"
+322 = "AA38"
+324 = "AA39"
+330 = "AA40"
+352 = "AA43"
+356 = "AA44"
+366 = "AA46"
+370 = "AA47"
+380 = "Z50"
+N33 = "AD8"
+N34 = "AD9"
+N35 = "AD10"
+N36 = "AD11"
+N37 = "AD12"
+N38 = "AD13"
+N39 = "AD14"
+N40 = "AD15"
+N41 = "AD16"
+N42 = "AD17"
+N43 = "AD18"
+N44 = "AD19"
+N45 = "AD20"
+N46 = "AD21"
+N47 = "AD22"
+N48 = "AD23"
+N49 = "AD24"
+N50 = "AD25"
+N51 = "AD26"
+N52 = "AD27"
+N53 = "AD28"
+N54 = "AD29"
+N55 = "AD30"
+N56 = "AD31"
+N57 = "AD32"
+N58 = "AD33"
+N59 = "AD34"
+314 = "AE35"
+342 = "AE41"
+350 = "AE42"
+354 = "AE43"
+360 = "AE45"
+368 = "AE46"
+372 = "AE47"
+388 = "AE48"
+399 = "AE50"
+
+
+;2033 IMMO AMORT.
+[2]
+400 = "H9"
+410 = "H10"
+420 = "H11"
+430 = "H12"
+440 = "H13"
+450 = "H14"
+460 = "H15"
+470 = "H16"
+480 = "H17"
+490 = "H18"
+402 = "P9"
+412 = "P10"
+422 = "P11"
+432 = "P12"
+442 = "P13"
+452 = "P14"
+462 = "P15"
+472 = "P16"
+482 = "P17"
+492 = "P18"
+404 = "W9"
+414 = "W10"
+424 = "W11"
+434 = "W12"
+444 = "W13"
+454 = "W14"
+464 = "W15"
+474 = "W16"
+484 = "W17"
+494 = "W18"
+406 = "AD9"
+416 = "AD10"
+426 = "AD11"
+436 = "AD12"
+446 = "AD13"
+456 = "AD14"
+466 = "AD15"
+476 = "AD16"
+486 = "AD17"
+496 = "AD18"
+500 = "K21"
+510 = "K22"
+520 = "K23"
+530 = "K24"
+540 = "K25"
+550 = "K26"
+560 = "K27"
+570 = "K28"
+502 = "T21"
+512 = "T22"
+522 = "T23"
+532 = "T24"
+543 = "T25"
+552 = "T26"
+562 = "T27"
+572 = "T28"
+504 = "AE21"
+514 = "AE22"
+524 = "AE23"
+534 = "AE24"
+544 = "AE25"
+554 = "AE26"
+564 = "AE27"
+574 = "AE28"
+506 = "AJ21"
+516 = "AJ22"
+526 = "AJ23"
+536 = "AJ24"
+546 = "AJ25"
+556 = "AJ26"
+566 = "AJ27"
+576 = "AJ28"
+578 = "I42"
+580 = "O42"
+582 = "U42"
+584 = "Z42"
+586 = "AG42"
+588 = "AM42"
+590 = "AG43"
+592 = "AM43"
+593 = "AM44"
+596 = "AG45"
+598 = "AM45"
+
+;2033 PROVISIONS
+[3]
+610 = "H9"
+601 = "H10"
+610 = "H11"
+620 = "H12"
+630 = "H13"
+640 = "H14"
+650 = "H15"
+660 = "H16"
+680 = "H17"
+602 = "P9"
+603 = "P10"
+612 = "P11"
+622 = "P12"
+632 = "P13"
+642 = "P14"
+652 = "P15"
+662 = "P16"
+682 = "P17"
+604 = "W9"
+605 = "W10"
+614 = "W11"
+624 = "W12"
+634 = "W13"
+644 = "W14"
+654 = "W15"
+664 = "W16"
+684 = "W17"
+606 = "AD9"
+607 = "AD10"
+616 = "AD11"
+626 = "AD12"
+636 = "AD13"
+646 = "AD14"
+656 = "AD15"
+666 = "AD16"
+686 = "AD17"
+700 = "G20"
+710 = "G21"
+720 = "G22"
+730 = "G23"
+740 = "G24"
+750 = "G25"
+760 = "G26"
+770 = "G27"
+705 = "K20"
+715 = "K21"
+725 = "K22"
+735 = "K23"
+745 = "K24"
+755 = "K25"
+765 = "K26"
+775 = "K27"
+780 = "AJ27"
+982 = "AJ29"
+983 = "AJ30"
+984 = "AJ31"
+860 = "AJ32"
+870 = "AJ33"
+
diff --git a/library/Scores/Finance/Liasse/models/liasse_2033.xls b/library/Scores/Finance/Liasse/models/liasse_2033.xls
new file mode 100644
index 0000000..a8e7dfb
Binary files /dev/null and b/library/Scores/Finance/Liasse/models/liasse_2033.xls differ
diff --git a/library/Scores/Finance/Liasse/models/liasse_2033_ori.xls b/library/Scores/Finance/Liasse/models/liasse_2033_ori.xls
new file mode 100644
index 0000000..e71f262
Binary files /dev/null and b/library/Scores/Finance/Liasse/models/liasse_2033_ori.xls differ
diff --git a/library/Scores/Finance/Liasse/models/liasse_2050.ini b/library/Scores/Finance/Liasse/models/liasse_2050.ini
new file mode 100644
index 0000000..0591e25
--- /dev/null
+++ b/library/Scores/Finance/Liasse/models/liasse_2050.ini
@@ -0,0 +1,1067 @@
+; 2050 - Actif
+[0]
+TEXTE_RS = "E4"
+;texte_adresse = "E5"
+TEXTE_SIRET = "D6"
+;texte_ape = "D7"
+TEXTE_DUREEN = "K6"
+TEXTE_DATEN1 = "K7"
+TEXTE_DUREEN1 = "K8"
+TEXTE_DATEN = "K9"
+
+; actif brut
+AA = "G11"
+AB = "G12"
+AD = "G13"
+AF = "G14"
+AH = "G15"
+AJ = "G16"
+AL = "G17"
+AN = "G18"
+AP = "G19"
+AR = "G20"
+AT = "G21"
+AV = "G22"
+AX = "G23"
+CS = "G24"
+CU = "G25"
+BB = "G26"
+BD = "G27"
+BF = "G28"
+BH = "G29"
+BJ = "G30"
+BL = "G31"
+BN = "G32"
+BP = "G33"
+BR = "G34"
+BT = "G35"
+BV = "G36"
+BX = "G37"
+BZ = "G38"
+CB = "G39"
+CD = "G40"
+CF = "G41"
+CH = "G42"
+CJ = "G43"
+CL = "G44"
+CM = "G45"
+CN = "G46"
+CO = "G47"
+; actif ammort.
+AC = "I12"
+AE = "I13"
+AG = "I14"
+AI = "I15"
+AK = "I16"
+AM = "I17"
+AO = "I18"
+AQ = "I19"
+AS = "I20"
+AU = "I21"
+AW = "I22"
+AY = "I23"
+CT = "I24"
+CV = "I25"
+BC = "I26"
+BE = "I27"
+BG = "I28"
+BI = "I29"
+BK = "I30"
+BM = "I31"
+BO = "I32"
+BQ = "I33"
+BS = "I34"
+BU = "I35"
+BW = "I36"
+BY = "I37"
+CA = "I38"
+CC = "I39"
+CE = "I40"
+CG = "I41"
+CI = "I42"
+CK = "I43"
+1A = "I47"
+CP = "I48"
+; actif net N
+AA2 = "J11"
+AC1 = "J12"
+AE1 = "J13"
+AG1 = "J14"
+AI1 = "J15"
+AK1 = "J16"
+AM1 = "J17"
+AO1 = "J18"
+AQ1 = "J19"
+AS1 = "J20"
+AU1 = "J21"
+AW1 = "J22"
+AY1 = "J23"
+CT1 = "J24"
+CV1 = "J25"
+BC1 = "J26"
+BE1 = "J27"
+BG1 = "J28"
+BI1 = "J29"
+BK1 = "J30"
+BM1 = "J31"
+BO1 = "J32"
+BQ1 = "J33"
+BS1 = "J34"
+BU1 = "J35"
+BW1 = "J36"
+BY1 = "J37"
+CA1 = "J38"
+CC1 = "J39"
+CE1 = "J40"
+CG1 = "J41"
+CI1 = "J42"
+CK1 = "J43"
+CL2 = "J44"
+CM2 = "J45"
+CN2 = "J46"
+1A1 = "J47"
+; actif net N-1
+AA3 = "K11"
+AC2 = "K12"
+AE2 = "K13"
+AG2 = "K14"
+AI2 = "K15"
+AK2 = "K16"
+AM2 = "K17"
+AO2 = "K18"
+AQ2 = "K19"
+AS2 = "K20"
+AU2 = "K21"
+AW2 = "K22"
+AY2 = "K23"
+CT2 = "K24"
+CV2 = "K25"
+BC2 = "K26"
+BE2 = "K27"
+BG2 = "K28"
+BI2 = "K29"
+BK2 = "K30"
+BM2 = "K31"
+BO2 = "K32"
+BQ2 = "K33"
+BS2 = "K34"
+BU2 = "K35"
+BW2 = "K36"
+BY2 = "K37"
+CA2 = "K38"
+CC2 = "K39"
+CE2 = "K40"
+CG2 = "K41"
+CI2 = "K42"
+CK2 = "K43"
+CL3 = "K44"
+CM3 = "K45"
+CN3 = "K46"
+1A2 = "K47"
+CR = "K48"
+
+; 2051 - Passif
+[1]
+DA = "I8"
+DB = "I9"
+DC = "I10"
+DD = "I11"
+DE = "I12"
+DF = "I13"
+DG = "I14"
+DH = "I15"
+DI = "I16"
+DJ = "I17"
+DK = "I18"
+DL = "I19"
+DM = "I20"
+DN = "I21"
+DO = "I22"
+DP = "I23"
+DQ = "I24"
+DR = "I25"
+DS = "I26"
+DT = "I27"
+DU = "I28"
+DV = "I29"
+DW = "I30"
+DX = "I31"
+DY = "I32"
+DZ = "I33"
+EA = "I34"
+EB = "I35"
+EC = "I36"
+ED = "I37"
+EE = "I38"
+1B = "I39"
+1C = "I40"
+1D = "I41"
+1E = "I42"
+EF = "I43"
+EG = "I44"
+EH = "I45"
+; passif dont
+DA0 = "F8"
+EK = "G10"
+B1 = "G13"
+EJ = "G14"
+EI = "G29"
+; passif N-1
+DA1 = "J8"
+DB1 = "J9"
+DC1 = "J10"
+DD1 = "J11"
+DE1 = "J12"
+DF1 = "J13"
+DG1 = "J14"
+DH1 = "J15"
+DI1 = "J16"
+DJ1 = "J17"
+DK1 = "J18"
+DL1 = "J19"
+DM1 = "J20"
+DN1 = "J21"
+DO1 = "J22"
+DP1 = "J23"
+DQ1 = "J24"
+DR1 = "J25"
+DS1 = "J26"
+DT1 = "J27"
+DU1 = "J28"
+DV1 = "J29"
+DW1 = "J30"
+DX1 = "J31"
+DY1 = "J32"
+DZ1 = "J33"
+EA1 = "J34"
+EB1 = "J35"
+EC1 = "J36"
+ED1 = "J37"
+EE1 = "J38"
+1B1 = "J39"
+1C1 = "J40"
+1D1 = "J41"
+1E1 = "J42"
+EF1 = "J43"
+EG1 = "J44"
+EH1 = "J45"
+
+; 2052 - Compte de résultat
+[2]
+FA = "E8"
+FB = "G8"
+FC = "I8"
+FD = "E9"
+FE = "G9"
+FF = "I9"
+FG = "E10"
+FH = "G10"
+FI = "I10"
+FJ = "E11"
+FK = "G11"
+FL = "I11"
+FM = "I12"
+FN = "I13"
+FO = "I14"
+FP = "I15"
+FQ = "I16"
+FR = "I17"
+FS = "I18"
+FT = "I19"
+FU = "I20"
+FV = "I21"
+FW = "I22"
+FX = "I23"
+FY = "I24"
+FZ = "I25"
+GA = "I26"
+GB = "I27"
+GC = "I28"
+GD = "I29"
+GE = "I30"
+;AZ = ""
+GF = "I31"
+GG = "I32"
+GH = "I33"
+GI = "I34"
+GJ = "I35"
+GK = "I36"
+GL = "I37"
+GM = "I38"
+GN = "I39"
+GO = "I40"
+GP = "I41"
+GQ = "I42"
+GR = "I43"
+GS = "I44"
+GT = "I45"
+GU = "I46"
+GV = "I47"
+GW = "I48"
+; cdr année N-1
+FC1 = "J8"
+FF1 = "J9"
+FI1 = "J10"
+FL1 = "J11"
+FM1 = "J12"
+FN1 = "J13"
+FO1 = "J14"
+FP1 = "J15"
+FQ1 = "J16"
+FR1 = "J17"
+FS1 = "J18"
+FT1 = "J19"
+FU1 = "J20"
+FV1 = "J21"
+FW1 = "J22"
+FX1 = "J23"
+FY1 = "J24"
+FZ1 = "J25"
+GA1 = "J26"
+GB1 = "J27"
+GC1 = "J28"
+GD1 = "J29"
+GE1 = "J30"
+GF1 = "J31"
+GG1 = "J32"
+GH1 = "J33"
+GI1 = "J34"
+GJ1 = "J35"
+GK1 = "J36"
+GL1 = "J37"
+GM1 = "J38"
+GN1 = "J39"
+GO1 = "J40"
+GP1 = "J41"
+GQ1 = "J42"
+GR1 = "J43"
+GS1 = "J44"
+GT1 = "J45"
+GU1 = "J46"
+GV1 = "J47"
+GW1 = "J48"
+
+; 2053 - Compte de résultat (suite)
+[3]
+HA = "J7"
+HB = "J8"
+HC = "J9"
+HD = "J10"
+HE = "J11"
+HF = "J12"
+HG = "J13"
+HH = "J14"
+HI = "J15"
+HJ = "J16"
+HK = "J17"
+HL = "J18"
+HM = "J19"
+HN = "J20"
+HO = "J21"
+HY = "J22"
+1G = "J23"
+HP = "J24"
+HQ = "J25"
+1H = "J26"
+1J = "J27"
+IK = "J28"
+HX = "J29"
+A1 = "J30"
+A2 = "J31"
+A3 = "J32"
+A4 = "J33"
+A6 = "E34"
+A9 = "H34"
+; renvois 7
+D3B = "J37"
+D3E = "J38"
+D3H = "J39"
+D3L = "J40"
+D3P = "J41"
+; renvoi 8
+D7B = "J44"
+D7E = "J45"
+D7H = "J46"
+D7L = "J47"
+D7P = "J48"
+; cdr suite N-1
+HA1 = "K7"
+HB1 = "K8"
+HC1 = "K9"
+HD1 = "K10"
+HE1 = "K11"
+HF1 = "K12"
+HG1 = "K13"
+HH1 = "K14"
+HI1 = "K15"
+HJ1 = "K16"
+HK1 = "K17"
+HL1 = "K18"
+HM1 = "K19"
+HN1 = "K20"
+HO1 = "K21"
+HY1 = "K22"
+1G1 = "K23"
+HP1 = "K24"
+HQ1 = "K25"
+1H1 = "K26"
+1J1 = "K27"
+IK1 = "K28"
+HX1 = "K29"
+A11 = "K30"
+A21 = "K31"
+A31 = "K32"
+A41 = "K33"
+; renvois 7
+D3C = "K37"
+D3F = "K38"
+D3J = "K39"
+D3M = "K40"
+D3R = "K41"
+; renvoi 8
+D7C = "K44"
+D7F = "K45"
+D7J = "K46"
+D7M = "K47"
+D7R = "K48"
+
+; 2054 - Annexe 5 Immobilisations
+[4]
+; immo brutes
+KA = "H7"
+KD = "H8"
+KG = "H9"
+KJ = "H10"
+KM = "H11"
+KP = "H12"
+KS = "H13"
+KV = "H14"
+KY = "H15"
+LB = "H16"
+LE = "H17"
+LH = "H18"
+LK = "H19"
+LN = "H20"
+8G = "H21"
+8U = "H22"
+1P = "H23"
+1T = "H24"
+LQ = "H25"
+0G = "H26"
+; immo augm. réévaluation
+KB = "J7"
+KE = "J8"
+KH = "J9"
+KK = "J10"
+KN = "J11"
+KQ = "J12"
+KT = "J13"
+KW = "J14"
+KZ = "J15"
+LC = "J16"
+LF = "J17"
+LI = "J18"
+LL = "J19"
+LO = "J20"
+8M = "J21"
+8V = "J22"
+1R = "J23"
+1U = "J24"
+LR = "J25"
+0H = "J26"
+; immo augm. acqui.
+KC = "L7"
+KF = "L8"
+KI = "L9"
+KL = "L10"
+KO = "L11"
+KR = "L12"
+KU = "L13"
+KX = "L14"
+LA = "L15"
+LD = "L16"
+LG = "L17"
+LJ = "L18"
+LM = "L19"
+LP = "L20"
+8T = "L21"
+8W = "L22"
+1S = "L23"
+1V = "L24"
+LS = "L25"
+0J = "L26"
+; dimin. par vir.
+NL = "F29"
+N0 = "F30"
+IP = "F31"
+IQ = "F32"
+IR = "F33"
+IS = "F34"
+IT = "F35"
+IU = "F36"
+IV = "F37"
+IW = "F38"
+IX = "F39"
+MY = "F40"
+NC = "F41"
+NN = "F42"
+IZ = "F43"
+I0 = "F44"
+I1 = "F45"
+I2 = "F46"
+NM = "F47"
+NP = "F48"
+; dimin. par cession.
+LT = "H29"
+LV = "H30"
+LX = "H31"
+MA = "H32"
+MD = "H33"
+MG = "H34"
+MJ = "H35"
+MM = "H36"
+MP = "H37"
+MS = "H38"
+MV = "H39"
+MZ = "H40"
+ND = "H41"
+NG = "H42"
+0U = "H43"
+0X = "H44"
+2B = "H45"
+2E = "H46"
+NJ = "H47"
+0K = "H48"
+; immo. fin exercice
+LU = "J29"
+LW = "J30"
+LY = "J31"
+MB = "J32"
+ME = "J33"
+MH = "J34"
+MK = "J35"
+MN = "J36"
+MQ = "J37"
+MT = "J38"
+MW = "J39"
+NA = "J40"
+NE = "J41"
+NH = "J42"
+0V = "J43"
+0Y = "J44"
+2C = "J45"
+2F = "J46"
+NK = "J47"
+0L = "J48"
+1W = "L29"
+1X = "L30"
+LZ = "L31"
+MC = "L32"
+MF = "L33"
+MI = "L34"
+ML = "L35"
+MO = "L36"
+MR = "L37"
+MU = "L38"
+MX = "L39"
+NB = "L40"
+NF = "L41"
+NI = "L42"
+0W = "L43"
+0Z = "L44"
+2D = "L45"
+2G = "L46"
+2H = "L47"
+0M = "L48"
+
+; 2055 - Annexe 6 Ammortissements
+[5]
+; ammo début exo
+PA = "G7"
+PE = "G8"
+PI = "G9"
+PM = "G10"
+PR = "G11"
+PV = "G12"
+PZ = "G13"
+QD = "G14"
+QH = "G15"
+QL = "G16"
+QP = "G17"
+QU = "G18"
+0N = "G19"
+; ammo augm. dotations
+PB = "I7"
+PF = "I8"
+PJ = "I9"
+PN = "I10"
+PS = "I11"
+PW = "I12"
+QA = "I13"
+QE = "I14"
+QI = "I15"
+QM = "I16"
+QR = "I17"
+QV = "I18"
+0P = "I19"
+; ammo dimin.
+PC = "K7"
+PG = "K8"
+PK = "K9"
+PO = "K10"
+PT = "K11"
+PX = "K12"
+QB = "K13"
+QF = "K14"
+QJ = "K15"
+QN = "K16"
+QS = "K17"
+QW = "K18"
+0Q = "K19"
+; ammo mt fin exo
+PD = "M7"
+PH = "M8"
+PL = "M9"
+PQ = "M10"
+PU = "M11"
+PY = "M12"
+QC = "M13"
+QG = "M14"
+QK = "M15"
+QO = "M16"
+QT = "M17"
+QX = "M18"
+0R = "M19"
+; cadre B amort. linéaires
+QY = "E22"
+QZ = "E23"
+RA = "E24"
+RD = "E25"
+RG = "E26"
+RJ = "E27"
+RM = "E28"
+RP = "E29"
+RS = "E30"
+RV = "E31"
+RY = "E32"
+SB = "E33"
+SG = "E34"
+; cadre B amort. deg.
+2J = "G22"
+2N = "G23"
+RB = "G24"
+RE = "G25"
+RH = "G26"
+RK = "G27"
+RN = "G28"
+RQ = "G29"
+RT = "G30"
+RW = "G31"
+RZ = "G32"
+SC = "G33"
+SH = "G34"
+; cadre B amort. exceptio.
+2K = "I22"
+2P = "I23"
+RC = "I24"
+RF = "I25"
+RI = "I26"
+RL = "I27"
+RO = "I28"
+RR = "I29"
+RU = "I30"
+RX = "I31"
+SA = "I32"
+SD = "I33"
+SJ = "I34"
+; cadre C dotations
+2L = "K22"
+2R = "K23"
+2T = "K24"
+2V = "K25"
+2X = "K26"
+2Z = "K27"
+3B = "K28"
+3D = "K29"
+3F = "K30"
+3H = "K31"
+3K = "K32"
+SE = "K33"
+SK = "K34"
+; cadre C reprises
+2M = "M22"
+2S = "M23"
+2U = "M24"
+2W = "M25"
+2Y = "M26"
+3A = "M27"
+3C = "M28"
+3E = "M29"
+3G = "M30"
+3J = "M31"
+3L = "M32"
+SF = "M33"
+SL = "M34"
+; cadre D
+SM0 = "G37"
+SP0 = "G38"
+SI = "I37"
+SO = "I38"
+SM = "K37"
+SP = "K38"
+SN = "M37"
+SR = "M38"
+
+; 2056 - Provisions
+[6]
+; début exo.
+3T = "F5"
+3U = "F6"
+3V = "F7"
+3W = "F8"
+3X = "F9"
+IA = "F10"
+IE = "F11"
+IJ = "F12"
+3Y = "F13"
+3Z = "F14"
+4A = "F15"
+4E = "F16"
+4J = "F17"
+4N = "F18"
+4T = "F19"
+4X = "F20"
+5B = "F21"
+5F = "F22"
+5L = "F23"
+5R = "F24"
+5V = "F25"
+5Z = "F26"
+6A = "F27"
+6E = "F28"
+O2 = "F29"
+9U = "F30"
+06 = "F31"
+6N = "F32"
+6T = "F33"
+6X = "F34"
+7B = "F35"
+7C = "F36"
+; augm. début exo
+TA = "H5"
+TD = "H6"
+TG = "H7"
+TJ = "H8"
+TM = "H9"
+IB = "H10"
+IF = "H11"
+IK = "H12"
+TP = "H13"
+TS = "H14"
+4B = "H15"
+4F = "H16"
+4K = "H17"
+4P = "H18"
+4U = "H19"
+4Y = "H20"
+5C = "H21"
+5H = "H22"
+5M = "H23"
+5S = "H24"
+5W = "H25"
+TV = "H26"
+6B = "H27"
+6F = "H28"
+03 = "H29"
+9V = "H30"
+07 = "H31"
+6P = "H32"
+6U = "H33"
+6Y = "H34"
+TY = "H35"
+UB = "H36"
+UE = "H37"
+UG = "H38"
+UJ = "H39"
+; dimin. reprise début ex.
+TB = "J5"
+TE = "J6"
+TH = "J7"
+TK = "J8"
+TN = "J9"
+IC = "J10"
+IG = "J11"
+IL = "J12"
+TQ = "J13"
+TT = "J14"
+4C = "J15"
+4G = "J16"
+4L = "J17"
+4R = "J18"
+4V = "J19"
+4Z = "J20"
+5D = "J21"
+5J = "J22"
+5N = "J23"
+5T = "J24"
+5X = "J25"
+TW = "J26"
+6C = "J27"
+6G = "J28"
+04 = "J29"
+9W = "J30"
+08 = "J31"
+6R = "J32"
+6V = "J33"
+6Z = "J34"
+TZ = "J35"
+UC = "J36"
+UF = "J37"
+UH = "J38"
+UK = "J39"
+; montant fin ex.
+TC = "L5"
+TF = "L6"
+TI = "L7"
+TL = "L8"
+TO = "L9"
+ID = "L10"
+IH = "L11"
+IM = "L12"
+TR = "L13"
+TU = "L14"
+4D = "L15"
+4H = "L16"
+4M = "L17"
+4S = "L18"
+4W = "L19"
+5A = "L20"
+5E = "L21"
+5K = "L22"
+5P = "L23"
+5U = "L24"
+5Y = "L25"
+TX = "L26"
+6D = "L27"
+6H = "L28"
+05 = "L29"
+9X = "L30"
+09 = "L31"
+6S = "L32"
+6W = "L33"
+7A = "L34"
+UA = "L35"
+UD = "L36"
+10 = "L40"
+
+;2057
+[7]
+; cadre A mont. bruts
+UL = "I6"
+UP = "I7"
+UT = "I8"
+VA = "I9"
+UX = "I10"
+UQ = "G11"
+UU = "I11"
+UY = "I12"
+UZ = "I13"
+VM = "I14"
+VB = "I15"
+VN = "I16"
+VP = "I17"
+VC = "I18"
+VR = "I19"
+VS = "I20"
+VT = "I21"
+VD = "I22"
+VE = "I23"
+VF = "I24"
+; cadre A à 1 an maxi
+UM = "L6"
+UR = "L7"
+UV = "L8"
+VA1 = "L9"
+UX1 = "L10"
+UU1 = "L11"
+UY1 = "L12"
+UZ1 = "L13"
+VM1 = "L14"
+VB1 = "L15"
+VN1 = "L16"
+VP1 = "L17"
+VC1 = "L18"
+VR1 = "L19"
+VS1 = "L20"
+VU = "L21"
+VD1 = "L22"
+VE1 = "L23"
+VF1 = "L24"
+; cadre A à + d'un an
+UN = "L6"
+US = "L7"
+UW = "L8"
+VA2 = "L9"
+UX2 = "L10"
+UU2 = "L11"
+UY2 = "L12"
+UZ2 = "L13"
+VM2 = "L14"
+VB2 = "L15"
+VN2 = "L16"
+VP2 = "L17"
+VC2 = "L18"
+VR2 = "L19"
+VS2 = "L20"
+VV = "L21"
+VD2 = "L22"
+VE2 = "L23"
+VF2 = "L24"
+; cadre B mont brut
+7Y = "G26"
+7Z = "G27"
+VG = "G28"
+VH = "G29"
+8A = "G30"
+8B = "G31"
+8C = "G32"
+8D = "G33"
+8E = "G34"
+VW = "G35"
+VX = "G36"
+VQ = "G37"
+8J = "G38"
+VI = "G39"
+8K = "G40"
+SZ = "G41"
+8L = "G42"
+VY = "G43"
+VJ = "G44"
+VK = "G45"
+; cadre B à 1 an
+7Y1 = "J26"
+7Z1 = "J27"
+VG1 = "J28"
+VH1 = "J29"
+8A1 = "J30"
+8B1 = "J31"
+8C1 = "J32"
+8D1 = "J33"
+8E1 = "J34"
+VW1 = "J35"
+VX1 = "J36"
+VQ1 = "J37"
+8J1 = "J38"
+VI1 = "J39"
+8K1 = "J40"
+SZ1 = "J41"
+8L1 = "J42"
+VZ = "J43"
+; cadre B + d'un an
+7Y2 = "L26"
+7Z2 = "L27"
+VG2 = "L28"
+VH2 = "L29"
+8A2 = "L30"
+8B2 = "L31"
+8C2 = "L32"
+8D2 = "L33"
+8E2 = "L34"
+VW2 = "L35"
+VX2 = "L36"
+VQ2 = "L37"
+8J2 = "L38"
+VI2 = "L39"
+8K2 = "L40"
+SZ2 = "L41"
+8L2 = "L42"
+VZ1 = "L43"
+; cadre B + de 5 ans
+7Y3 = "N26"
+7Z3 = "N27"
+VG3 = "N28"
+VH3 = "N29"
+8A3 = "N30"
+8B3 = "N31"
+8C3 = "N32"
+8D3 = "N33"
+8E3 = "N34"
+VW3 = "N35"
+VX3 = "N36"
+VQ3 = "N37"
+8J3 = "N38"
+VI3 = "N39"
+8K3 = "N40"
+SZ3 = "N41"
+8L3 = "N42"
+VZ2 = "N43"
+VL = "N44"
+
+;2058C
+[8]
+; aff. résultat
+0C = "T6"
+0D = "T7"
+0E = "T10"
+0F = "T11"
+ZB = "T12"
+ZC = "T13"
+ZD = "T14"
+A5 = "T15"
+ZE = "T16"
+ZF = "T17"
+ZG = "T18"
+ZH = "T19"
+; rens. divers N
+YQ = "O22"
+YR = "O23"
+YS = "O24"
+YT = "O25"
+XQ = "O26"
+YU = "O27"
+SS = "O28"
+YV = "O29"
+ST = "O30"
+ZJ = "O31"
+YW = "O32"
+ZS = "J33"
+9Z = "O33"
+YX = "O35"
+YY = "O36"
+YZ = "O37"
+ZA = "O38"
+0B = "O39"
+0S = "O40"
+; rens. divers N-1
+YQ1 = "S22"
+YR1 = "S23"
+YS1 = "S24"
+YT1 = "S25"
+XQ1 = "S26"
+YU1 = "S27"
+SS1 = "S28"
+YV1 = "S29"
+ST1 = "S30"
+ZJ1 = "S31"
+YW1 = "S32"
+9Z1 = "S33"
+YX1 = "S35"
+YY1 = "S36"
+YZ1 = "S37"
+ZA1 = "S38"
+0B1 = "S39"
+0S1 = "S40"
+; groupe
+JA = "G41"
+JD = "G42"
+JB = "L41"
+JE = "L42"
+JC = "T41"
+JF = "T42"
+JG = "I43"
+XP = "I44"
+JH = "L43"
+JJ = "Q43"
+YP = "P45"
+ZK = "P46"
+ZR = "T47"
\ No newline at end of file
diff --git a/library/Scores/Finance/Liasse/models/liasse_2050.xls b/library/Scores/Finance/Liasse/models/liasse_2050.xls
new file mode 100644
index 0000000..c41e271
Binary files /dev/null and b/library/Scores/Finance/Liasse/models/liasse_2050.xls differ
diff --git a/library/Scores/Finance/Liasse/models/liasse_2050_ori.xls b/library/Scores/Finance/Liasse/models/liasse_2050_ori.xls
new file mode 100644
index 0000000..3b094b2
Binary files /dev/null and b/library/Scores/Finance/Liasse/models/liasse_2050_ori.xls differ
diff --git a/library/Scores/Finance/Ratios/Data.php b/library/Scores/Finance/Ratios/Data.php
new file mode 100644
index 0000000..089582e
--- /dev/null
+++ b/library/Scores/Finance/Ratios/Data.php
@@ -0,0 +1,362 @@
+RatiosSecteur->item)>0){
+ foreach($ratios->RatiosSecteur->item as $item){
+ foreach($item->liste->item as $ratiosItem){
+ $this->ratiosSecteur[$item->annee][$ratiosItem->id] = $ratiosItem->val;
+ }
+ }
+ }
+ //Orgnaisation des informations des ratios
+ foreach($ratios->RatiosInfos->item as $item){ //@todo : protection
+ $this->ratiosInfos[$item->id] = $item;
+ }
+
+ //Orgnaisation RatiosEntrep et RatiosEntrepEvol
+ if (count($ratios->BilansInfos->item)>0){
+ foreach($ratios->BilansInfos->item as $item)
+ {
+ $typeBilan = $item->typeBilan;
+ if ($typeBilan == 'S') $typeBilan = 'N';
+
+ $this->bilansInfo[$typeBilan][$item->dateCloture] = $item;
+ foreach($item->RatiosEntrep->item as $ratiosItem){
+ $this->ratiosEntrep[$typeBilan][$item->dateCloture][$ratiosItem->id] = $ratiosItem->val;
+ }
+ foreach($item->RatiosEntrepEvol->item as $ratiosItem){
+ $this->ratiosEntrepEvol[$typeBilan][$item->dateCloture][$ratiosItem->id] = $ratiosItem->val;
+ }
+ //Comptage de bilans
+ $this->{'nbBilan'.$typeBilan}++;
+ }
+ }
+ }
+
+ public function getNbBilan($type)
+ {
+ return $this->{'nbBilan'.$type};
+ }
+
+ /**
+ * Renvoi le ratio de l'entité
+ * @param string $type
+ * @param string $dateCloture
+ * @param string $id
+ */
+ function dRatio($type, $dateCloture, $id){
+ $ratio = $this->ratiosEntrep[$type][$dateCloture][$id];
+ $return = '';
+ $formatRatio = TRUE;
+ if ($ratio=='NS' || $ratio==0) {
+ $return.= 'NS';
+ $formatRatio = FALSE;
+ }elseif(substr($ratio,0,1)=='<' ){
+ $return.= '< ';
+ $ratio = substr($ratio,1)*1;
+ }elseif(substr($ratio,0,1)=='>'){
+ $return.= '> ';
+ $ratio = substr($ratio,1)*1;
+ }elseif($ratio==NULL){
+ $return.= '-';
+ $formatRatio = FALSE;
+ }
+
+ if($formatRatio == TRUE) {
+ if ( ($this->ratiosInfos[$id]->unite=='EUR') && ((abs($ratio)/1000)>0) ){
+ $return.= number_format($ratio/1000, 0, '', ' ').' K€';
+ }elseif (($this->ratiosInfos[$id]->unite=='EUR') && ((abs($ratio)/1000)<0)) {
+ $return.= number_format($ratio, 0, '', ' ').' €';
+ }elseif (($this->ratiosInfos[$id]->unite=='Jours')) {
+ $return.= number_format($ratio, 0, '', ' ').' '.$this->ratiosInfos[$id]->unite;
+ }elseif (($this->ratiosInfos[$id]->unite=='AN')) {
+ $return.= round($ratio, 2).' '.$this->ratiosInfos[$id]->unite;
+ }elseif (($this->ratiosInfos[$id]->unite=='%')) {
+ $return.= round($ratio).' '.$this->ratiosInfos[$id]->unite;
+ }else{
+ $return.= $ratio.' '.$this->ratiosInfos[$id]->unite;
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * Renvoi le ratio secteur
+ * @param string $dateCloture
+ * @param string $id
+ */
+ function dSecteur($dateCloture, $id){
+ $ratio = $this->ratiosSecteur[substr($dateCloture,0,4)][$id];
+ $return = '';
+ $formatRatio = TRUE;
+ if ($ratio=='NS') {
+ $return.= 'NS';
+ $formatRatio = FALSE;
+ }elseif(substr($ratio,0,1)=='<' ){
+ $return.= '< ';
+ $ratio = substr($ratio,1)*1;
+ }elseif(substr($ratio,0,1)=='>'){
+ $return.= '> ';
+ $ratio = substr($ratio,1)*1;
+ }elseif($ratio==NULL){
+ $return.= '-';
+ $formatRatio = FALSE;
+ }
+
+ if($formatRatio == TRUE) {
+ if ( ($this->ratiosInfos[$id]->unite=='EUR') && ((abs($ratio)/1000)>0) ){
+ $return.= number_format($ratio/1000, 0, '', ' ').' K€';
+ }elseif (($this->ratiosInfos[$id]->unite=='EUR') && ((abs($ratio)/1000)<0)) {
+ $return.= number_format($ratio, 0, '', ' ').' €';
+ }elseif (($this->ratiosInfos[$id]->unite=='Jours')) {
+ $return.= number_format($ratio, 0, '', ' ').' '.$this->ratiosInfos[$id]->unite;
+ }elseif (($this->ratiosInfos[$id]->unite=='AN')) {
+ $return.= round($ratio, 2).' '.$this->ratiosInfos[$id]->unite;
+ }elseif (($this->ratiosInfos[$id]->unite=='%')) {
+ $return.= round($ratio).' '.$this->ratiosInfos[$id]->unite;
+ }else{
+ $return.= $ratio.' '.$this->ratiosInfos[$id]->unite;
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * Renvoi la position de l'entité en comparant son ratio avec le ratio secteur
+ * Enter description here ...
+ * @param string $type
+ * @param string $dateCloture
+ * @param string $id
+ * @param string $compare
+ * @return string
+ */
+ function dPosition($type, $dateCloture, $id, $compare)
+ {
+ $ratioS = $this->ratiosSecteur[substr($dateCloture,0,4)][$id];
+ $ratioE = $this->ratiosEntrep[$type][$dateCloture][$id];
+ $ecart = 1/100;
+
+ if( $ratioS=='NS' || $ratioE=='NS' || $ratioS==NULL || $ratioE==NULL){
+ $return = '-';
+ }elseif($compare=='>'){
+ if( $ratioE+$ecart > $ratioS ){
+ $return = '';
+ }elseif( ($ratioS-($ratioS*$ecart))<$ratioE && ($ratioS+($ratioS*$ecart))>$ratioE){
+ $return = '-';
+ }else{
+ $return = '';
+ }
+ }elseif($compare=='<'){
+ if($ratioE < $ratioS){
+ $return = '';
+ }elseif( ($ratioS-($ratioS*$ecart))<$ratioE && ($ratioS+($ratioS*$ecart))>$ratioE){
+ $return = '-';
+ }else{
+ $return = '';
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * Affiche l'évolution d'un ratio.
+ * @param string $type
+ * @param string $dateCloture
+ * @param string $id
+ */
+ function dEvol($type, $dateCloture, $id){
+ $ratio = $this->ratiosEntrepEvol[$type][$dateCloture][$id];
+ if ($ratio=='NS') {
+ return 'NS';
+ }elseif($ratio==NULL){
+ return '-';
+ }else{
+ return $ratio.' %';
+ }
+ }
+
+ /**
+ * Enter description here ...
+ * @param unknown_type $type
+ * @param unknown_type $dateCloture
+ * @param unknown_type $id
+ * @param unknown_type $totalRatio
+ * @return string
+ */
+ function dTotal($type, $dateCloture, $id, $totalRatio)
+ {
+ $ratio = isset($this->ratiosEntrep[$type][$dateCloture][$id]) ?
+ $this->ratiosEntrep[$type][$dateCloture][$id] : 0;
+ $total = isset($this->ratiosEntrep[$type][$dateCloture][$totalRatio]) ?
+ $this->ratiosEntrep[$type][$dateCloture][$totalRatio] : 0;
+ if($total!=0){
+ return number_format($ratio*100/$total, 2);
+ }else{
+ return '-';
+ }
+ }
+
+ /**
+ * Retourne le tableau pour l'affichage des graphiques d'évolution
+ * @param string $type
+ * @param string $id
+ */
+ function dGraph($type, $id)
+ {
+ $evol = array();
+ $bilansInfo = $this->bilansInfo[$type];
+ ksort($bilansInfo);
+ foreach($bilansInfo as $item) {
+ $dateCloture = $item->dateCloture;
+ $div = 1;
+ $ratioE = $this->ratiosEntrep[$type][$dateCloture][$id];
+ $ratioS = $this->ratiosSecteur[substr($dateCloture,0,4)][$id];
+ if ( ($ratiosInfos[$nRatio]['unite']=='EUR') && ((abs($ratioE)/1000)>0) ){
+ $unite = 'KEURO';
+ $div = 1000;
+ }else{
+ $unite = $this->ratiosInfos[$id]->unite;
+ }
+ //Données pour les graphiques évolutions
+ $data[] = array(
+ 'date' => $dateCloture,
+ 'entreprise' => (($ratioE!='NS') ? $ratioE/$div : 0 ),
+ 'secteur' => (($ratioS!='NS') ? $ratioS/$div : 0 ),
+ );
+ }
+ $evol = array('data' => $data, 'unite' => $unite);
+ return $evol;
+ }
+
+ /**
+ * Affiche le pourcentage d'un ratio par rapport au total.
+ * @param string $type
+ * @param string $dateCloture
+ * @param string $id
+ * @param string $totalRatio
+ * @return mixed
+ */
+ function dPercent($type, $dateCloture, $id, $totalRatio){
+ $ratio = $this->ratiosEntrep[$type][$dateCloture][$id];
+ $totalRatio = $this->ratiosEntrep[$type][$dateCloture][$totalRatio];
+ if ($ratio=='NS') {
+ $return = 'NS';
+ }elseif($ratio==NULL){
+ $return = '-';
+ }else {
+ if ($totalRatio!=0 && $totalRatio!='NS'){
+ $percent = $ratio*100/$totalRatio;
+ }else{
+ $percent = 0;
+ }
+ if ($percent>=0 && $percent<10){
+ $return = round($percent, 1);
+ } elseif ($percent>-10 && $percent<0) {
+ $return = round($percent, 1);
+ } else {
+ $return = round($percent, 0);
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * Retourne le pourcentage d'un ratio par rapport au total pour les graphiques
+ * @param string $type
+ * @param string $dateCloture
+ * @param string $id
+ * @param string $totalRatio
+ */
+ function graphPercent($type, $dateCloture, $id, $totalRatio){
+ $ratio = isset($this->ratiosEntrep[$type][$dateCloture][$id]) ?
+ $this->ratiosEntrep[$type][$dateCloture][$id] : 0;
+ $totalRatio = $this->ratiosEntrep[$type][$dateCloture][$totalRatio];
+ if ( ($ratio!='NS' && $ratio!=NULL) && ($totalRatio!=0 && $totalRatio!='NS')){
+ return $ratio*100/$totalRatio;
+ }else{
+ return 0;
+ }
+ }
+
+ /**
+ * Formatte le commentaire pour l'afficher dans l'infobulle.
+ * @param string $nRatios
+ * Identifiant du ratio
+ * @return string
+ */
+ function wrapComment($nRatio){
+ $text = $this->ratiosInfos[$nRatio]->commentaires;
+ $newtext = htmlentities($text, null, 'utf-8');
+ $newtext = nl2br($newtext);
+ return $newtext;
+ }
+
+ public function getBilansInfo($type)
+ {
+ return $this->bilansInfo[$type];
+ }
+
+ public function getRatiosInfos($id) {
+ return $this->ratiosInfos[$id];
+ }
+
+ public function getRatiosEntrep($type, $dateCloture, $id) {
+ return $this->ratiosEntrep[$type][$dateCloture][$id];
+ }
+
+ public function getRatiosEntrepEvol($type, $dateCloture, $id) {
+ return $this->ratiosEntrepEvol[$type][$dateCloture][$id];
+ }
+
+ public function getRatiosSecteur($annee, $id) {
+ return $this->ratiosSecteur[substr($annee,0,4)][$id];
+ }
+
+ public function getTableRatiosInfos()
+ {
+ return $this->ratiosInfos;
+ }
+
+ public function getTableRatiosSecteur()
+ {
+ return $this->ratiosSecteur;
+ }
+
+ public function getTableRatiosEntrep($type)
+ {
+ if (array_key_exists($type, $this->ratiosEntrep)){
+ return $this->ratiosEntrep[$type];
+ }
+ return false;
+ }
+
+ public function getTableRatiosEntrepEvol($type)
+ {
+ if (array_key_exists($type, $this->ratiosEntrepEvol)){
+ return $this->ratiosEntrepEvol[$type];
+ }
+ return false;
+ }
+
+ private function ignoreType($type, $typeDelete) {
+ foreach ($typeDelete as $t) {
+ if ($t == $type) return (false);
+ }
+ return (true);
+ }
+}
\ No newline at end of file
diff --git a/library/Scores/Finance/Ratios/Graph.php b/library/Scores/Finance/Ratios/Graph.php
new file mode 100644
index 0000000..49a5fc3
--- /dev/null
+++ b/library/Scores/Finance/Ratios/Graph.php
@@ -0,0 +1,384 @@
+path = $c->profil->path->pages . '/imgcache/';
+ $this->siret = $siret;
+ $this->id = $id;
+ }
+
+ /**
+ * Enregistre le graphique bilan passif sous forme d'image.
+ * @param array $data
+ * Tableau structuré des données
+ * @param string $filename
+ * Le nom de fichier généré
+ * @return string
+ * Retourne un message d'erreur ou le code HTML d'affichage.
+ */
+ public function bilansgraphpassif($data, $typeBilan, $dateCloture)
+ {
+ $file = 'bilansgraphpassif-'.$this->siret.'-'.$this->id.'-'.$typeBilan.$dateCloture.'.png';
+ $cache = new Cache();
+ if( $cache->exist($this->path.$file) ){
+ $return = $file;
+ } else {
+ $w = 665;
+ $h = 210;
+ $x = round($w/2);
+ $y = round($h/2);
+ $radius = 90;
+ $c = new PieChart($w, $h);
+ $labels = array('Fonds propres',
+ 'Provisions Risques',
+ 'Compte Courant',
+ 'Dettes Financières',
+ 'Dettes Fournisseurs',
+ 'Dettes fiscales',
+ 'Autres Dettes',
+ 'Trésorerie Passive');
+ $textBoxObj = $c->addTitle("Composition du passif", "timesbi.ttf", 15);
+ $c->setPieSize($x, $y, $radius);
+ $c->setLabelLayout(SideLayout);
+ $t = $c->setLabelStyle();
+ $t->setBackground(SameAsMainColor, Transparent, glassEffect());
+ $t->setRoundedCorners(5);
+ $c->setLineColor(SameAsMainColor, 0x000000);
+ $c->setStartAngle(135);
+ $c->setLabelFormat("<*block,valign=absmiddle*>{label} <*font=timesbi.ttf,size=0*>({percent|0}%)");
+ $c->setData($data, $labels);
+ $c->set3D(20);
+ if($c->makeChart($this->path.$file) === TRUE){
+ $return = '';
+ }else{
+ $return = false;
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * Enregistre le graphique bilan SIG sous forme d'image.
+ */
+ public function bilansgraphsig($data, $typeBilan, $dateCloture)
+ {
+ $file = 'bilansgraphsig-'.$this->siret.'-'.$this->id.'-'.$typeBilan.$dateCloture.'.png';
+ $cache = new Cache();
+ if( $cache->exist($this->path.$file) ){
+ $return = $file;
+ } else {
+ $w = 665;
+ $h = 210;
+ $x = round($w/2);
+ $y = round($h/2);
+ $radius=70;
+ $c = new PieChart($w, $h);
+ $labels = array('Achats de marchandises.',
+ 'Autres achats externes',
+ 'Charges de fonctionnement',
+ 'Amortissement et provisions',
+ 'Perte financière',
+ 'Impôts sociétés',
+ 'RÉSULTAT NET',
+ );
+ $textBoxObj = $c->addTitle("Solde Intermédiaire de Gestion", "timesbi.ttf", 15);
+ $c->setPieSize($x, $y, $radius);
+ $c->setLabelLayout(SideLayout);
+ $t = $c->setLabelStyle();
+ $t->setBackground(SameAsMainColor, Transparent, glassEffect());
+ $t->setRoundedCorners(5);
+ $c->setLineColor(SameAsMainColor, 0x000000);
+ $c->setLabelFormat("<*block,valign=absmiddle*>{label} <*font=arial.ttf,size=0*>({percent|0}%)");
+ $c->setStartAngle(135);
+ $c->setData($data, $labels);
+ $c->set3D(20);
+
+ if($c->makeChart($this->path.$file) === TRUE){
+ $return = $file;
+ }else{
+ $return = false;
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * Enregistre le graphique bilan actif sous forme d'image.
+ * @param array $data
+ * Tableau structuré des données
+ * @return mixed
+ */
+ public function bilansgraphactif($data, $typeBilan, $dateCloture)
+ {
+ $file = 'bilansgraphactif-'.$this->siret.'-'.$this->id.'-'.$typeBilan.$dateCloture.'.png';
+ $cache = new Cache();
+ if( $cache->exist($this->path.$file) ){
+ $return = $file;
+ } else {
+ $w = 665;
+ $h = 210;
+ $x = round($w/2);
+ $y = round($h/2);
+ $radius = 90;
+ $c = new PieChart($w, $h);
+ $labels = array('Immo. incorporelles',
+ 'Immo. corporelles',
+ 'Immo. financières',
+ 'Stock et encours',
+ 'Créances Clients',
+ 'Autres créances',
+ 'Trésorerie Active');
+ $textBoxObj = $c->addTitle("Composition de l'actif", "timesbi.ttf", 15);
+ $c->setPieSize($x, $y, $radius);
+ $c->setLabelLayout(SideLayout);
+ $t = $c->setLabelStyle();
+ $t->setBackground(SameAsMainColor, Transparent, glassEffect());
+ $t->setRoundedCorners(5);
+ # Set the border color of the sector the same color as the fill color. Set the line # color of the join line to black (0x0)
+ $c->setLineColor(SameAsMainColor, 0x000000);
+ $c->setStartAngle(135);
+ $c->setLabelFormat("<*block,valign=absmiddle*>{label} <*font=timesbi.ttf,size=0*>({percent|0}%)");
+ $c->setData($data, $labels);
+ $c->set3D(20);
+ if($c->makeChart($this->path.$file) === TRUE){
+ $return = $file;
+ }else{
+ $return = false;
+ }
+ }
+ return $return;
+ }
+
+
+ public function ratiosgraph($ratio, $data)
+ {
+ $file = 'ratiosgraph-'.$this->siret.'-'.$this->id.'-'.$ratio.'.png';
+ $cache = new Cache();
+ if( $cache->exist($this->path.$file) ){
+ $return = $file;
+ }else{
+ if(count($data)<=1){
+ $return = 0;
+ }else{
+ $labelsX = array();
+ $labelsY = array();
+ $dataX1 = array();
+ $dataX2 = array();
+ foreach($data['data'] as $value){
+ $dataX1[] = $value['entreprise'];
+ $dataX2[] = $value['secteur'];
+ $labelsX[] = substr($value['date'],0,4);
+ }
+ $i=-100; while($i>100){
+ $labelsY[] = $i;
+ }
+ $c = new XYChart(350, 250);
+ $c->setPlotArea(70, 10, 280, 200);
+ $c->yAxis->setTitle($data['unite']);
+ $c->xAxis->setTitle("Années");
+ $c->xAxis->setWidth(2);
+ $c->yAxis->setWidth(2);
+ $legendObj = $c->addLegend(50, 10, false, "times.ttf", 9);
+ $legendObj->setBackground(Transparent);
+ $c->addLineLayer($dataX1, 0x0000ff, "Entreprise");
+ $c->addLineLayer($dataX2, 0x008C00, "Secteur");
+ $c->yAxis->setLabels($labelsY);
+ $c->yAxis->setLabelStep(10);
+ $c->xAxis->setLabels($labelsX);
+ if($c->makeChart($this->path.$file) === TRUE){
+ $return = $file;
+ }
+ else{ $return = FALSE;
+ }
+ }
+ }
+ return $return;
+ }
+
+ public function syntheseGraphEvol($data, $ratio, $unite)
+ {
+ $file = 'syntheseEvol-'.$this->siret.'-'.$this->id.'-'.$ratio.'.png';
+ $cache = new Cache();
+ if( $cache->exist($this->path.$file) ){
+ $return = $file;
+ } else {
+ $unite = !empty($unite) ? $unite : 'KEUROS';
+ $labelsX = array();
+ $labelsY = array();
+ $dataX = array();
+ if(count($data)<=1){
+ $return = 0;
+ } else {
+ foreach($data as $value){
+ $dataX[] = $value['value'];
+ $labelsX[] = substr($value['date'],0,4);
+ }
+ $i=-100;
+ while($i>100){
+ $labelsY[] = $i;
+ }
+ # Create a XYChart object of size 250 x 250 pixels
+ $c = new XYChart(400, 250);
+ $c->setPlotArea(70, 10, 280, 200);
+ $c->yAxis->setTitle($unite);
+ $c->xAxis->setTitle("Années");
+ $c->xAxis->setWidth(2);
+ $c->yAxis->setWidth(2);
+ $c->addLineLayer($dataX);
+ # Set the labels.
+ $c->yAxis->setLabels($labelsY);
+ $c->yAxis->setLabelStep(10);
+ $c->xAxis->setLabels($labelsX);
+ if($c->makeChart($this->path.$file) === TRUE){
+ $return = $file;
+ } else {
+ $return = false;
+ }
+ }
+ }
+ return $return;
+ }
+
+ public function syntheseGraphLineCompare($data, $typeBilan)
+ {
+ $file = 'synthese-linecompare-'.$this->siret.'-'.$this->id.'-'.$typeBilan.'.png';
+ $cache = new Cache();
+
+ if( $cache->exist($this->path.$file) ){
+ $return = $this->path.$file;
+ } else {
+ //Tri des données par date et par ordre croissant
+ foreach ($data as $key => $row) {
+ $date[$key] = $row['date'];
+ }
+ array_multisort($date, SORT_ASC, $data);
+
+ //Définition des valeurs pour le graph
+ $dataBFR = array();
+ $dataFR = array();
+ $dataCA = array();
+ $i=0;
+ //Parcourir les années
+ foreach($data as $item){
+ $anneeFin = substr($item['date'],0,4);
+ $moisFin = substr($item['date'],4,2);
+ $jourFin = substr($item['date'],6,2);
+ //Calcul de la date de début
+ $dateDebut = date("Ymd", mktime(0, 0, 0, $moisFin-$item['duree'], $jourFin, $anneeFin));
+ $anneeDebut = substr($dateDebut,0,4);
+ $moisDebut = substr($dateDebut,4,2);
+ $jourDebut = substr($dateDebut,6,2);
+ //Affectation des abscisses
+ $dataBFR['x'][$i] = $dataFR['x'][$i] = $dataCA['x'][$i] = $dataEBE['x'][$i] = chartTime((int)$anneeDebut, (int)$moisDebut, (int)$jourDebut);
+ $dataBFR['x'][$i+1] = $dataFR['x'][$i+1] = $dataCA['x'][$i+1] = $dataEBE['x'][$i+1] = chartTime((int)$anneeFin, (int)$moisFin, (int)$jourFin);
+ //Affectation des ordonnées
+ $dataBFR['y'][$i] = $dataBFR['y'][$i+1] = $item['r236'];
+ $dataFR['y'][$i] = $dataFR['y'][$i+1] = $item['r235'];
+ $dataCA['y'][$i] = $dataCA['y'][$i+1] = $item['r6'];
+ $dataEBE['y'][$i] = $dataEBE['y'][$i+1] = $item['r146'];
+ $i+=2;
+ }
+
+ $c = new XYChart(665, 350, 0xcccccc, 0x000000, 1);
+ $c->addTitle("Synthèse *", "timesbi.ttf", 15, 0x000000);
+ $c->addText(60, 320, "* Elements financier rapportés à 12 mois" );
+ $c->setPlotArea(70, 80, 500, 200, 0xffffff, -1, -1, 0xcccccc, 0xcccccc);
+ $c->yAxis->setTitle("KEUROS","timesbi.ttf",10);
+ $c->xAxis->setTitle( "<*block,valign=absmiddle*>Années<*/*>");
+ $c->xAxis->setWidth(2);
+ $c->yAxis->setWidth(2);
+
+ // Add a legend box at (55, 32) (top of the chart) with horizontal layout. Use 9 pts
+ // Arial Bold font. Set the background and border color to Transparent.
+ $legendObj = $c->addLegend(55, 30, false, "times.ttf", 9);
+ $legendObj->setBackground(Transparent);
+
+ // Add a blue (0000ff) step line layer to the chart and set the line width to 2 pixels
+ $layer1 = $c->addStepLineLayer($dataFR['y'], 0x0000ff, "FONDS DE ROULEMENT");
+ $layer1->setXData($dataFR['x']);
+ $layer1->setLineWidth(2);
+
+ // Add a red (ff0000) step line layer to the chart and set the line width to 2 pixels
+ $layer0 = $c->addStepLineLayer($dataBFR['y'], 0xff0000, "BESOIN EN FONDS DE ROULEMENT");
+ $layer0->setXData($dataBFR['x']);
+ $layer0->setLineWidth(2);
+
+ // Add a green (00ff00) step line layer to the chart and set the line width to 2 pixels
+ $layer2 = $c->addStepLineLayer($dataCA['y'], 0x00ff00, "CHIFFRE D'AFFAIRES");
+ $layer2->setXData($dataCA['x']);
+ $layer2->setLineWidth(2);
+
+ // Add a black (000000) step line layer style dash to the chart and set the line width to 2 pixels
+ $layer3 = $c->addStepLineLayer($dataEBE['y'], $c->dashLineColor(0x000000, DashLine), "EXCEDENT BRUT D'EXPLOITATION");
+ $layer3->setXData($dataEBE['x']);
+ $layer3->setLineWidth(2);
+
+ # If the FR line gets above the BFR line, color to area between the lines red (ff0000)
+ $c->addInterLineLayer($layer0->getLine(0), $layer1->getLine(0), 0xff0000, Transparent);
+
+ # If the FR line gets below the lower BFR line, color to area between the lines light green (8099ff99)
+ $c->addInterLineLayer($layer0->getLine(0), $layer1->getLine(0), Transparent, 0x8044ff44);
+
+ if($c->makeChart($this->path.$file) === TRUE){
+ $return = $this->path.$file;
+ }else{
+ $return = false;
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * Génére l'histogramme flux de trésorerie
+ * @param array $labels
+ * @param array $data
+ * @param string $typeBilan
+ * @return boolean|string
+ */
+ function flux($labels, $data, $typeBilan)
+ {
+ $couleur = array(0xff8080, 0x80ff80, 0x8080ff);
+ $file = 'flux-'.$this->siret.'-'.$this->id.'-'.$typeBilan.'.png';
+ $cache = new Cache();
+
+ if( $cache->exist($this->path.$file) ){
+ $return = $this->path.$file;
+ } else {
+ if (count($data)<=1) {
+ $return = 0;
+ } else {
+
+ $c = new XYChart(600, 300);
+ $c->setPlotArea(100, 70, 300, 200);
+ $legendObj = $c->addLegend(100, 20, false, "times.ttf", 9);
+ $legendObj->setBackground(Transparent);
+ $layer = $c->addBarLayer2(Stack);
+ $layer->setBorderColor(Transparent, softLighting(Left));
+ $c->xAxis->setLabels($labels);
+ $cptCouleur = 0;
+ foreach ( $data as $d ) {
+ $layer->addDataSet($d['values'], $couleur[$cptCouleur], $d['titre']);
+ $cptCouleur++;
+ }
+ $layer->setBarGap(0.2, 0);
+ $c->yAxis->setAutoScale(0.2);
+ if( $c->makeChart($this->path.$file) === TRUE ){
+ $return = $file;
+ }
+ else{ $return = FALSE;
+ }
+ }
+ }
+ return $return;
+ }
+
+}
\ No newline at end of file
diff --git a/library/Scores/Mobile/Detect.php b/library/Scores/Mobile/Detect.php
new file mode 100644
index 0000000..e599f17
--- /dev/null
+++ b/library/Scores/Mobile/Detect.php
@@ -0,0 +1,23 @@
+data->Ratios->siret = $infos->Identite->siret;
$this->data->Ratios->id = $infos->Identite->id;
@@ -280,7 +278,7 @@ class Scores_Partner_Report
$tabRatio = array( $ratio => $tabRatio[$ratio] );
}
- $ratiosData = new RatiosData($infos->Ratios);
+ $ratiosData = new Scores_Finance_Ratios_Data($infos->Ratios);
$nbBilanN = $ratiosData->getNbBilan('N');
$nbBilanC = $ratiosData->getNbBilan('C');
@@ -292,7 +290,7 @@ class Scores_Partner_Report
if ($nbBilanN!=0 || $nbBilanC!=0)
{
//Génération Graphique evolution
- $ratiosGraph = new RatiosGraph($this->siret, $this->id);
+ $ratiosGraph = new Scores_Finance_Ratios_Graph($siren);
$infosAnnee = $ratiosData->getBilansInfo($typeBilan);
$annees = array_keys($infosAnnee);
@@ -331,7 +329,7 @@ class Scores_Partner_Report
//Bilans
$typeBilan = 'N';
$this->data->Bilans->typeBilan = $typeBilan;
- $ratiosData = new RatiosData($infos->Ratios);
+ $ratiosData = new Scores_Finance_Ratios_Data($infos->Ratios);
$nbBilanN = $ratiosData->getNbBilan('N');
$nbBilanC = $ratiosData->getNbBilan('C');
@@ -348,7 +346,7 @@ class Scores_Partner_Report
$infosAnnee = $ratiosData->getBilansInfo($typeBilan);
$annees = array_keys($infosAnnee);
- $ratiosGraph = new RatiosGraph($this->siret, $this->id);
+ $ratiosGraph = new Scores_Finance_Ratios_Graph($siren);
$tabRatioActif = array(
'r59' => array( 'titre' => 'Actif Immobilisé Net', 'class' => 'subhead'),
@@ -546,7 +544,7 @@ class Scores_Partner_Report
}
//Formattage des données
- $ratiosData = new RatiosData($infos->Ratios);
+ $ratiosData = new Scores_Finance_Ratios_Data($infos->Ratios);
$nbBilanN = $ratiosData->getNbBilan('N');
$nbBilanC = $ratiosData->getNbBilan('C');
@@ -567,7 +565,7 @@ class Scores_Partner_Report
sort($annees);
if (count($annees)>1){
//Générer les différents graphiques d'évolutions
- $ratiosGraph = new RatiosGraph($this->siret, $this->id);
+ $ratiosGraph = new Scores_Finance_Ratios_Graph($siren);
$tabGraphEvol = array();
foreach($tabRatio as $idRatio => $infoRatio){
$dataGraphEvol = array();
diff --git a/library/Scores/Wkhtmltopdf.php b/library/Scores/Wkhtml/Pdf.php
similarity index 98%
rename from library/Scores/Wkhtmltopdf.php
rename to library/Scores/Wkhtml/Pdf.php
index 0688b23..377b1e8 100644
--- a/library/Scores/Wkhtmltopdf.php
+++ b/library/Scores/Wkhtml/Pdf.php
@@ -1,5 +1,5 @@
+#/ Represents a Financial Chart
+#/
+class FinanceChart extends MultiChart
+{
+ var $m_totalWidth = 0;
+ var $m_totalHeight = 0;
+ var $m_antiAlias = true;
+ var $m_logScale = false;
+ var $m_axisOnRight = true;
+
+ var $m_leftMargin = 40;
+ var $m_rightMargin = 40;
+ var $m_topMargin = 30;
+ var $m_bottomMargin = 35;
+
+ var $m_plotAreaBgColor = 0xffffff;
+ var $m_plotAreaBorder = 0x888888;
+ var $m_plotAreaGap = 2;
+
+ var $m_majorHGridColor = 0xdddddd;
+ var $m_minorHGridColor = 0xdddddd;
+ var $m_majorVGridColor = 0xdddddd;
+ var $m_minorVGridColor = 0xdddddd;
+
+ var $m_legendFont = "normal";
+ var $m_legendFontSize = 8;
+ var $m_legendFontColor = TextColor;
+ var $m_legendBgColor = 0x80cccccc;
+
+ var $m_yAxisFont = "normal";
+ var $m_yAxisFontSize = 8;
+ var $m_yAxisFontColor = TextColor;
+ var $m_yAxisMargin = 14;
+
+ var $m_xAxisFont = "normal";
+ var $m_xAxisFontSize = 8;
+ var $m_xAxisFontColor = TextColor;
+ var $m_xAxisFontAngle = 0;
+
+ var $m_timeStamps = null;
+ var $m_highData = null;
+ var $m_lowData = null;
+ var $m_openData = null;
+ var $m_closeData = null;
+ var $m_volData = null;
+ var $m_volUnit = "";
+ var $m_extraPoints = 0;
+
+ var $m_yearFormat = "{value|yyyy}";
+ var $m_firstMonthFormat = "<*font=bold*>{value|mmm yy}";
+ var $m_otherMonthFormat = "{value|mmm}";
+ var $m_firstDayFormat = "<*font=bold*>{value|d mmm}";
+ var $m_otherDayFormat = "{value|d}";
+ var $m_firstHourFormat = "<*font=bold*>{value|d mmm\nh:nna}";
+ var $m_otherHourFormat = "{value|h:nna}";
+ var $m_timeLabelSpacing = 50;
+
+ var $m_generalFormat = "P3";
+
+ var $m_toolTipMonthFormat = "[{xLabel|mmm yyyy}]";
+ var $m_toolTipDayFormat = "[{xLabel|mmm d, yyyy}]";
+ var $m_toolTipHourFormat = "[{xLabel|mmm d, yyyy hh:nn:ss}]";
+
+ var $m_mainChart = null;
+ var $m_currentChart = null;
+
+ #/
+ #/ Create a FinanceChart with a given width. The height will be automatically determined
+ #/ as the chart is built.
+ #/
+ #/ Width of the chart in pixels
+ function FinanceChart($width) {
+ $this->MultiChart($width, 1);
+ $this->m_totalWidth = $width;
+ $this->setMainChart($this);
+ }
+
+ #/
+ #/ Enable/Disable anti-alias. Enabling anti-alias makes the line smoother. Disabling
+ #/ anti-alias make the chart file size smaller, and so can be downloaded faster
+ #/ through the Internet. The default is to enable anti-alias.
+ #/
+ #/ True to enable anti-alias. False to disable anti-alias.
+ function enableAntiAlias($antiAlias) {
+ $this->m_antiAlias = $antiAlias;
+ }
+
+ #/
+ #/ Set the margins around the plot area.
+ #/
+ #/ The distance between the plot area and the chart left edge.
+ #/ The distance between the plot area and the chart top edge.
+ #/ The distance between the plot area and the chart right edge.
+ #/ The distance between the plot area and the chart bottom edge.
+ function setMargins($leftMargin, $topMargin, $rightMargin, $bottomMargin) {
+ $this->m_leftMargin = $leftMargin;
+ $this->m_rightMargin = $rightMargin;
+ $this->m_topMargin = $topMargin;
+ $this->m_bottomMargin = $bottomMargin;
+ }
+
+ #/
+ #/ Add a text title above the plot area. You may add multiple title above the plot area by
+ #/ calling this method multiple times.
+ #/
+ #/ The alignment with respect to the region that is on top of the
+ #/ plot area.
+ #/ The text to add.
+ #/ The TextBox object representing the text box above the plot area.
+ function addPlotAreaTitle($alignment, $text) {
+ $ret = $this->addText($this->m_leftMargin, 0, $text, "bold", 10, TextColor, $alignment);
+ $ret->setSize($this->m_totalWidth - $this->m_leftMargin - $this->m_rightMargin + 1,
+ $this->m_topMargin - 1);
+ $ret->setMargin(0);
+ return $ret;
+ }
+
+ #/
+ #/ Set the plot area style. The default is to use pale yellow 0xfffff0 as the background,
+ #/ and light grey 0xdddddd as the grid lines.
+ #/
+ #/ The plot area background color.
+ #/ Major horizontal grid color.
+ #/ Major vertical grid color.
+ #/ Minor horizontal grid color. In current version, minor
+ #/ horizontal grid is not used.
+ #/ Minor vertical grid color.
+ function setPlotAreaStyle($bgColor, $majorHGridColor, $majorVGridColor, $minorHGridColor,
+ $minorVGridColor) {
+ $this->m_plotAreaBgColor = $bgColor;
+ $this->m_majorHGridColor = $majorHGridColor;
+ $this->m_majorVGridColor = $majorVGridColor;
+ $this->m_minorHGridColor = $minorHGridColor;
+ $this->m_minorVGridColor = $minorVGridColor;
+ }
+
+ #/
+ #/ Set the plot area border style. The default is grey color (888888), with a gap
+ #/ of 2 pixels between charts.
+ #/
+ #/ The color of the border.
+ #/ The gap between two charts.
+ function setPlotAreaBorder($borderColor, $borderGap) {
+ $this->m_plotAreaBorder = $borderColor;
+ $this->m_plotAreaGap = $borderGap;
+ }
+
+ #/
+ #/ Set legend style. The default is Arial 8 pt black color, with light grey background.
+ #/
+ #/ The font of the legend text.
+ #/ The font size of the legend text in points.
+ #/ The color of the legend text.
+ #/ The background color of the legend box.
+ function setLegendStyle($font, $fontSize, $fontColor, $bgColor) {
+ $this->m_legendFont = $font;
+ $this->m_legendFontSize = $fontSize;
+ $this->m_legendFontColor = $fontColor;
+ $this->m_legendBgColor = $bgColor;
+ }
+
+ #/
+ #/ Set x-axis label style. The default is Arial 8 pt black color no rotation.
+ #/
+ #/ The font of the axis labels.
+ #/ The font size of the axis labels in points.
+ #/ The color of the axis labels.
+ #/ The rotation of the axis labels.
+ function setXAxisStyle($font, $fontSize, $fontColor, $fontAngle) {
+ $this->m_xAxisFont = $font;
+ $this->m_xAxisFontSize = $fontSize;
+ $this->m_xAxisFontColor = $fontColor;
+ $this->m_xAxisFontAngle = $fontAngle;
+ }
+
+ #/
+ #/ Set y-axis label style. The default is Arial 8 pt black color, with 13 pixels margin.
+ #/
+ #/ The font of the axis labels.
+ #/ The font size of the axis labels in points.
+ #/ The color of the axis labels.
+ #/ The margin at the top of the y-axis in pixels (to leave
+ #/ space for the legend box).
+ function setYAxisStyle($font, $fontSize, $fontColor, $axisMargin) {
+ $this->m_yAxisFont = $font;
+ $this->m_yAxisFontSize = $fontSize;
+ $this->m_yAxisFontColor = $fontColor;
+ $this->m_yAxisMargin = $axisMargin;
+ }
+
+ #/
+ #/ Set whether the main y-axis is on right of left side of the plot area. The default is
+ #/ on right.
+ #/
+ #/ True if the y-axis is on right. False if the y-axis is on left.
+ function setAxisOnRight($b) {
+ $this->m_axisOnRight = $b;
+ }
+
+ #/
+ #/ Determines if log scale should be used for the main chart. The default is linear scale.
+ #/
+ #/ True for using log scale. False for using linear scale.
+ function setLogScale($b) {
+ $this->m_logScale = $b;
+ if ($this->m_mainChart != null) {
+ if ($this->m_logScale) {
+ $this->m_mainChart->yAxis->setLogScale();
+ } else {
+ $this->m_mainChart->yAxis->setLinearScale();
+ }
+ }
+ }
+
+ #/
+ #/ Set the date/time formats to use for the x-axis labels under various cases.
+ #/
+ #/ The format for displaying labels on an axis with yearly ticks. The
+ #/ default is "yyyy".
+ #/ The format for displaying labels on an axis with monthly ticks.
+ #/ This parameter applies to the first available month of a year (usually January) only, so it can
+ #/ be formatted differently from the other labels.
+ #/ The format for displaying labels on an axis with monthly ticks.
+ #/ This parameter applies to months other than the first available month of a year.
+ #/ The format for displaying labels on an axis with daily ticks.
+ #/ This parameter applies to the first available day of a month only, so it can be formatted
+ #/ differently from the other labels.
+ #/ The format for displaying labels on an axis with daily ticks.
+ #/ This parameter applies to days other than the first available day of a month.
+ #/ The format for displaying labels on an axis with hourly
+ #/ resolution. This parameter applies to the first tick of a day only, so it can be formatted
+ #/ differently from the other labels.
+ #/ The format for displaying labels on an axis with hourly.
+ #/ resolution. This parameter applies to ticks at hourly boundaries, except the first tick
+ #/ of a day.
+ function setDateLabelFormat($yearFormat, $firstMonthFormat, $otherMonthFormat, $firstDayFormat,
+ $otherDayFormat, $firstHourFormat, $otherHourFormat) {
+ if ($yearFormat != null) {
+ $this->m_yearFormat = $yearFormat;
+ }
+ if ($firstMonthFormat != null) {
+ $this->m_firstMonthFormat = $firstMonthFormat;
+ }
+ if ($otherMonthFormat != null) {
+ $this->m_otherMonthFormat = $otherMonthFormat;
+ }
+ if ($firstDayFormat != null) {
+ $this->m_firstDayFormat = $firstDayFormat;
+ }
+ if ($otherDayFormat != null) {
+ $this->m_otherDayFormat = $otherDayFormat;
+ }
+ if ($firstHourFormat != null) {
+ $this->m_firstHourFormat = $firstHourFormat;
+ }
+ if ($otherHourFormat != null) {
+ $this->m_otherHourFormat = $otherHourFormat;
+ }
+ }
+
+ #/
+ #/ Set the minimum label spacing between two labels on the time axis
+ #/
+ #/ The minimum label spacing in pixels.
+ function setDateLabelSpacing($labelSpacing) {
+ if ($labelSpacing > 0) {
+ $this->m_timeLabelSpacing = $labelSpacing;
+ } else {
+ $this->m_timeLabelSpacing = 0;
+ }
+ }
+
+ #/
+ #/ Set the tool tip formats for display date/time
+ #/
+ #/ The tool tip format to use if the data point spacing is one
+ #/ or more months (more than 30 days).
+ #/ The tool tip format to use if the data point spacing is 1 day
+ #/ to less than 30 days.
+ #/ The tool tip format to use if the data point spacing is less
+ #/ than 1 day.
+ function setToolTipDateFormat($monthFormat, $dayFormat, $hourFormat) {
+ if ($monthFormat != null) {
+ $this->m_toolTipMonthFormat = $monthFormat;
+ }
+ if ($dayFormat != null) {
+ $this->m_toolTipDayFormat = $dayFormat;
+ }
+ if ($hourFormat != null) {
+ $this->m_toolTipHourFormat = $hourFormat;
+ }
+ }
+
+ #/
+ #/ Get the tool tip format for display date/time
+ #/
+ #/ The tool tip format string.
+ function getToolTipDateFormat() {
+ if ($this->m_timeStamps == null) {
+ return $this->m_toolTipHourFormat;
+ }
+ if (count($this->m_timeStamps) <= $this->m_extraPoints) {
+ return $this->m_toolTipHourFormat;
+ }
+ $resolution = ($this->m_timeStamps[count($this->m_timeStamps) - 1] - $this->m_timeStamps[0])
+ / count($this->m_timeStamps);
+ if ($resolution >= 30 * 86400) {
+ return $this->m_toolTipMonthFormat;
+ } else if ($resolution >= 86400) {
+ return $this->m_toolTipDayFormat;
+ } else {
+ return $this->m_toolTipHourFormat;
+ }
+ }
+
+ #/
+ #/ Set the number format for use in displaying values in legend keys and tool tips.
+ #/
+ #/ The default number format.
+ function setNumberLabelFormat($formatString) {
+ if ($formatString != null) {
+ $this->m_generalFormat = $formatString;
+ }
+ }
+
+ #/
+ #/ A utility function to compute triangular moving averages
+ #/
+ #/ An array of numbers as input.
+ #/ The moving average period.
+ #/ An array representing the triangular moving average of the input array.
+ function computeTriMovingAvg($data, $period) {
+ $p = $period / 2 + 1;
+ $tmpArrayMath1 = new ArrayMath($data);
+ $tmpArrayMath1->movAvg($p);
+ $tmpArrayMath1->movAvg($p);
+ return $tmpArrayMath1->result();
+ }
+
+ #/
+ #/ A utility function to compute weighted moving averages
+ #/
+ #/ An array of numbers as input.
+ #/ The moving average period.
+ #/ An array representing the weighted moving average of the input array.
+ function computeWeightedMovingAvg($data, $period) {
+ $acc = new ArrayMath($data);
+ for($i = 2; $i < $period + 1; ++$i) {
+ $tmpArrayMath1 = new ArrayMath($data);
+ $tmpArrayMath1->movAvg($i);
+ $tmpArrayMath1->mul($i);
+ $acc->add($tmpArrayMath1->result());
+ }
+ $divObj = $acc->div((1 + $period) * $period / 2);
+ return $divObj->result();
+ }
+
+ #/
+ #/ A utility function to obtain the first visible closing price.
+ #/
+ #/ The first closing price.
+ #/ are cd.NoValue.
+ function firstCloseValue() {
+ for($i = $this->m_extraPoints; $i < count($this->m_closeData); ++$i) {
+ if (($this->m_closeData[$i] != NoValue) && ($this->m_closeData[$i] != 0)) {
+ return $this->m_closeData[$i];
+ }
+ }
+ return NoValue;
+ }
+
+ #/
+ #/ A utility function to obtain the last valid position (that is, position not
+ #/ containing cd.NoValue) of a data series.
+ #/
+ #/ An array of numbers as input.
+ #/ The last valid position in the input array, or -1 if all positions
+ #/ are cd.NoValue.
+ function lastIndex($data) {
+ $i = count($data) - 1;
+ while ($i >= 0) {
+ if ($data[$i] != NoValue) {
+ break;
+ }
+ $i = $i - 1;
+ }
+ return $i;
+ }
+
+ #/
+ #/ Set the data used in the chart. If some of the data are not available, some artifical
+ #/ values should be used. For example, if the high and low values are not available, you
+ #/ may use closeData as highData and lowData.
+ #/
+ #/ An array of dates/times for the time intervals.
+ #/ The high values in the time intervals.
+ #/ The low values in the time intervals.
+ #/ The open values in the time intervals.
+ #/ The close values in the time intervals.
+ #/ The volume values in the time intervals.
+ #/ The number of leading time intervals that are not
+ #/ displayed in the chart. These intervals are typically used for computing
+ #/ indicators that require extra leading data, such as moving averages.
+ function setData($timeStamps, $highData, $lowData, $openData, $closeData, $volData, $extraPoints
+ ) {
+ $this->m_timeStamps = $timeStamps;
+ $this->m_highData = $highData;
+ $this->m_lowData = $lowData;
+ $this->m_openData = $openData;
+ $this->m_closeData = $closeData;
+ if ($extraPoints > 0) {
+ $this->m_extraPoints = $extraPoints;
+ } else {
+ $this->m_extraPoints = 0;
+ }
+
+ #///////////////////////////////////////////////////////////////////////
+ # Auto-detect volume units
+ #///////////////////////////////////////////////////////////////////////
+ $tmpArrayMath1 = new ArrayMath($volData);
+ $maxVol = $tmpArrayMath1->max();
+ $units = array("", "K", "M", "B");
+ $unitIndex = count($units) - 1;
+ while (($unitIndex > 0) && ($maxVol < pow(1000, $unitIndex))) {
+ $unitIndex = $unitIndex - 1;
+ }
+
+ $tmpArrayMath1 = new ArrayMath($volData);
+ $tmpArrayMath1->div(pow(1000, $unitIndex));
+ $this->m_volData = $tmpArrayMath1->result();
+ $this->m_volUnit = $units[$unitIndex];
+ }
+
+ #////////////////////////////////////////////////////////////////////////////
+ # Format x-axis labels
+ #////////////////////////////////////////////////////////////////////////////
+ function setXLabels(&$a) {
+ $a->setLabels2($this->m_timeStamps);
+ if ($this->m_extraPoints < count($this->m_timeStamps)) {
+ $tickStep = (int)((count($this->m_timeStamps) - $this->m_extraPoints) *
+ $this->m_timeLabelSpacing / ($this->m_totalWidth - $this->m_leftMargin -
+ $this->m_rightMargin)) + 1;
+ $timeRangeInSeconds = $this->m_timeStamps[count($this->m_timeStamps) - 1] -
+ $this->m_timeStamps[$this->m_extraPoints];
+ $secondsBetweenTicks = $timeRangeInSeconds / ($this->m_totalWidth - $this->m_leftMargin
+ - $this->m_rightMargin) * $this->m_timeLabelSpacing;
+
+ if ($secondsBetweenTicks * (count($this->m_timeStamps) - $this->m_extraPoints) <=
+ $timeRangeInSeconds) {
+ $tickStep = 1;
+ if (count($this->m_timeStamps) > 1) {
+ $secondsBetweenTicks = $this->m_timeStamps[count($this->m_timeStamps) - 1] -
+ $this->m_timeStamps[count($this->m_timeStamps) - 2];
+ } else {
+ $secondsBetweenTicks = 86400;
+ }
+ }
+
+ if (($secondsBetweenTicks > 360 * 86400) || (($secondsBetweenTicks > 90 * 86400) && (
+ $timeRangeInSeconds >= 720 * 86400))) {
+ #yearly ticks
+ $a->setMultiFormat2(StartOfYearFilter(), $this->m_yearFormat, $tickStep);
+ } else if (($secondsBetweenTicks >= 30 * 86400) || (($secondsBetweenTicks > 7 * 86400)
+ && ($timeRangeInSeconds >= 60 * 86400))) {
+ #monthly ticks
+ $monthBetweenTicks = (int)($secondsBetweenTicks / 31 / 86400) + 1;
+ $a->setMultiFormat(StartOfYearFilter(), $this->m_firstMonthFormat,
+ StartOfMonthFilter($monthBetweenTicks), $this->m_otherMonthFormat);
+ $a->setMultiFormat2(StartOfMonthFilter(), "-", 1, false);
+ } else if (($secondsBetweenTicks >= 86400) || (($secondsBetweenTicks > 6 * 3600) && (
+ $timeRangeInSeconds >= 86400))) {
+ #daily ticks
+ $a->setMultiFormat(StartOfMonthFilter(), $this->m_firstDayFormat, StartOfDayFilter(
+ 1, 0.5), $this->m_otherDayFormat, $tickStep);
+ } else {
+ #hourly ticks
+ $a->setMultiFormat(StartOfDayFilter(1, 0.5), $this->m_firstHourFormat,
+ StartOfHourFilter(1, 0.5), $this->m_otherHourFormat, $tickStep);
+ }
+ }
+ }
+
+ #////////////////////////////////////////////////////////////////////////////
+ # Create tool tip format string for showing OHLC data
+ #////////////////////////////////////////////////////////////////////////////
+ function getHLOCToolTipFormat() {
+ return sprintf("title='%s Op:{open|%s}, Hi:{high|%s}, Lo:{low|%s}, Cl:{close|%s}'",
+ $this->getToolTipDateFormat(), $this->m_generalFormat, $this->m_generalFormat,
+ $this->m_generalFormat, $this->m_generalFormat);
+ }
+
+ #/
+ #/ Add the main chart - the chart that shows the HLOC data.
+ #/
+ #/ The height of the main chart in pixels.
+ #/ An XYChart object representing the main chart created.
+ function addMainChart($height) {
+ $this->m_mainChart = $this->addIndicator($height);
+ $this->m_mainChart->yAxis->setMargin(2 * $this->m_yAxisMargin);
+ if ($this->m_logScale) {
+ $this->m_mainChart->yAxis->setLogScale();
+ } else {
+ $this->m_mainChart->yAxis->setLinearScale();
+ }
+ return $this->m_mainChart;
+ }
+
+ #/
+ #/ Add a candlestick layer to the main chart.
+ #/
+ #/ The candle color for an up day.
+ #/ The candle color for a down day.
+ #/ The CandleStickLayer created.
+ function addCandleStick($upColor, $downColor) {
+ $this->addOHLCLabel($upColor, $downColor, true);
+ $ret = $this->m_mainChart->addCandleStickLayer($this->m_highData, $this->m_lowData,
+ $this->m_openData, $this->m_closeData, $upColor, $downColor);
+ $ret->setHTMLImageMap("", "", $this->getHLOCToolTipFormat());
+ if (count($this->m_highData) - $this->m_extraPoints > 60) {
+ $ret->setDataGap(0);
+ }
+
+ if (count($this->m_highData) > $this->m_extraPoints) {
+ $expectedWidth = (int)(($this->m_totalWidth - $this->m_leftMargin - $this->m_rightMargin
+ ) / (count($this->m_highData) - $this->m_extraPoints));
+ if ($expectedWidth <= 5) {
+ $ret->setDataWidth($expectedWidth + 1 - $expectedWidth % 2);
+ }
+ }
+
+ return $ret;
+ }
+
+ #/
+ #/ Add a HLOC layer to the main chart.
+ #/
+ #/ The color of the HLOC symbol for an up day.
+ #/ The color of the HLOC symbol for a down day.
+ #/ The HLOCLayer created.
+ function addHLOC($upColor, $downColor) {
+ $this->addOHLCLabel($upColor, $downColor, false);
+ $ret = $this->m_mainChart->addHLOCLayer($this->m_highData, $this->m_lowData,
+ $this->m_openData, $this->m_closeData);
+ $ret->setColorMethod(HLOCUpDown, $upColor, $downColor);
+ $ret->setHTMLImageMap("", "", $this->getHLOCToolTipFormat());
+ $ret->setDataGap(0);
+ return $ret;
+ }
+
+ function addOHLCLabel($upColor, $downColor, $candleStickMode) {
+ $i = $this->lastIndex($this->m_closeData);
+ if ($i >= 0) {
+ $openValue = NoValue;
+ $closeValue = NoValue;
+ $highValue = NoValue;
+ $lowValue = NoValue;
+
+ if ($i < count($this->m_openData)) {
+ $openValue = $this->m_openData[$i];
+ }
+ if ($i < count($this->m_closeData)) {
+ $closeValue = $this->m_closeData[$i];
+ }
+ if ($i < count($this->m_highData)) {
+ $highValue = $this->m_highData[$i];
+ }
+ if ($i < count($this->m_lowData)) {
+ $lowValue = $this->m_lowData[$i];
+ }
+
+ $openLabel = "";
+ $closeLabel = "";
+ $highLabel = "";
+ $lowLabel = "";
+ $delim = "";
+ if ($openValue != NoValue) {
+ $openLabel = sprintf("Op:%s", $this->formatValue($openValue, $this->m_generalFormat)
+ );
+ $delim = ", ";
+ }
+ if ($highValue != NoValue) {
+ $highLabel = sprintf("%sHi:%s", $delim, $this->formatValue($highValue,
+ $this->m_generalFormat));
+ $delim = ", ";
+ }
+ if ($lowValue != NoValue) {
+ $lowLabel = sprintf("%sLo:%s", $delim, $this->formatValue($lowValue,
+ $this->m_generalFormat));
+ $delim = ", ";
+ }
+ if ($closeValue != NoValue) {
+ $closeLabel = sprintf("%sCl:%s", $delim, $this->formatValue($closeValue,
+ $this->m_generalFormat));
+ $delim = ", ";
+ }
+ $label = "$openLabel$highLabel$lowLabel$closeLabel";
+
+ $useUpColor = ($closeValue >= $openValue);
+ if ($candleStickMode != true) {
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->delta();
+ $closeChanges = $tmpArrayMath1->result();
+ $lastChangeIndex = $this->lastIndex($closeChanges);
+ $useUpColor = ($lastChangeIndex < 0);
+ if ($useUpColor != true) {
+ $useUpColor = ($closeChanges[$lastChangeIndex] >= 0);
+ }
+ }
+
+ $udcolor = $downColor;
+ if ($useUpColor) {
+ $udcolor = $upColor;
+ }
+ $legendObj = $this->m_mainChart->getLegend();
+ $legendObj->addKey($label, $udcolor);
+ }
+ }
+
+ #/
+ #/ Add a closing price line on the main chart.
+ #/
+ #/ The color of the line.
+ #/ The LineLayer object representing the line created.
+ function addCloseLine($color) {
+ return $this->addLineIndicator2($this->m_mainChart, $this->m_closeData, $color,
+ "Closing Price");
+ }
+
+ #/
+ #/ Add a weight close line on the main chart.
+ #/
+ #/ The color of the line.
+ #/ The LineLayer object representing the line created.
+ function addWeightedClose($color) {
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->add($this->m_lowData);
+ $tmpArrayMath1->add($this->m_closeData);
+ $tmpArrayMath1->add($this->m_closeData);
+ $tmpArrayMath1->div(4);
+ return $this->addLineIndicator2($this->m_mainChart, $tmpArrayMath1->result(), $color,
+ "Weighted Close");
+ }
+
+ #/
+ #/ Add a typical price line on the main chart.
+ #/
+ #/ The color of the line.
+ #/ The LineLayer object representing the line created.
+ function addTypicalPrice($color) {
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->add($this->m_lowData);
+ $tmpArrayMath1->add($this->m_closeData);
+ $tmpArrayMath1->div(3);
+ return $this->addLineIndicator2($this->m_mainChart, $tmpArrayMath1->result(), $color,
+ "Typical Price");
+ }
+
+ #/
+ #/ Add a median price line on the main chart.
+ #/
+ #/ The color of the line.
+ #/ The LineLayer object representing the line created.
+ function addMedianPrice($color) {
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->add($this->m_lowData);
+ $tmpArrayMath1->div(2);
+ return $this->addLineIndicator2($this->m_mainChart, $tmpArrayMath1->result(), $color,
+ "Median Price");
+ }
+
+ #/
+ #/ Add a simple moving average line on the main chart.
+ #/
+ #/ The moving average period
+ #/ The color of the line.
+ #/ The LineLayer object representing the line created.
+ function addSimpleMovingAvg($period, $color) {
+ $label = "SMA ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->movAvg($period);
+ return $this->addLineIndicator2($this->m_mainChart, $tmpArrayMath1->result(), $color, $label
+ );
+ }
+
+ #/
+ #/ Add an exponential moving average line on the main chart.
+ #/
+ #/ The moving average period
+ #/ The color of the line.
+ #/ The LineLayer object representing the line created.
+ function addExpMovingAvg($period, $color) {
+ $label = "EMA ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->expAvg(2.0 / ($period + 1));
+ return $this->addLineIndicator2($this->m_mainChart, $tmpArrayMath1->result(), $color, $label
+ );
+ }
+
+ #/
+ #/ Add a triangular moving average line on the main chart.
+ #/
+ #/ The moving average period
+ #/ The color of the line.
+ #/ The LineLayer object representing the line created.
+ function addTriMovingAvg($period, $color) {
+ $label = "TMA ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->computeTriMovingAvg($this->m_closeData, $period));
+ return $this->addLineIndicator2($this->m_mainChart, $tmpArrayMath1->result(), $color, $label
+ );
+ }
+
+ #/
+ #/ Add a weighted moving average line on the main chart.
+ #/
+ #/ The moving average period
+ #/ The color of the line.
+ #/ The LineLayer object representing the line created.
+ function addWeightedMovingAvg($period, $color) {
+ $label = "WMA ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->computeWeightedMovingAvg($this->m_closeData, $period))
+ ;
+ return $this->addLineIndicator2($this->m_mainChart, $tmpArrayMath1->result(), $color, $label
+ );
+ }
+
+ #/
+ #/ Add a parabolic SAR indicator to the main chart.
+ #/
+ #/ Initial acceleration factor
+ #/ Acceleration factor increment
+ #/ Maximum acceleration factor
+ #/ The symbol used to plot the parabolic SAR
+ #/ The symbol size in pixels
+ #/ The fill color of the symbol
+ #/ The edge color of the symbol
+ #/ The LineLayer object representing the layer created.
+ function addParabolicSAR($accInitial, $accIncrement, $accMaximum, $symbolType, $symbolSize,
+ $fillColor, $edgeColor) {
+ $isLong = true;
+ $acc = $accInitial;
+ $extremePoint = 0;
+ $psar = array_pad(array(), count($this->m_lowData), 0);
+
+ $i_1 = -1;
+ $i_2 = -1;
+
+ for($i = 0; $i < count($this->m_lowData); ++$i) {
+ $psar[$i] = NoValue;
+ if (($this->m_lowData[$i] != NoValue) && ($this->m_highData[$i] != NoValue)) {
+ if (($i_1 >= 0) && ($i_2 < 0)) {
+ if ($this->m_lowData[$i_1] <= $this->m_lowData[$i]) {
+ $psar[$i] = $this->m_lowData[$i_1];
+ $isLong = true;
+ if ($this->m_highData[$i_1] > $this->m_highData[$i]) {
+ $extremePoint = $this->m_highData[$i_1];
+ } else {
+ $extremePoint = $this->m_highData[$i];
+ }
+ } else {
+ $extremePoint = $this->m_lowData[$i];
+ $isLong = false;
+ if ($this->m_highData[$i_1] > $this->m_highData[$i]) {
+ $psar[$i] = $this->m_highData[$i_1];
+ } else {
+ $psar[$i] = $this->m_highData[$i];
+ }
+ }
+ } else if (($i_1 >= 0) && ($i_2 >= 0)) {
+ if ($acc > $accMaximum) {
+ $acc = $accMaximum;
+ }
+
+ $psar[$i] = $psar[$i_1] + $acc * ($extremePoint - $psar[$i_1]);
+
+ if ($isLong) {
+ if ($this->m_lowData[$i] < $psar[$i]) {
+ $isLong = false;
+ $psar[$i] = $extremePoint;
+ $extremePoint = $this->m_lowData[$i];
+ $acc = $accInitial;
+ } else {
+ if ($this->m_highData[$i] > $extremePoint) {
+ $extremePoint = $this->m_highData[$i];
+ $acc = $acc + $accIncrement;
+ }
+
+ if ($this->m_lowData[$i_1] < $psar[$i]) {
+ $psar[$i] = $this->m_lowData[$i_1];
+ }
+ if ($this->m_lowData[$i_2] < $psar[$i]) {
+ $psar[$i] = $this->m_lowData[$i_2];
+ }
+ }
+ } else {
+ if ($this->m_highData[$i] > $psar[$i]) {
+ $isLong = true;
+ $psar[$i] = $extremePoint;
+ $extremePoint = $this->m_highData[$i];
+ $acc = $accInitial;
+ } else {
+ if ($this->m_lowData[$i] < $extremePoint) {
+ $extremePoint = $this->m_lowData[$i];
+ $acc = $acc + $accIncrement;
+ }
+
+ if ($this->m_highData[$i_1] > $psar[$i]) {
+ $psar[$i] = $this->m_highData[$i_1];
+ }
+ if ($this->m_highData[$i_2] > $psar[$i]) {
+ $psar[$i] = $this->m_highData[$i_2];
+ }
+ }
+ }
+ }
+
+ $i_2 = $i_1;
+ $i_1 = $i;
+ }
+ }
+
+ $ret = $this->addLineIndicator2($this->m_mainChart, $psar, $fillColor, "Parabolic SAR");
+ $ret->setLineWidth(0);
+
+ $ret = $this->addLineIndicator2($this->m_mainChart, $psar, $fillColor, "");
+ $ret->setLineWidth(0);
+ $dataSetObj = $ret->getDataSet(0);
+ $dataSetObj->setDataSymbol($symbolType, $symbolSize, $fillColor, $edgeColor);
+ return $ret;
+ }
+
+ #/
+ #/ Add a comparison line to the main price chart.
+ #/
+ #/ The data series to compare to
+ #/ The color of the comparison line
+ #/ The name of the comparison line
+ #/ The LineLayer object representing the line layer created.
+ function addComparison($data, $color, $name) {
+ $firstIndex = $this->m_extraPoints;
+ while (($firstIndex < count($data)) && ($firstIndex < count($this->m_closeData))) {
+ if (($data[$firstIndex] != NoValue) && ($this->m_closeData[$firstIndex] != NoValue) && (
+ $data[$firstIndex] != 0) && ($this->m_closeData[$firstIndex] != 0)) {
+ break;
+ }
+ $firstIndex = $firstIndex + 1;
+ }
+ if (($firstIndex >= count($data)) || ($firstIndex >= count($this->m_closeData))) {
+ return null;
+ }
+
+ $scaleFactor = $this->m_closeData[$firstIndex] / $data[$firstIndex];
+ $tmpArrayMath1 = new ArrayMath($data);
+ $tmpArrayMath1->mul($scaleFactor);
+ $layer = $this->m_mainChart->addLineLayer($tmpArrayMath1->result(), Transparent);
+ $layer->setHTMLImageMap("{disable}");
+
+ $a = $this->m_mainChart->addAxis(Right, 0);
+ $a->setColors(Transparent, Transparent);
+ $a->syncAxis($this->m_mainChart->yAxis, 1 / $scaleFactor, 0);
+
+ $ret = $this->addLineIndicator2($this->m_mainChart, $data, $color, $name);
+ $ret->setUseYAxis($a);
+ return $ret;
+ }
+
+ #/
+ #/ Display percentage axis scale
+ #/
+ #/ The Axis object representing the percentage axis.
+ function setPercentageAxis() {
+ $firstClose = $this->firstCloseValue();
+ if ($firstClose == NoValue) {
+ return null;
+ }
+
+ $axisAlign = Left;
+ if ($this->m_axisOnRight) {
+ $axisAlign = Right;
+ }
+
+ $ret = $this->m_mainChart->addAxis($axisAlign, 0);
+ $this->configureYAxis($ret, 300);
+ $ret->syncAxis($this->m_mainChart->yAxis, 100 / $firstClose);
+ $ret->setRounding(false, false);
+ $ret->setLabelFormat("{={value}-100|@}%");
+ $this->m_mainChart->yAxis->setColors(Transparent, Transparent);
+ $plotAreaObj = $this->m_mainChart->getPlotArea();
+ $plotAreaObj->setGridAxis(null, $ret);
+ return $ret;
+ }
+
+ #/
+ #/ Add a generic band to the main finance chart. This method is used internally by other methods to add
+ #/ various bands (eg. Bollinger band, Donchian channels, etc).
+ #/
+ #/ The data series for the upper band line.
+ #/ The data series for the lower band line.
+ #/ The color of the upper and lower band line.
+ #/ The color to fill the region between the upper and lower band lines.
+ #/ The name of the band.
+ #/ An InterLineLayer object representing the filled region.
+ function addBand($upperLine, $lowerLine, $lineColor, $fillColor, $name) {
+ $i = count($upperLine) - 1;
+ if ($i >= count($lowerLine)) {
+ $i = count($lowerLine) - 1;
+ }
+
+ while ($i >= 0) {
+ if (($upperLine[$i] != NoValue) && ($lowerLine[$i] != NoValue)) {
+ $name = sprintf("%s: %s - %s", $name, $this->formatValue($lowerLine[$i],
+ $this->m_generalFormat), $this->formatValue($upperLine[$i],
+ $this->m_generalFormat));
+ break;
+ }
+ $i = $i - 1;
+ }
+
+ $layer = $this->m_mainChart->addLineLayer2();
+ $layer->addDataSet($upperLine, $lineColor, $name);
+ $layer->addDataSet($lowerLine, $lineColor);
+ return $this->m_mainChart->addInterLineLayer($layer->getLine(0), $layer->getLine(1),
+ $fillColor);
+ }
+
+ #/
+ #/ Add a Bollinger band on the main chart.
+ #/
+ #/ The period to compute the band.
+ #/ The half-width of the band in terms multiples of standard deviation. Typically 2 is used.
+ #/ The color of the lines defining the upper and lower limits.
+ #/ The color to fill the regional within the band.
+ #/ The InterLineLayer object representing the band created.
+ function addBollingerBand($period, $bandWidth, $lineColor, $fillColor) {
+ #Bollinger Band is moving avg +/- (width * moving std deviation)
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->movStdDev($period);
+ $tmpArrayMath1->mul($bandWidth);
+ $stdDev = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->movAvg($period);
+ $movAvg = $tmpArrayMath1->result();
+ $label = "Bollinger ($period, $bandWidth)";
+ $tmpArrayMath1 = new ArrayMath($movAvg);
+ $tmpArrayMath1->add($stdDev);
+ $tmpArrayMath2 = new ArrayMath($movAvg);
+ $tmpArrayMath2->sub($stdDev);
+ $tmpArrayMath2->selectGTZ(null, 0);
+ return $this->addBand($tmpArrayMath1->result(), $tmpArrayMath2->result(), $lineColor,
+ $fillColor, $label);
+ }
+
+ #/
+ #/ Add a Donchian channel on the main chart.
+ #/
+ #/ The period to compute the band.
+ #/ The color of the lines defining the upper and lower limits.
+ #/ The color to fill the regional within the band.
+ #/ The InterLineLayer object representing the band created.
+ function addDonchianChannel($period, $lineColor, $fillColor) {
+ #Donchian Channel is the zone between the moving max and moving min
+ $label = "Donchian ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->movMax($period);
+ $tmpArrayMath2 = new ArrayMath($this->m_lowData);
+ $tmpArrayMath2->movMin($period);
+ return $this->addBand($tmpArrayMath1->result(), $tmpArrayMath2->result(), $lineColor,
+ $fillColor, $label);
+ }
+
+ #/
+ #/ Add a price envelop on the main chart. The price envelop is a defined as a ratio around a
+ #/ moving average. For example, a ratio of 0.2 means 20% above and below the moving average.
+ #/
+ #/ The period for the moving average.
+ #/ The ratio above and below the moving average.
+ #/ The color of the lines defining the upper and lower limits.
+ #/ The color to fill the regional within the band.
+ #/ The InterLineLayer object representing the band created.
+ function addEnvelop($period, $range, $lineColor, $fillColor) {
+ #Envelop is moving avg +/- percentage
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->movAvg($period);
+ $movAvg = $tmpArrayMath1->result();
+ $label = sprintf("Envelop (SMA %s +/- %s%%)", $period, (int)($range * 100));
+ $tmpArrayMath1 = new ArrayMath($movAvg);
+ $tmpArrayMath1->mul(1 + $range);
+ $tmpArrayMath2 = new ArrayMath($movAvg);
+ $tmpArrayMath2->mul(1 - $range);
+ return $this->addBand($tmpArrayMath1->result(), $tmpArrayMath2->result(), $lineColor,
+ $fillColor, $label);
+ }
+
+ #/
+ #/ Add a volume bar chart layer on the main chart.
+ #/
+ #/ The height of the bar chart layer in pixels.
+ #/ The color to used on an 'up' day. An 'up' day is a day where
+ #/ the closing price is higher than that of the previous day.
+ #/ The color to used on a 'down' day. A 'down' day is a day
+ #/ where the closing price is lower than that of the previous day.
+ #/ The color to used on a 'flat' day. A 'flat' day is a day
+ #/ where the closing price is the same as that of the previous day.
+ #/ The XYChart object representing the chart created.
+ function addVolBars($height, $upColor, $downColor, $flatColor) {
+ return $this->addVolBars2($this->m_mainChart, $height, $upColor, $downColor, $flatColor);
+ }
+
+ function addVolBars2(&$c, $height, $upColor, $downColor, $flatColor) {
+ $barLayer = $c->addBarLayer2(Overlay);
+ $barLayer->setBorderColor(Transparent);
+
+ if ($c == $this->m_mainChart) {
+ $this->configureYAxis($c->yAxis2, $height);
+ $drawAreaObj = $c->getDrawArea();
+ $topMargin = $drawAreaObj->getHeight() - $this->m_topMargin - $this->m_bottomMargin -
+ $height + $this->m_yAxisMargin;
+ if ($topMargin < 0) {
+ $topMargin = 0;
+ }
+ $c->yAxis2->setTopMargin($topMargin);
+ $barLayer->setUseYAxis2();
+ }
+
+ $a = $c->yAxis2;
+ if ($c != $this->m_mainChart) {
+ $a = $c->yAxis;
+ }
+ $tmpArrayMath1 = new ArrayMath($this->m_volData);
+ if ($tmpArrayMath1->max() < 10) {
+ $a->setLabelFormat(sprintf("{value|1}%s", $this->m_volUnit));
+ } else {
+ $a->setLabelFormat(sprintf("{value}%s", $this->m_volUnit));
+ }
+
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->delta();
+ $tmpArrayMath1->replace(NoValue, 0);
+ $closeChange = $tmpArrayMath1->result();
+ $i = $this->lastIndex($this->m_volData);
+ $label = "Vol";
+ if ($i >= 0) {
+ $label = sprintf("%s: %s%s", $label, $this->formatValue($this->m_volData[$i],
+ $this->m_generalFormat), $this->m_volUnit);
+ }
+
+ $tmpArrayMath1 = new ArrayMath($this->m_volData);
+ $tmpArrayMath1->selectGTZ($closeChange);
+ $upDS = $barLayer->addDataSet($tmpArrayMath1->result(), $upColor);
+ $tmpArrayMath1 = new ArrayMath($this->m_volData);
+ $tmpArrayMath1->selectLTZ($closeChange);
+ $dnDS = $barLayer->addDataSet($tmpArrayMath1->result(), $downColor);
+ $tmpArrayMath1 = new ArrayMath($this->m_volData);
+ $tmpArrayMath1->selectEQZ($closeChange);
+ $flatDS = $barLayer->addDataSet($tmpArrayMath1->result(), $flatColor);
+
+ if (($i < 0) || ($closeChange[$i] == 0) || ($closeChange[$i] == NoValue)) {
+ $flatDS->setDataName($label);
+ } else if ($closeChange[$i] > 0) {
+ $upDS->setDataName($label);
+ } else {
+ $dnDS->setDataName($label);
+ }
+
+ return $barLayer;
+ }
+
+ #/
+ #/ Add a blank indicator chart to the finance chart. Used internally to add other indicators.
+ #/ Override to change the default formatting (eg. axis fonts, etc.) of the various indicators.
+ #/
+ #/ The height of the chart in pixels.
+ #/ The XYChart object representing the chart created.
+ function addIndicator($height) {
+ #create a new chart object
+ $ret = new XYChart($this->m_totalWidth, $height + $this->m_topMargin +
+ $this->m_bottomMargin, Transparent);
+ $ret->setTrimData($this->m_extraPoints);
+
+ if ($this->m_currentChart != null) {
+ #if there is a chart before the newly created chart, disable its x-axis, and copy
+ #its x-axis labels to the new chart
+ $this->m_currentChart->xAxis->setColors(Transparent, Transparent);
+ $ret->xAxis->copyAxis($this->m_currentChart->xAxis);
+
+ #add chart to MultiChart and update the total height
+ $this->addChart(0, $this->m_totalHeight + $this->m_plotAreaGap, $ret);
+ $this->m_totalHeight = $this->m_totalHeight + $height + 1 + $this->m_plotAreaGap;
+ } else {
+ #no existing chart - create the x-axis labels from scratch
+ $this->setXLabels($ret->xAxis);
+
+ #add chart to MultiChart and update the total height
+ $this->addChart(0, $this->m_totalHeight, $ret);
+ $this->m_totalHeight = $this->m_totalHeight + $height + 1;
+ }
+
+ #the newly created chart becomes the current chart
+ $this->m_currentChart = $ret;
+
+ #update the size
+ $this->setSize($this->m_totalWidth, $this->m_totalHeight + $this->m_topMargin +
+ $this->m_bottomMargin);
+
+ #configure the plot area
+ $plotAreaObj = $ret->setPlotArea($this->m_leftMargin, $this->m_topMargin,
+ $this->m_totalWidth - $this->m_leftMargin - $this->m_rightMargin, $height,
+ $this->m_plotAreaBgColor, -1, $this->m_plotAreaBorder);
+ $plotAreaObj->setGridColor($this->m_majorHGridColor, $this->m_majorVGridColor,
+ $this->m_minorHGridColor, $this->m_minorVGridColor);
+ $ret->setAntiAlias($this->m_antiAlias);
+
+ #configure legend box
+ if ($this->m_legendFontColor != Transparent) {
+ $box = $ret->addLegend($this->m_leftMargin, $this->m_topMargin, false,
+ $this->m_legendFont, $this->m_legendFontSize);
+ $box->setFontColor($this->m_legendFontColor);
+ $box->setBackground($this->m_legendBgColor);
+ $box->setMargin2(5, 0, 2, 1);
+ $box->setSize($this->m_totalWidth - $this->m_leftMargin - $this->m_rightMargin + 1, 0);
+ }
+
+ #configure x-axis
+ $a = $ret->xAxis;
+ $a->setIndent(true);
+ $a->setTickLength(2, 0);
+ $a->setColors(Transparent, $this->m_xAxisFontColor, $this->m_xAxisFontColor,
+ $this->m_xAxisFontColor);
+ $a->setLabelStyle($this->m_xAxisFont, $this->m_xAxisFontSize, $this->m_xAxisFontColor,
+ $this->m_xAxisFontAngle);
+
+ #configure y-axis
+ $ret->setYAxisOnRight($this->m_axisOnRight);
+ $this->configureYAxis($ret->yAxis, $height);
+
+ return $ret;
+ }
+
+ function configureYAxis(&$a, $height) {
+ $a->setAutoScale(0, 0.05, 0);
+ if ($height < 100) {
+ $a->setTickDensity(15);
+ }
+ $a->setMargin($this->m_yAxisMargin);
+ $a->setLabelStyle($this->m_yAxisFont, $this->m_yAxisFontSize, $this->m_yAxisFontColor, 0);
+ $a->setTickLength(-4, -2);
+ $a->setColors(Transparent, $this->m_yAxisFontColor, $this->m_yAxisFontColor,
+ $this->m_yAxisFontColor);
+ }
+
+ #/
+ #/ Add a generic line indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The data series of the indicator line.
+ #/ The color of the indicator line.
+ #/ The name of the indicator.
+ #/ The XYChart object representing the chart created.
+ function addLineIndicator($height, $data, $color, $name) {
+ $c = $this->addIndicator($height);
+ $this->addLineIndicator2($c, $data, $color, $name);
+ return $c;
+ }
+
+ #/
+ #/ Add a line to an existing indicator chart.
+ #/
+ #/ The indicator chart to add the line to.
+ #/ The data series of the indicator line.
+ #/ The color of the indicator line.
+ #/ The name of the indicator.
+ #/ The LineLayer object representing the line created.
+ function addLineIndicator2(&$c, $data, $color, $name) {
+ return $c->addLineLayer($data, $color, $this->formatIndicatorLabel($name, $data));
+ }
+
+ #/
+ #/ Add a generic bar indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The data series of the indicator bars.
+ #/ The color of the indicator bars.
+ #/ The name of the indicator.
+ #/ The XYChart object representing the chart created.
+ function addBarIndicator($height, $data, $color, $name) {
+ $c = $this->addIndicator($height);
+ $this->addBarIndicator2($c, $data, $color, $name);
+ return $c;
+ }
+
+ #/
+ #/ Add a bar layer to an existing indicator chart.
+ #/
+ #/ The indicator chart to add the bar layer to.
+ #/ The data series of the indicator bars.
+ #/ The color of the indicator bars.
+ #/ The name of the indicator.
+ #/ The BarLayer object representing the bar layer created.
+ function addBarIndicator2(&$c, $data, $color, $name) {
+ $layer = $c->addBarLayer($data, $color, $this->formatIndicatorLabel($name, $data));
+ $layer->setBorderColor(Transparent);
+ return $layer;
+ }
+
+ #/
+ #/ Add an upper/lower threshold range to an existing indicator chart.
+ #/
+ #/ The indicator chart to add the threshold range to.
+ #/ The line layer that the threshold range applies to.
+ #/ The upper threshold.
+ #/ The color to fill the region of the line that is above the
+ #/ upper threshold.
+ #/ The lower threshold.
+ #/ The color to fill the region of the line that is below
+ #/ the lower threshold.
+ function addThreshold(&$c, &$layer, $topRange, $topColor, $bottomRange, $bottomColor) {
+ $topMark = $c->yAxis->addMark($topRange, $topColor, $this->formatValue($topRange,
+ $this->m_generalFormat));
+ $bottomMark = $c->yAxis->addMark($bottomRange, $bottomColor, $this->formatValue(
+ $bottomRange, $this->m_generalFormat));
+
+ $c->addInterLineLayer($layer->getLine(), $topMark->getLine(), $topColor, Transparent);
+ $c->addInterLineLayer($layer->getLine(), $bottomMark->getLine(), Transparent, $bottomColor);
+ }
+
+ function formatIndicatorLabel($name, $data) {
+ $i = $this->lastIndex($data);
+ if ($name == null) {
+ return $name;
+ }
+ if (($name == "") || ($i < 0)) {
+ return $name;
+ }
+ $ret = sprintf("%s: %s", $name, $this->formatValue($data[$i], $this->m_generalFormat));
+ return $ret;
+ }
+
+ #/
+ #/ Add an Accumulation/Distribution indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addAccDist($height, $color) {
+ #Close Location Value = ((C - L) - (H - C)) / (H - L)
+ #Accumulation Distribution Line = Accumulation of CLV * volume
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $range = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->mul(2);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $tmpArrayMath1->sub($this->m_highData);
+ $tmpArrayMath1->mul($this->m_volData);
+ $tmpArrayMath1->financeDiv($range, 0);
+ $tmpArrayMath1->acc();
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color,
+ "Accumulation/Distribution");
+ }
+
+ function computeAroonUp($period) {
+ $aroonUp = array_pad(array(), count($this->m_highData), 0);
+ for($i = 0; $i < count($this->m_highData); ++$i) {
+ $highValue = $this->m_highData[$i];
+ if ($highValue == NoValue) {
+ $aroonUp[$i] = NoValue;
+ } else {
+ $currentIndex = $i;
+ $highCount = $period;
+ $count = $period;
+
+ while (($count > 0) && ($currentIndex >= $count)) {
+ $currentIndex = $currentIndex - 1;
+ $currentValue = $this->m_highData[$currentIndex];
+ if ($currentValue != NoValue) {
+ $count = $count - 1;
+ if ($currentValue > $highValue) {
+ $highValue = $currentValue;
+ $highCount = $count;
+ }
+ }
+ }
+
+ if ($count > 0) {
+ $aroonUp[$i] = NoValue;
+ } else {
+ $aroonUp[$i] = $highCount * 100.0 / $period;
+ }
+ }
+ }
+
+ return $aroonUp;
+ }
+
+ function computeAroonDn($period) {
+ $aroonDn = array_pad(array(), count($this->m_lowData), 0);
+ for($i = 0; $i < count($this->m_lowData); ++$i) {
+ $lowValue = $this->m_lowData[$i];
+ if ($lowValue == NoValue) {
+ $aroonDn[$i] = NoValue;
+ } else {
+ $currentIndex = $i;
+ $lowCount = $period;
+ $count = $period;
+
+ while (($count > 0) && ($currentIndex >= $count)) {
+ $currentIndex = $currentIndex - 1;
+ $currentValue = $this->m_lowData[$currentIndex];
+ if ($currentValue != NoValue) {
+ $count = $count - 1;
+ if ($currentValue < $lowValue) {
+ $lowValue = $currentValue;
+ $lowCount = $count;
+ }
+ }
+ }
+
+ if ($count > 0) {
+ $aroonDn[$i] = NoValue;
+ } else {
+ $aroonDn[$i] = $lowCount * 100.0 / $period;
+ }
+ }
+ }
+
+ return $aroonDn;
+ }
+
+ #/
+ #/ Add an Aroon Up/Down indicators chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicators.
+ #/ The color of the Aroon Up indicator line.
+ #/ The color of the Aroon Down indicator line.
+ #/ The XYChart object representing the chart created.
+ function addAroon($height, $period, $upColor, $downColor) {
+ $c = $this->addIndicator($height);
+ $this->addLineIndicator2($c, $this->computeAroonUp($period), $upColor, "Aroon Up");
+ $this->addLineIndicator2($c, $this->computeAroonDn($period), $downColor, "Aroon Down");
+ $c->yAxis->setLinearScale(0, 100);
+ return $c;
+ }
+
+ #/
+ #/ Add an Aroon Oscillator indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addAroonOsc($height, $period, $color) {
+ $label = "Aroon Oscillator ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->computeAroonUp($period));
+ $tmpArrayMath1->sub($this->computeAroonDn($period));
+ $c = $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ $c->yAxis->setLinearScale(-100, 100);
+ return $c;
+ }
+
+ function computeTrueRange() {
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->shift();
+ $previousClose = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $ret = $tmpArrayMath1->result();
+ $temp = 0;
+
+ for($i = 0; $i < count($this->m_highData); ++$i) {
+ if (($ret[$i] != NoValue) && ($previousClose[$i] != NoValue)) {
+ $temp = abs($this->m_highData[$i] - $previousClose[$i]);
+ if ($temp > $ret[$i]) {
+ $ret[$i] = $temp;
+ }
+ $temp = abs($previousClose[$i] - $this->m_lowData[$i]);
+ if ($temp > $ret[$i]) {
+ $ret[$i] = $temp;
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ #/
+ #/ Add an Average Directional Index indicators chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the Positive Directional Index line.
+ #/ The color of the Negatuve Directional Index line.
+ #/ The color of the Average Directional Index line.
+ #/ The XYChart object representing the chart created.
+ function addADX($height, $period, $posColor, $negColor, $color) {
+ #pos/neg directional movement
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->delta();
+ $pos = $tmpArrayMath1->selectGTZ();
+ $tmpArrayMath1 = new ArrayMath($this->m_lowData);
+ $tmpArrayMath1->delta();
+ $tmpArrayMath1->mul(-1);
+ $neg = $tmpArrayMath1->selectGTZ();
+ $tmpArrayMath1 = new ArrayMath($pos->result());
+ $tmpArrayMath1->sub($neg->result());
+ $delta = $tmpArrayMath1->result();
+ $pos->selectGTZ($delta);
+ $neg->selectLTZ($delta);
+
+ #initial value
+ $posData = $pos->result();
+ $negData = $neg->result();
+ if ((count($posData) > 1) && ($posData[1] != NoValue) && ($negData[1] != NoValue)) {
+ $posData[1] = ($posData[1] * 2 + $negData[1]) / 3;
+ $negData[1] = ($negData[1] + $posData[1]) / 2;
+ $pos = new ArrayMath($posData);
+ $neg = new ArrayMath($negData);
+ }
+
+ #pos/neg directional index
+ $tr = $this->computeTrueRange();
+ $tmpArrayMath1 = new ArrayMath($tr);
+ $tmpArrayMath1->expAvg(1.0 / $period);
+ $tr = $tmpArrayMath1->result();
+ $expAvgObj = $pos->expAvg(1.0 / $period);
+ $financeDivObj = $expAvgObj->financeDiv($tr, 0);
+ $financeDivObj->mul(100);
+ $expAvgObj = $neg->expAvg(1.0 / $period);
+ $financeDivObj = $expAvgObj->financeDiv($tr, 0);
+ $financeDivObj->mul(100);
+
+ #directional movement index ??? what happen if division by zero???
+ $tmpArrayMath1 = new ArrayMath($pos->result());
+ $tmpArrayMath1->add($neg->result());
+ $totalDM = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($pos->result());
+ $tmpArrayMath1->sub($neg->result());
+ $tmpArrayMath1->abs();
+ $tmpArrayMath1->financeDiv($totalDM, 0);
+ $tmpArrayMath1->mul(100);
+ $dx = $tmpArrayMath1->expAvg(1.0 / $period);
+
+ $c = $this->addIndicator($height);
+ $label1 = "+DI ($period)";
+ $label2 = "-DI ($period)";
+ $label3 = "ADX ($period)";
+ $this->addLineIndicator2($c, $pos->result(), $posColor, $label1);
+ $this->addLineIndicator2($c, $neg->result(), $negColor, $label2);
+ $this->addLineIndicator2($c, $dx->result(), $color, $label3);
+ return $c;
+ }
+
+ #/
+ #/ Add an Average True Range indicators chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the True Range line.
+ #/ The color of the Average True Range line.
+ #/ The XYChart object representing the chart created.
+ function addATR($height, $period, $color1, $color2) {
+ $trueRange = $this->computeTrueRange();
+ $c = $this->addLineIndicator($height, $trueRange, $color1, "True Range");
+ $label = "Average True Range ($period)";
+ $tmpArrayMath1 = new ArrayMath($trueRange);
+ $tmpArrayMath1->expAvg(2.0 / ($period + 1));
+ $this->addLineIndicator2($c, $tmpArrayMath1->result(), $color2, $label);
+ return $c;
+ }
+
+ #/
+ #/ Add a Bollinger Band Width indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The band width to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addBollingerWidth($height, $period, $width, $color) {
+ $label = "Bollinger Width ($period, $width)";
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->movStdDev($period);
+ $tmpArrayMath1->mul($width * 2);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ }
+
+ #/
+ #/ Add a Community Channel Index indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The distance beween the middle line and the upper and lower threshold lines.
+ #/ The fill color when the indicator exceeds the upper threshold line.
+ #/ The fill color when the indicator falls below the lower threshold line.
+ #/ The XYChart object representing the chart created.
+ function addCCI($height, $period, $color, $deviation, $upColor, $downColor) {
+ #typical price
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->add($this->m_lowData);
+ $tmpArrayMath1->add($this->m_closeData);
+ $tmpArrayMath1->div(3);
+ $tp = $tmpArrayMath1->result();
+
+ #simple moving average of typical price
+ $tmpArrayMath1 = new ArrayMath($tp);
+ $tmpArrayMath1->movAvg($period);
+ $smvtp = $tmpArrayMath1->result();
+
+ #compute mean deviation
+ $movMeanDev = array_pad(array(), count($smvtp), 0);
+ for($i = 0; $i < count($smvtp); ++$i) {
+ $avg = $smvtp[$i];
+ if ($avg == NoValue) {
+ $movMeanDev[$i] = NoValue;
+ } else {
+ $currentIndex = $i;
+ $count = $period - 1;
+ $acc = 0;
+
+ while (($count >= 0) && ($currentIndex >= $count)) {
+ $currentValue = $tp[$currentIndex];
+ $currentIndex = $currentIndex - 1;
+ if ($currentValue != NoValue) {
+ $count = $count - 1;
+ $acc = $acc + abs($avg - $currentValue);
+ }
+ }
+
+ if ($count > 0) {
+ $movMeanDev[$i] = NoValue;
+ } else {
+ $movMeanDev[$i] = $acc / $period;
+ }
+ }
+ }
+
+ $c = $this->addIndicator($height);
+ $label = "CCI ($period)";
+ $tmpArrayMath1 = new ArrayMath($tp);
+ $tmpArrayMath1->sub($smvtp);
+ $tmpArrayMath1->financeDiv($movMeanDev, 0);
+ $tmpArrayMath1->div(0.015);
+ $layer = $this->addLineIndicator2($c, $tmpArrayMath1->result(), $color, $label);
+ $this->addThreshold($c, $layer, $deviation, $upColor, -$deviation, $downColor);
+ return $c;
+ }
+
+ #/
+ #/ Add a Chaikin Money Flow indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addChaikinMoneyFlow($height, $period, $color) {
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $range = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_volData);
+ $tmpArrayMath1->movAvg($period);
+ $volAvg = $tmpArrayMath1->result();
+ $label = "Chaikin Money Flow ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->mul(2);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $tmpArrayMath1->sub($this->m_highData);
+ $tmpArrayMath1->mul($this->m_volData);
+ $tmpArrayMath1->financeDiv($range, 0);
+ $tmpArrayMath1->movAvg($period);
+ $tmpArrayMath1->financeDiv($volAvg, 0);
+ return $this->addBarIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ }
+
+ #/
+ #/ Add a Chaikin Oscillator indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addChaikinOscillator($height, $color) {
+ #first compute acc/dist line
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $range = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->mul(2);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $tmpArrayMath1->sub($this->m_highData);
+ $tmpArrayMath1->mul($this->m_volData);
+ $tmpArrayMath1->financeDiv($range, 0);
+ $tmpArrayMath1->acc();
+ $accdist = $tmpArrayMath1->result();
+
+ #chaikin osc = exp3(accdist) - exp10(accdist)
+ $tmpArrayMath1 = new ArrayMath($accdist);
+ $tmpArrayMath1->expAvg(2.0 / (10 + 1));
+ $expAvg10 = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($accdist);
+ $tmpArrayMath1->expAvg(2.0 / (3 + 1));
+ $tmpArrayMath1->sub($expAvg10);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color,
+ "Chaikin Oscillator");
+ }
+
+ #/
+ #/ Add a Chaikin Volatility indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to smooth the range.
+ #/ The period to compute the rate of change of the smoothed range.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addChaikinVolatility($height, $period1, $period2, $color) {
+ $label = "Chaikin Volatility ($period1, $period2)";
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $tmpArrayMath1->expAvg(2.0 / ($period1 + 1));
+ $tmpArrayMath1->rate($period2);
+ $tmpArrayMath1->sub(1);
+ $tmpArrayMath1->mul(100);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ }
+
+ #/
+ #/ Add a Close Location Value indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addCLV($height, $color) {
+ #Close Location Value = ((C - L) - (H - C)) / (H - L)
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $range = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->mul(2);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $tmpArrayMath1->sub($this->m_highData);
+ $tmpArrayMath1->financeDiv($range, 0);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color,
+ "Close Location Value");
+ }
+
+ #/
+ #/ Add a Detrended Price Oscillator indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addDPO($height, $period, $color) {
+ $label = "DPO ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->movAvg($period);
+ $tmpArrayMath1->shift($period / 2 + 1);
+ $tmpArrayMath1->sub($this->m_closeData);
+ $tmpArrayMath1->mul(-1);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ }
+
+ #/
+ #/ Add a Donchian Channel Width indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addDonchianWidth($height, $period, $color) {
+ $label = "Donchian Width ($period)";
+ $tmpArrayMath2 = new ArrayMath($this->m_lowData);
+ $tmpArrayMath2->movMin($period);
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->movMax($period);
+ $tmpArrayMath1->sub($tmpArrayMath2->result());
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ }
+
+ #/
+ #/ Add a Ease of Movement indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to smooth the indicator.
+ #/ The color of the indicator line.
+ #/ The color of the smoothed indicator line.
+ #/ The XYChart object representing the chart created.
+ function addEaseOfMovement($height, $period, $color1, $color2) {
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $tmpArrayMath1->financeDiv($this->m_volData, 0);
+ $boxRatioInverted = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->add($this->m_lowData);
+ $tmpArrayMath1->div(2);
+ $tmpArrayMath1->delta();
+ $tmpArrayMath1->mul($boxRatioInverted);
+ $result = $tmpArrayMath1->result();
+
+ $c = $this->addLineIndicator($height, $result, $color1, "EMV");
+ $label = "EMV EMA ($period)";
+ $tmpArrayMath1 = new ArrayMath($result);
+ $tmpArrayMath1->movAvg($period);
+ $this->addLineIndicator2($c, $tmpArrayMath1->result(), $color2, $label);
+ return $c;
+ }
+
+ #/
+ #/ Add a Fast Stochastic indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the %K line.
+ #/ The period to compute the %D line.
+ #/ The color of the %K line.
+ #/ The color of the %D line.
+ #/ The XYChart object representing the chart created.
+ function addFastStochastic($height, $period1, $period2, $color1, $color2) {
+ $tmpArrayMath1 = new ArrayMath($this->m_lowData);
+ $tmpArrayMath1->movMin($period1);
+ $movLow = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->movMax($period1);
+ $tmpArrayMath1->sub($movLow);
+ $movRange = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->sub($movLow);
+ $tmpArrayMath1->financeDiv($movRange, 0.5);
+ $tmpArrayMath1->mul(100);
+ $stochastic = $tmpArrayMath1->result();
+
+ $label1 = "Fast Stochastic %K ($period1)";
+ $c = $this->addLineIndicator($height, $stochastic, $color1, $label1);
+ $label2 = "%D ($period2)";
+ $tmpArrayMath1 = new ArrayMath($stochastic);
+ $tmpArrayMath1->movAvg($period2);
+ $this->addLineIndicator2($c, $tmpArrayMath1->result(), $color2, $label2);
+
+ $c->yAxis->setLinearScale(0, 100);
+ return $c;
+ }
+
+ #/
+ #/ Add a MACD indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The first moving average period to compute the indicator.
+ #/ The second moving average period to compute the indicator.
+ #/ The moving average period of the signal line.
+ #/ The color of the indicator line.
+ #/ The color of the signal line.
+ #/ The color of the divergent bars.
+ #/ The XYChart object representing the chart created.
+ function addMACD($height, $period1, $period2, $period3, $color, $signalColor, $divColor) {
+ $c = $this->addIndicator($height);
+
+ #MACD is defined as the difference between two exponential averages (typically 12/26 days)
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->expAvg(2.0 / ($period1 + 1));
+ $expAvg1 = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->expAvg(2.0 / ($period2 + 1));
+ $tmpArrayMath1->sub($expAvg1);
+ $macd = $tmpArrayMath1->result();
+
+ #Add the MACD line
+ $label1 = "MACD ($period1, $period2)";
+ $this->addLineIndicator2($c, $macd, $color, $label1);
+
+ #MACD signal line
+ $tmpArrayMath1 = new ArrayMath($macd);
+ $tmpArrayMath1->expAvg(2.0 / ($period3 + 1));
+ $macdSignal = $tmpArrayMath1->result();
+ $label2 = "EXP ($period3)";
+ $this->addLineIndicator2($c, $macdSignal, $signalColor, $label2);
+
+ #Divergence
+ $tmpArrayMath1 = new ArrayMath($macd);
+ $tmpArrayMath1->sub($macdSignal);
+ $this->addBarIndicator2($c, $tmpArrayMath1->result(), $divColor, "Divergence");
+
+ return $c;
+ }
+
+ #/
+ #/ Add a Mass Index indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The color of the indicator line.
+ #/ The fill color when the indicator exceeds the upper threshold line.
+ #/ The fill color when the indicator falls below the lower threshold line.
+ #/ The XYChart object representing the chart created.
+ function addMassIndex($height, $color, $upColor, $downColor) {
+ #Mass Index
+ $f = 2.0 / (10);
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->sub($this->m_lowData);
+ $tmpArrayMath1->expAvg($f);
+ $exp9 = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($exp9);
+ $tmpArrayMath1->expAvg($f);
+ $exp99 = $tmpArrayMath1->result();
+
+ $tmpArrayMath1 = new ArrayMath($exp9);
+ $tmpArrayMath1->financeDiv($exp99, 1);
+ $tmpArrayMath1->movAvg(25);
+ $tmpArrayMath1->mul(25);
+ $c = $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, "Mass Index");
+ $c->yAxis->addMark(27, $upColor);
+ $c->yAxis->addMark(26.5, $downColor);
+ return $c;
+ }
+
+ #/
+ #/ Add a Money Flow Index indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The distance beween the middle line and the upper and lower threshold lines.
+ #/ The fill color when the indicator exceeds the upper threshold line.
+ #/ The fill color when the indicator falls below the lower threshold line.
+ #/ The XYChart object representing the chart created.
+ function addMFI($height, $period, $color, $range, $upColor, $downColor) {
+ #Money Flow Index
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->add($this->m_lowData);
+ $tmpArrayMath1->add($this->m_closeData);
+ $tmpArrayMath1->div(3);
+ $typicalPrice = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($typicalPrice);
+ $tmpArrayMath1->mul($this->m_volData);
+ $moneyFlow = $tmpArrayMath1->result();
+
+ $tmpArrayMath1 = new ArrayMath($typicalPrice);
+ $tmpArrayMath1->delta();
+ $selector = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($moneyFlow);
+ $tmpArrayMath1->selectGTZ($selector);
+ $tmpArrayMath1->movAvg($period);
+ $posMoneyFlow = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($moneyFlow);
+ $tmpArrayMath1->selectLTZ($selector);
+ $tmpArrayMath1->movAvg($period);
+ $tmpArrayMath1->add($posMoneyFlow);
+ $posNegMoneyFlow = $tmpArrayMath1->result();
+
+ $c = $this->addIndicator($height);
+ $label = "Money Flow Index ($period)";
+ $tmpArrayMath1 = new ArrayMath($posMoneyFlow);
+ $tmpArrayMath1->financeDiv($posNegMoneyFlow, 0.5);
+ $tmpArrayMath1->mul(100);
+ $layer = $this->addLineIndicator2($c, $tmpArrayMath1->result(), $color, $label);
+ $this->addThreshold($c, $layer, 50 + $range, $upColor, 50 - $range, $downColor);
+
+ $c->yAxis->setLinearScale(0, 100);
+ return $c;
+ }
+
+ #/
+ #/ Add a Momentum indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addMomentum($height, $period, $color) {
+ $label = "Momentum ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->delta($period);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ }
+
+ #/
+ #/ Add a Negative Volume Index indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the signal line.
+ #/ The color of the indicator line.
+ #/ The color of the signal line.
+ #/ The XYChart object representing the chart created.
+ function addNVI($height, $period, $color, $signalColor) {
+ $nvi = array_pad(array(), count($this->m_volData), 0);
+
+ $previousNVI = 100;
+ $previousVol = NoValue;
+ $previousClose = NoValue;
+ for($i = 0; $i < count($this->m_volData); ++$i) {
+ if ($this->m_volData[$i] == NoValue) {
+ $nvi[$i] = NoValue;
+ } else {
+ if (($previousVol != NoValue) && ($this->m_volData[$i] < $previousVol) && (
+ $previousClose != NoValue) && ($this->m_closeData[$i] != NoValue)) {
+ $nvi[$i] = $previousNVI + $previousNVI * ($this->m_closeData[$i] -
+ $previousClose) / $previousClose;
+ } else {
+ $nvi[$i] = $previousNVI;
+ }
+
+ $previousNVI = $nvi[$i];
+ $previousVol = $this->m_volData[$i];
+ $previousClose = $this->m_closeData[$i];
+ }
+ }
+
+ $c = $this->addLineIndicator($height, $nvi, $color, "NVI");
+ if (count($nvi) > $period) {
+ $label = "NVI SMA ($period)";
+ $tmpArrayMath1 = new ArrayMath($nvi);
+ $tmpArrayMath1->movAvg($period);
+ $this->addLineIndicator2($c, $tmpArrayMath1->result(), $signalColor, $label);
+ }
+ return $c;
+ }
+
+ #/
+ #/ Add an On Balance Volume indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addOBV($height, $color) {
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->delta();
+ $closeChange = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_volData);
+ $tmpArrayMath1->selectGTZ($closeChange);
+ $upVolume = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_volData);
+ $tmpArrayMath1->selectLTZ($closeChange);
+ $downVolume = $tmpArrayMath1->result();
+
+ $tmpArrayMath1 = new ArrayMath($upVolume);
+ $tmpArrayMath1->sub($downVolume);
+ $tmpArrayMath1->acc();
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, "OBV");
+ }
+
+ #/
+ #/ Add a Performance indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addPerformance($height, $color) {
+ $closeValue = $this->firstCloseValue();
+ if ($closeValue != NoValue) {
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->mul(100 / $closeValue);
+ $tmpArrayMath1->sub(100);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, "Performance")
+ ;
+ } else {
+ #chart is empty !!!
+ return $this->addIndicator($height);
+ }
+ }
+
+ #/
+ #/ Add a Percentage Price Oscillator indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The first moving average period to compute the indicator.
+ #/ The second moving average period to compute the indicator.
+ #/ The moving average period of the signal line.
+ #/ The color of the indicator line.
+ #/ The color of the signal line.
+ #/ The color of the divergent bars.
+ #/ The XYChart object representing the chart created.
+ function addPPO($height, $period1, $period2, $period3, $color, $signalColor, $divColor) {
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->expAvg(2.0 / ($period1 + 1));
+ $expAvg1 = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->expAvg(2.0 / ($period2 + 1));
+ $expAvg2 = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($expAvg2);
+ $tmpArrayMath1->sub($expAvg1);
+ $tmpArrayMath1->financeDiv($expAvg2, 0);
+ $ppo = $tmpArrayMath1->mul(100);
+ $tmpArrayMath1 = new ArrayMath($ppo->result());
+ $tmpArrayMath1->expAvg(2.0 / ($period3 + 1));
+ $ppoSignal = $tmpArrayMath1->result();
+
+ $label1 = "PPO ($period1, $period2)";
+ $label2 = "EMA ($period3)";
+ $c = $this->addLineIndicator($height, $ppo->result(), $color, $label1);
+ $this->addLineIndicator2($c, $ppoSignal, $signalColor, $label2);
+ $subtractObj = $ppo->sub($ppoSignal);
+ $this->addBarIndicator2($c, $subtractObj->result(), $divColor, "Divergence");
+ return $c;
+ }
+
+ #/
+ #/ Add a Positive Volume Index indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the signal line.
+ #/ The color of the indicator line.
+ #/ The color of the signal line.
+ #/ The XYChart object representing the chart created.
+ function addPVI($height, $period, $color, $signalColor) {
+ #Positive Volume Index
+ $pvi = array_pad(array(), count($this->m_volData), 0);
+
+ $previousPVI = 100;
+ $previousVol = NoValue;
+ $previousClose = NoValue;
+ for($i = 0; $i < count($this->m_volData); ++$i) {
+ if ($this->m_volData[$i] == NoValue) {
+ $pvi[$i] = NoValue;
+ } else {
+ if (($previousVol != NoValue) && ($this->m_volData[$i] > $previousVol) && (
+ $previousClose != NoValue) && ($this->m_closeData[$i] != NoValue)) {
+ $pvi[$i] = $previousPVI + $previousPVI * ($this->m_closeData[$i] -
+ $previousClose) / $previousClose;
+ } else {
+ $pvi[$i] = $previousPVI;
+ }
+
+ $previousPVI = $pvi[$i];
+ $previousVol = $this->m_volData[$i];
+ $previousClose = $this->m_closeData[$i];
+ }
+ }
+
+ $c = $this->addLineIndicator($height, $pvi, $color, "PVI");
+ if (count($pvi) > $period) {
+ $label = "PVI SMA ($period)";
+ $tmpArrayMath1 = new ArrayMath($pvi);
+ $tmpArrayMath1->movAvg($period);
+ $this->addLineIndicator2($c, $tmpArrayMath1->result(), $signalColor, $label);
+ }
+ return $c;
+ }
+
+ #/
+ #/ Add a Percentage Volume Oscillator indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The first moving average period to compute the indicator.
+ #/ The second moving average period to compute the indicator.
+ #/ The moving average period of the signal line.
+ #/ The color of the indicator line.
+ #/ The color of the signal line.
+ #/ The color of the divergent bars.
+ #/ The XYChart object representing the chart created.
+ function addPVO($height, $period1, $period2, $period3, $color, $signalColor, $divColor) {
+ $tmpArrayMath1 = new ArrayMath($this->m_volData);
+ $tmpArrayMath1->expAvg(2.0 / ($period1 + 1));
+ $expAvg1 = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_volData);
+ $tmpArrayMath1->expAvg(2.0 / ($period2 + 1));
+ $expAvg2 = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($expAvg2);
+ $tmpArrayMath1->sub($expAvg1);
+ $tmpArrayMath1->financeDiv($expAvg2, 0);
+ $pvo = $tmpArrayMath1->mul(100);
+ $tmpArrayMath1 = new ArrayMath($pvo->result());
+ $tmpArrayMath1->expAvg(2.0 / ($period3 + 1));
+ $pvoSignal = $tmpArrayMath1->result();
+
+ $label1 = "PVO ($period1, $period2)";
+ $label2 = "EMA ($period3)";
+ $c = $this->addLineIndicator($height, $pvo->result(), $color, $label1);
+ $this->addLineIndicator2($c, $pvoSignal, $signalColor, $label2);
+ $subtractObj = $pvo->sub($pvoSignal);
+ $this->addBarIndicator2($c, $subtractObj->result(), $divColor, "Divergence");
+ return $c;
+ }
+
+ #/
+ #/ Add a Price Volumne Trend indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addPVT($height, $color) {
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->rate();
+ $tmpArrayMath1->sub(1);
+ $tmpArrayMath1->mul($this->m_volData);
+ $tmpArrayMath1->acc();
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, "PVT");
+ }
+
+ #/
+ #/ Add a Rate of Change indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addROC($height, $period, $color) {
+ $label = "ROC ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->rate($period);
+ $tmpArrayMath1->sub(1);
+ $tmpArrayMath1->mul(100);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ }
+
+ function RSIMovAvg($data, $period) {
+ #The "moving average" in classical RSI is based on a formula that mixes simple
+ #and exponential moving averages.
+
+ if ($period <= 0) {
+ $period = 1;
+ }
+
+ $count = 0;
+ $acc = 0;
+
+ for($i = 0; $i < count($data); ++$i) {
+ if (abs($data[$i] / NoValue - 1) > 1e-005) {
+ $count = $count + 1;
+ $acc = $acc + $data[$i];
+ if ($count < $period) {
+ $data[$i] = NoValue;
+ } else {
+ $data[$i] = $acc / $period;
+ $acc = $data[$i] * ($period - 1);
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ function computeRSI($period) {
+ #RSI is defined as the average up changes for the last 14 days, divided by the
+ #average absolute changes for the last 14 days, expressed as a percentage.
+
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->delta();
+ $tmpArrayMath1->abs();
+ $absChange = $this->RSIMovAvg($tmpArrayMath1->result(), $period);
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->delta();
+ $tmpArrayMath1->selectGTZ();
+ $absUpChange = $this->RSIMovAvg($tmpArrayMath1->result(), $period);
+ $tmpArrayMath1 = new ArrayMath($absUpChange);
+ $tmpArrayMath1->financeDiv($absChange, 0.5);
+ $tmpArrayMath1->mul(100);
+ return $tmpArrayMath1->result();
+ }
+
+ #/
+ #/ Add a Relative Strength Index indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The distance beween the middle line and the upper and lower threshold lines.
+ #/ The fill color when the indicator exceeds the upper threshold line.
+ #/ The fill color when the indicator falls below the lower threshold line.
+ #/ The XYChart object representing the chart created.
+ function addRSI($height, $period, $color, $range, $upColor, $downColor) {
+ $c = $this->addIndicator($height);
+ $label = "RSI ($period)";
+ $layer = $this->addLineIndicator2($c, $this->computeRSI($period), $color, $label);
+
+ #Add range if given
+ if (($range > 0) && ($range < 50)) {
+ $this->addThreshold($c, $layer, 50 + $range, $upColor, 50 - $range, $downColor);
+ }
+ $c->yAxis->setLinearScale(0, 100);
+ return $c;
+ }
+
+ #/
+ #/ Add a Slow Stochastic indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the %K line.
+ #/ The period to compute the %D line.
+ #/ The color of the %K line.
+ #/ The color of the %D line.
+ #/ The XYChart object representing the chart created.
+ function addSlowStochastic($height, $period1, $period2, $color1, $color2) {
+ $tmpArrayMath1 = new ArrayMath($this->m_lowData);
+ $tmpArrayMath1->movMin($period1);
+ $movLow = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->movMax($period1);
+ $tmpArrayMath1->sub($movLow);
+ $movRange = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->sub($movLow);
+ $tmpArrayMath1->financeDiv($movRange, 0.5);
+ $tmpArrayMath1->mul(100);
+ $stochastic = $tmpArrayMath1->movAvg(3);
+
+ $label1 = "Slow Stochastic %K ($period1)";
+ $label2 = "%D ($period2)";
+ $c = $this->addLineIndicator($height, $stochastic->result(), $color1, $label1);
+ $movAvgObj = $stochastic->movAvg($period2);
+ $this->addLineIndicator2($c, $movAvgObj->result(), $color2, $label2);
+
+ $c->yAxis->setLinearScale(0, 100);
+ return $c;
+ }
+
+ #/
+ #/ Add a Moving Standard Deviation indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addStdDev($height, $period, $color) {
+ $label = "Moving StdDev ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->movStdDev($period);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ }
+
+ #/
+ #/ Add a Stochastic RSI indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The distance beween the middle line and the upper and lower threshold lines.
+ #/ The fill color when the indicator exceeds the upper threshold line.
+ #/ The fill color when the indicator falls below the lower threshold line.
+ #/ The XYChart object representing the chart created.
+ function addStochRSI($height, $period, $color, $range, $upColor, $downColor) {
+ $rsi = $this->computeRSI($period);
+ $tmpArrayMath1 = new ArrayMath($rsi);
+ $tmpArrayMath1->movMin($period);
+ $movLow = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($rsi);
+ $tmpArrayMath1->movMax($period);
+ $tmpArrayMath1->sub($movLow);
+ $movRange = $tmpArrayMath1->result();
+
+ $c = $this->addIndicator($height);
+ $label = "StochRSI ($period)";
+ $tmpArrayMath1 = new ArrayMath($rsi);
+ $tmpArrayMath1->sub($movLow);
+ $tmpArrayMath1->financeDiv($movRange, 0.5);
+ $tmpArrayMath1->mul(100);
+ $layer = $this->addLineIndicator2($c, $tmpArrayMath1->result(), $color, $label);
+
+ #Add range if given
+ if (($range > 0) && ($range < 50)) {
+ $this->addThreshold($c, $layer, 50 + $range, $upColor, 50 - $range, $downColor);
+ }
+ $c->yAxis->setLinearScale(0, 100);
+ return $c;
+ }
+
+ #/
+ #/ Add a TRIX indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The XYChart object representing the chart created.
+ function addTRIX($height, $period, $color) {
+ $f = 2.0 / ($period + 1);
+ $label = "TRIX ($period)";
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->expAvg($f);
+ $tmpArrayMath1->expAvg($f);
+ $tmpArrayMath1->expAvg($f);
+ $tmpArrayMath1->rate();
+ $tmpArrayMath1->sub(1);
+ $tmpArrayMath1->mul(100);
+ return $this->addLineIndicator($height, $tmpArrayMath1->result(), $color, $label);
+ }
+
+ function computeTrueLow() {
+ #the lower of today's low or yesterday's close.
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->shift();
+ $previousClose = $tmpArrayMath1->result();
+ $ret = array_pad(array(), count($this->m_lowData), 0);
+ for($i = 0; $i < count($this->m_lowData); ++$i) {
+ if (($this->m_lowData[$i] != NoValue) && ($previousClose[$i] != NoValue)) {
+ if ($this->m_lowData[$i] < $previousClose[$i]) {
+ $ret[$i] = $this->m_lowData[$i];
+ } else {
+ $ret[$i] = $previousClose[$i];
+ }
+ } else {
+ $ret[$i] = NoValue;
+ }
+ }
+
+ return $ret;
+ }
+
+ #/
+ #/ Add an Ultimate Oscillator indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The first moving average period to compute the indicator.
+ #/ The second moving average period to compute the indicator.
+ #/ The third moving average period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The distance beween the middle line and the upper and lower threshold lines.
+ #/ The fill color when the indicator exceeds the upper threshold line.
+ #/ The fill color when the indicator falls below the lower threshold line.
+ #/ The XYChart object representing the chart created.
+ function addUltimateOscillator($height, $period1, $period2, $period3, $color, $range, $upColor,
+ $downColor) {
+ $trueLow = $this->computeTrueLow();
+ $tmpArrayMath1 = new ArrayMath($this->m_closeData);
+ $tmpArrayMath1->sub($trueLow);
+ $buyingPressure = $tmpArrayMath1->result();
+ $trueRange = $this->computeTrueRange();
+
+ $tmpArrayMath2 = new ArrayMath($trueRange);
+ $tmpArrayMath2->movAvg($period1);
+ $tmpArrayMath1 = new ArrayMath($buyingPressure);
+ $tmpArrayMath1->movAvg($period1);
+ $tmpArrayMath1->financeDiv($tmpArrayMath2->result(), 0.5);
+ $tmpArrayMath1->mul(4);
+ $rawUO1 = $tmpArrayMath1->result();
+ $tmpArrayMath2 = new ArrayMath($trueRange);
+ $tmpArrayMath2->movAvg($period2);
+ $tmpArrayMath1 = new ArrayMath($buyingPressure);
+ $tmpArrayMath1->movAvg($period2);
+ $tmpArrayMath1->financeDiv($tmpArrayMath2->result(), 0.5);
+ $tmpArrayMath1->mul(2);
+ $rawUO2 = $tmpArrayMath1->result();
+ $tmpArrayMath2 = new ArrayMath($trueRange);
+ $tmpArrayMath2->movAvg($period3);
+ $tmpArrayMath1 = new ArrayMath($buyingPressure);
+ $tmpArrayMath1->movAvg($period3);
+ $tmpArrayMath1->financeDiv($tmpArrayMath2->result(), 0.5);
+ $tmpArrayMath1->mul(1);
+ $rawUO3 = $tmpArrayMath1->result();
+
+ $c = $this->addIndicator($height);
+ $label = "Ultimate Oscillator ($period1, $period2, $period3)";
+ $tmpArrayMath1 = new ArrayMath($rawUO1);
+ $tmpArrayMath1->add($rawUO2);
+ $tmpArrayMath1->add($rawUO3);
+ $tmpArrayMath1->mul(100.0 / 7);
+ $layer = $this->addLineIndicator2($c, $tmpArrayMath1->result(), $color, $label);
+ $this->addThreshold($c, $layer, 50 + $range, $upColor, 50 - $range, $downColor);
+
+ $c->yAxis->setLinearScale(0, 100);
+ return $c;
+ }
+
+ #/
+ #/ Add a Volume indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The color to used on an 'up' day. An 'up' day is a day where
+ #/ the closing price is higher than that of the previous day.
+ #/ The color to used on a 'down' day. A 'down' day is a day
+ #/ where the closing price is lower than that of the previous day.
+ #/ The color to used on a 'flat' day. A 'flat' day is a day
+ #/ where the closing price is the same as that of the previous day.
+ #/ The XYChart object representing the chart created.
+ function addVolIndicator($height, $upColor, $downColor, $flatColor) {
+ $c = $this->addIndicator($height);
+ $this->addVolBars2($c, $height, $upColor, $downColor, $flatColor);
+ return $c;
+ }
+
+ #/
+ #/ Add a William %R indicator chart.
+ #/
+ #/ The height of the indicator chart in pixels.
+ #/ The period to compute the indicator.
+ #/ The color of the indicator line.
+ #/ The distance beween the middle line and the upper and lower threshold lines.
+ #/ The fill color when the indicator exceeds the upper threshold line.
+ #/ The fill color when the indicator falls below the lower threshold line.
+ #/ The XYChart object representing the chart created.
+ function addWilliamR($height, $period, $color, $range, $upColor, $downColor) {
+ $tmpArrayMath1 = new ArrayMath($this->m_lowData);
+ $tmpArrayMath1->movMin($period);
+ $movLow = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($this->m_highData);
+ $tmpArrayMath1->movMax($period);
+ $movHigh = $tmpArrayMath1->result();
+ $tmpArrayMath1 = new ArrayMath($movHigh);
+ $tmpArrayMath1->sub($movLow);
+ $movRange = $tmpArrayMath1->result();
+
+ $c = $this->addIndicator($height);
+ $tmpArrayMath1 = new ArrayMath($movHigh);
+ $tmpArrayMath1->sub($this->m_closeData);
+ $tmpArrayMath1->financeDiv($movRange, 0.5);
+ $tmpArrayMath1->mul(-100);
+ $layer = $this->addLineIndicator2($c, $tmpArrayMath1->result(), $color, "William %R");
+ $this->addThreshold($c, $layer, -50 + $range, $upColor, -50 - $range, $downColor);
+ $c->yAxis->setLinearScale(-100, 0);
+ return $c;
+ }
+}
diff --git a/library/Vendors/ChartDirector/README.TXT b/library/Vendors/ChartDirector/README.TXT
new file mode 100644
index 0000000..df77210
--- /dev/null
+++ b/library/Vendors/ChartDirector/README.TXT
@@ -0,0 +1,5 @@
+- Récupérer l'extension de ChartDirector pour PHP et le placer dans le répertoire des extensions
+- Copier le répertoire "fonts" dans le répertoire des extensions PHP
+ Attention, pour que les fonts soient accessible placer le répertoire des extensions en chmod 755
+- Placer la clé dans le répertoire des extensions PHP
+
diff --git a/library/Vendors/ChartDirector/phpchartdir.php b/library/Vendors/ChartDirector/phpchartdir.php
new file mode 100644
index 0000000..ad12ef7
--- /dev/null
+++ b/library/Vendors/ChartDirector/phpchartdir.php
@@ -0,0 +1,3719 @@
+Trying to load "'.$ext.'" from the PHP extension directory '.listExtDir().'. ';
+ @cdSetHint(ini_get("extension_dir"));
+ if (dl($ext))
+ return true;
+
+ $ver = explode('.', phpversion());
+ $ver = $ver[0] * 10000 + $ver[1] * 100 + $ver[2];
+ if ((!$cdDebug) && ($ver >= 50205))
+ return false;
+
+ $scriptPath = dirname(__FILE__);
+ $tryPath = getRelExtPath($scriptPath);
+ if (!$tryPath)
+ return false;
+
+ if ($cdDebug || (error_reporting() != 0))
+ echo ' Trying to load "'.$ext.'" from '.listRelExtDir($scriptPath).'. ';
+ @cdSetHint($scriptPath);
+ return dl($tryPath."/$ext");
+}
+
+function cdFilterMsg($msg)
+{
+ global $cdRelOp;
+ for ($j = 0; $j <= 10; ++$j)
+ {
+ $pos = strpos($msg, $cdRelOp);
+ if ($pos === false)
+ return $msg;
+ for ($i = $pos - 1; $i >= 0; --$i)
+ {
+ if (strstr(" \t\n\r'\"", $msg{$i}))
+ break;
+ }
+ $msg = substr($msg, 0, $i + 1)."/".substr($msg, $pos + strlen($cdRelOp));
+ }
+
+ return $msg;
+}
+
+function listExtDir()
+{
+ $extdir = ini_get("extension_dir");
+ if (($extdir{0} != "/") && ($extdir{0} != "\\") && ($extdir{1} != ":"))
+ return '"'.$extdir.'" (note: directory ambiguous)';
+ elseif (isOnWindows() && ($extdir{1} != ":"))
+ return '"'.$extdir.'" (note: drive ambiguous)';
+ else
+ return '"'.$extdir.'"';
+}
+
+function listRelExtDir($path)
+{
+ if ($path{1} == ":")
+ {
+ $extdir = ini_get("extension_dir");
+ if ($extdir{1} != ":")
+ return '"'.substr($path, 2).'" (note: drive ambiguous)';
+ }
+ return '"'.$path.'"';
+}
+
+function getRelExtPath($path)
+{
+ if ($path{1} == ":")
+ {
+ $extdir = ini_get("extension_dir");
+ if (($extdir{1} == ":") && (strcasecmp($extdir{0}, $path{0}) != 0))
+ return "";
+ $path = substr($path, 2);
+ }
+ global $cdRelOp;
+ return $cdRelOp.substr($path, 1);
+}
+
+function cdErrorHandler($errno, $errstr, $errfile, $errline)
+{
+ global $cdDebug;
+ if ($cdDebug || ((error_reporting() != 0) && (($errno & 0x3F7) != 0)))
+ echo " ".cdFilterMsg($errstr)." ";
+}
+
+if (!extension_loaded("ChartDirector PHP API"))
+{
+ $ver = explode('.', phpversion());
+ $ver = $ver[0] * 10000 + $ver[1] * 100 + $ver[2];
+
+ if ($ver >= 50400)
+ $ext = "phpchartdir540.dll";
+ else if ($ver >= 50300)
+ $ext = "phpchartdir530.dll";
+ else if ($ver >= 50200)
+ $ext = "phpchartdir520.dll";
+ else if ($ver >= 50100)
+ $ext = "phpchartdir510.dll";
+ else if ($ver >= 50003)
+ $ext = "phpchartdir503.dll";
+ else if ($ver >= 50000)
+ $ext = "phpchartdir500.dll";
+ else if ($ver >= 40201)
+ $ext = "phpchartdir421.dll";
+ else if ($ver >= 40100)
+ $ext = "phpchartdir410.dll";
+ else if ($ver >= 40005)
+ $ext = "phpchartdir405.dll";
+ else if ($ver >= 40004)
+ $ext = "phpchartdir404.dll";
+ else
+ user_error("ChartDirector requires PHP 4.0.4 or above, but the current PHP version is ".phpversion().".", E_USER_ERROR);
+
+ $old_error_handler = set_error_handler("cdErrorHandler");
+ $old_html_errors = ini_set("html_errors", "0");
+ ob_start();
+?>
+
+Error Loading ChartDirector for PHP Extension
+
+It appears this PHP system has not loaded the ChartDirector extension by using an extension
+statement in the PHP configuration file (typically called "php.ini"). An attempt has been made
+to dynamically load ChartDirector on the fly, but it was not successful. Please refer to the
+Installation section of the ChartDirector for PHP documentation on how to resolve this problem.
+
Error Log
+ 1) && (($ver < 50300) || (!isOnWindows())))
+ $success = @cdLoadDLL($extList[1]);
+ }
+ else
+ $success = false;
+
+ if ($success)
+ {
+ $dllVersion = (callmethod("getVersion") >> 16) & 0x7fff;
+ if ($dllVersion != $cdPhpVersion)
+ {
+ echo ' Version mismatch: "phpchartdir.php" is of version '.($cdPhpVersion >> 8).
+ '.'.($cdPhpVersion & 0xff).', but "'.(isOnWindows() ? "chartdir.dll" : "libchartdir.so").
+ '" is of version '.($dllVersion >> 8).'.'.($dllVersion & 0xff).'. ';
+ $success = 0;
+ }
+ }
+
+ ini_set("html_errors", $old_html_errors);
+ restore_error_handler();
+ if ($success)
+ ob_end_clean();
+ else
+ ob_end_flush();
+
+ if (!$success)
+ {
+ if ($hasDL)
+ {
+ $dir_valid = 1;
+ if (!isOnWindows())
+ {
+ $dir_valid = @opendir(ini_get("extension_dir"));
+ if ($dir_valid)
+ closedir($dir_valid);
+ }
+
+ if (!$dir_valid)
+ {
+?>
+
+
+It appears the PHP extension directory of this system is configured as ,
+but this directory does not exist or is inaccessible. PHP will then refuse to load extensions from
+any directory due to invalid directory configuration. Please ensure that directory exists and is
+accessible by the web server.
+
+
+The version and type of PHP in this system does not support dynmaic loading of PHP extensions. All
+PHP extensions must be loaded by using extension statements in the PHP configuration file.
+
+