0.0.4 • Published 7 years ago

portfolio-analytics v0.0.4

Weekly downloads
24
License
MIT
Repository
github
Last release
7 years ago

PortfolioAnalytics v0.0.4 (Changelog)

Travis Build Status

Pour le suivi des performances de mes stratégies d'investissement en bourse, ainsi que pour l'analyse des stratégies que je publie sur mon blog Le Quant 40, j'avais besoin de fonctions de mesures de performances de portefeuille en JavaScript.

Pourquoi en JavaScript ? Principalement parce que je suis un utilisateur inconditionel de Google Sheets, qui est facilement extensible grâce à Google Apps Script, un language dérivé du JavaScript.

Après avoir cherché en vain mon bonheur sur Internet (codes incomplets, ou avec trop de dépendances, ou non documentés, ou comportant beaucoup d'erreurs...), j'ai décidé de créer ma propre bibliothèque de fonctions, en espérant qu'elle puisse être utile à quelqu'un d'autre que moi...

Caractéristiques

  • Compatible avec Google Sheets
  • Compatible avec les navigateurs supportant le ECMAScript 5 (i.e., développement front-end)
  • Compatible avec Node.js (i.e., développement back-end)
  • (Performances) Utilisation automatique des tableaux typés JavaScript
  • (Précision) Utilisation de méthodes numériques précises (algorithmes corrigés en deux passes pour le calcul de la moyenne, de la variance, de l'asymétrie, de l'aplatissement, algorithme précis pour le calcul de la fonction d'erreur...)
  • Code testé et intégré de manière continue avec Travis CI
  • Code documenté avec JSDoc

Utilisation

Utilisation avec Google Sheets

Si vous souhaitez utiliser PortfolioAnalytics avec Google Sheets dans vos feuilles de calcul, vous pouvez soit :

ou soit :

Dans les deux cas, vous pouvez ensuite appeler les fonctions de PortfolioAnalytics de la manière que vous préferez :

  • En utilisant une fonction qui encapsule ces appels, fonction qui est directement accessible depuis votre feuille de calcul et à laquelle vous pouvez donc fournir une plage de données quelconque (A1:A99...), e.g.:
function computeUlcerIndexWrapper(iEquityCurveRange) {
  // La plage d'entree est convertie en tableau
  var aInternalArray = [];
  for (var i=0; i<iEquityCurveRange.length; ++i) {
    aInternalArray.push(iEquityCurveRange[i][0]);
  }
    
  // Calcul de l'index par PortfolioAnalytics
  var ulcerIndex = PortfolioAnalytics.ulcerIndex(aInternalArray);
  
  // Renvoi de cet index a la feuille de calcul
  return ulcerIndex;
}
  • En utilisant des fonctions internes à Google Apps Script - typiquement la famille de fonctions getRange(...) -, qui sont optimisées pour les performances, e.g.:
function computeUlcerIndex() {
  // Adapte de https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow-column-numrows
 var ss = SpreadsheetApp.getActiveSpreadsheet();
 var sheet = ss.getSheets()[0];
 var range = sheet.getRange(1, 1, 100); // A1:A100
 var values = range.getValues();

 // Conversion de la plage ci-dessus en tableau
 var aInternalArray = [];
 for (var row in values) {
   for (var col in values[row]) {
     aInternalArray.push(values[row][col]);
   }
 }
 
  // Calcul de l'index
  var ulcerIndex = PortfolioAnalytics.ulcerIndex(aInternalArray);
  
  // Utilisation de l'index (nouveau calcul, ecriture dans la feuille de calcul...)
  ...
}

Vous trouverez des exemples d'utilisation dans cette feuille de calcul.

Utilisation avec un navigateur

Si vous souhaitez utiliser PortfolioAnalytics avec un navigateur, vous pouvez télécharger le code source et/ou le code source minifié.

Il vous suffit ensuite d'inclure ce code dans une page HTML, par exemple :

<script src="portfolio_analytics.dist.min.js" type="text/javascript"></script>

A noter que si le navigateur prend en charge les tableaux typés JavaScript, vous pouvez utiliser ces tableaux avec PortfolioAnalytics pour de meilleures performances, par exemple :

PortfolioAnalytics.arithmeticReturns(new Float64Array([100.0, 109.75, 111.25]))
// Le type de retour sera un Float64Array

Utilisation avec Node.js

Si vous souhaitez utiliser PortfolioAnalytics avec Node.js, vous devez simplement déclarer ce module comme dépendance dans votre fichier package.json.

Le reste est du code Node.js standard, e.g. :

var PortfolioAnalytics = require('portfolio-analytics');
...
var ui = PortfolioAnalytics.ulcerIndex([100, 110, 105, 102, 95]);
// ui == 0.07204222820421435

Exemples

Mesures liées aux pertes (drawdowns)

PortfolioAnalytics.maxDrawdown([1, 2, 1]); 
// == La perte maximale (maximum drawdown)

PortfolioAnalytics.drawdownFunction([1, 2, 1]); 
// == La fonction de pertes (drawdown function)

PortfolioAnalytics.topDrawdowns([1, 2, 1], 1); 
// == Les 'n' pertes maximales (second largest drawdown, etc.) avec leurs indexes de début/fin

PortfolioAnalytics.ulcerIndex([1, 2, 1]);
// == L'Ulcer Index

PortfolioAnalytics.painIndex([1, 2, 1]);
// == Le Pain Index, qui correspond aussi à la valeur moyenne de la fonction de pertes

PortfolioAnalytics.conditionalDrawdown([100, 90, 80], 0.5);
// == La perte conditionelle (conditional drawdown)

Mesures liées aux rendements

PortfolioAnalytics.cumulativeReturn([1, 2, 1]); 
// Le rendement cumulé de la première à la dernière période

PortfolioAnalytics.cagr([1, 2, 1], [new Date("2015-12-31"), new Date("2016-12-31"), new Date("2017-12-31")]); 
// Le taux de croissance annuel composé (CAGR) de la première à la dernière date

PortfolioAnalytics.arithmeticReturns([1, 2, 1]); 
// Les rendements arithmétiques pour toutes les périodes

PortfolioAnalytics.valueAtRisk([1, 2, 1], 0.7);
// La valeur à risque en pourcentage (value at risk)

Mesures liéesau ratio de Sharpe

PortfolioAnalytics.sharpeRatio([100, 110, 105, 107.5, 115], [100, 100, 100, 100, 100]); 
// Le ratio de Sharpe

PortfolioAnalytics.biasAdjustedSharpeRatio([100, 110, 105, 107.5, 115], [100, 100, 100, 100, 100]); 
// Le ratio de Sharpe ajusté de son biais

PortfolioAnalytics.doubleSharpeRatio([100, 110, 105, 107.5, 115], [100, 100, 100, 100, 100]); 
// Le double ratio de Sharpe (i.e., le ratio de Sharpe ajusté de son risque d'estimation)

PortfolioAnalytics.sharpeRatioConfidenceInterval([100, 110, 105, 107.5, 115], [100, 100, 100, 100, 100], 0.05); 
// L'intervalle de confiance du ratio de Sharpe (ici, à un niveau de significativité de 5%)

PortfolioAnalytics.probabilisticSharpeRatio([100, 110, 105, 107.5, 115], [100, 100, 100, 100, 100], 0); 
// Le ratio de Sharpe probabilistique (i.e., la probabilité que le ratio de Sharpe soit plus grand qu'un
// ratio de Sharpe de référence, ici 0)

PortfolioAnalytics.minimumTrackRecordLength([100, 110, 105, 107.5, 115], [100, 100, 100, 100, 100], 0.05, 0); 
// La longueur minimale de l'historique des performances (i.e., la longueur minimale de l'historique des performances
// nécessaire à avoir confiance statistiquement, ici à 95%, que le ratio de Sharpe est plus grand qu'un ratio
// de Sharpe de référence).

Mesures liées aux rendements par rapport à la variabilité

PortfolioAnalytics.gainToPainRatio([1, 2, 1]); 
// Le ratio gain to pain

Comment contribuer ?

Forker le projet depuis Github...

Installer les dépendances Grunt

npm install

Développer...

Compiler

  • La commande suivante génère les fichiers à utiliser dans un navigateur ou avec Node.js dans le répertoire dist :
grunt deliver
  • La commande suivante génère les fichiers à utiliser avec Google Sheets dans le répertoire dist\gs :
grunt deliver-gs

Tester

L'une ou l'autre des deux commandes suivantes exécute les tests unitaires QUnit du répertoire test sur le fichier généré dist\portfolio_analytics.dev.min.js :

npm test
grunt test

Soumettre une pull-request...

License

License MIT