portfolio-analytics
v0.0.4
Published
A JavaScript library to track and measure stock market portfolio performances.
Downloads
868
Maintainers
Readme
PortfolioAnalytics v0.0.4 (Changelog)
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 :
- (Solution recommandée) Importer la bibliothèque externe de Script ID 1NXwj16pdgcJT-XG5LiWRJyRW604Dj26U4lqgGsJJfOKLum4y9grakXPI
ou soit :
- Importer les fichiers JavaScript contenus dans le répertoire dist/gs
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