Skip to content

Instantly share code, notes, and snippets.

@cesarvargas00
Last active November 3, 2020 23:08
Show Gist options
  • Select an option

  • Save cesarvargas00/0a3d765cea51df8b04c37fee09690a3e to your computer and use it in GitHub Desktop.

Select an option

Save cesarvargas00/0a3d765cea51df8b04c37fee09690a3e to your computer and use it in GitHub Desktop.

Revisions

  1. cesarvargas00 revised this gist Nov 3, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion markowitz.js
    Original file line number Diff line number Diff line change
    @@ -48,7 +48,7 @@ function markowitz(portfolio) {
    const variance = returns.reduce((acc, r) => (r - mean) ** 2 + acc, 0) / n
    const stdev = variance ** 0.5
    const close = portfolio[i].returns[portfolio[i].returns.length-1]
    assets.push({ symbol, returns, amount, mean, variance, stdev, close })
    assets.push({ portfolio[i].symbol, returns, portfolio[i].amount, mean, variance, stdev, close })
    }

    const correlations = {}
  2. cesarvargas00 revised this gist Nov 3, 2020. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions markowitz.js
    Original file line number Diff line number Diff line change
    @@ -33,22 +33,22 @@ function covariancesFromCorrelations(correlations, stdevs) {
    {}
    )
    }
    // portfolio = [{symbol, returns, amount}]
    // portfolio = [{symbol, closes, amount}]
    function markowitz(portfolio) {
    const assets = []
    let assets = []
    for (let i = 0; i < portfolio.length; i++) {
    const returns = []
    for (let i = 1; i < portfolio.returns.length; i++) {
    for (let j = 1; j < portfolio[i].closes.length; j++) {
    returns.push(
    Math.log(portfolio.returns[i] / portfolio.returns[i-1])
    Math.log(portfolio[i].closes[j] / portfolio[i].closes[j-1])
    )
    }
    const n = returns.length
    const mean = returns.reduce((acc, r) => r + acc, 0) / n
    const variance = returns.reduce((acc, r) => (r - mean) ** 2 + acc, 0) / n
    const stdev = variance ** 0.5
    const close = data[data.length - 1]
    returns.push({ symbol, returns, amount, mean, variance, stdev, close })
    const close = portfolio[i].returns[portfolio[i].returns.length-1]
    assets.push({ symbol, returns, amount, mean, variance, stdev, close })
    }

    const correlations = {}
  3. cesarvargas00 revised this gist Oct 29, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion markowitz.js
    Original file line number Diff line number Diff line change
    @@ -40,7 +40,7 @@ function markowitz(portfolio) {
    const returns = []
    for (let i = 1; i < portfolio.returns.length; i++) {
    returns.push(
    Math.log(portfolio.returns[i-1] / portfolio.returns[i])
    Math.log(portfolio.returns[i] / portfolio.returns[i-1])
    )
    }
    const n = returns.length
  4. cesarvargas00 revised this gist Oct 29, 2020. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions markowitz.js
    Original file line number Diff line number Diff line change
    @@ -40,8 +40,7 @@ function markowitz(portfolio) {
    const returns = []
    for (let i = 1; i < portfolio.returns.length; i++) {
    returns.push(
    (portfolio.returns[i] - portfolio.returns[i - 1]) /
    portfolio.returns[i - 1]
    Math.log(portfolio.returns[i-1] / portfolio.returns[i])
    )
    }
    const n = returns.length
  5. cesarvargas00 revised this gist Oct 29, 2020. 1 changed file with 4 additions and 6 deletions.
    10 changes: 4 additions & 6 deletions markowitz.js
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,8 @@
    function correlation(x, xMean, y, yMean) {
    function correlation(x, y) {
    if (x.length !== y.length) return null

    xMean = xMean / x.length
    yMean = yMean / y.length
    const xMean = x.reduce((acc, el) => el + acc, 0) / x.length
    const yMean = y.reduce((acc, el) => el + acc, 0) / y.length

    let numerator = 0,
    xDSquaredSum = 0,
    @@ -60,9 +60,7 @@ function markowitz(portfolio) {
    }
    correlations[assets[i].symbol][assets[j].symbol] = correlation(
    assets[i].returns,
    assets[i].mean,
    assets[j].returns,
    assets[j].mean
    assets[j].returns
    )
    }
    }
  6. cesarvargas00 created this gist Oct 29, 2020.
    93 changes: 93 additions & 0 deletions markowitz.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,93 @@
    function correlation(x, xMean, y, yMean) {
    if (x.length !== y.length) return null

    xMean = xMean / x.length
    yMean = yMean / y.length

    let numerator = 0,
    xDSquaredSum = 0,
    yDSquaredSum = 0

    for (let i = 0; i < x.length; i++) {
    const xd = x[i] - xMean
    const yd = y[i] - yMean
    numerator += xd * yd
    xDSquaredSum += xd ** 2
    yDSquaredSum += yd ** 2
    }
    return numerator / (xDSquaredSum * yDSquaredSum) ** 0.5
    }

    function covariancesFromCorrelations(correlations, stdevs) {
    return Object.keys(correlations).reduce(
    (acc, row) => ({
    ...acc,
    [row]: Object.keys(correlations[row]).reduce(
    (acc, col) => ({
    ...acc,
    [col]: correlations[row][col] * stdevs[row] * stdevs[col],
    }),
    {}
    ),
    }),
    {}
    )
    }
    // portfolio = [{symbol, returns, amount}]
    function markowitz(portfolio) {
    const assets = []
    for (let i = 0; i < portfolio.length; i++) {
    const returns = []
    for (let i = 1; i < portfolio.returns.length; i++) {
    returns.push(
    (portfolio.returns[i] - portfolio.returns[i - 1]) /
    portfolio.returns[i - 1]
    )
    }
    const n = returns.length
    const mean = returns.reduce((acc, r) => r + acc, 0) / n
    const variance = returns.reduce((acc, r) => (r - mean) ** 2 + acc, 0) / n
    const stdev = variance ** 0.5
    const close = data[data.length - 1]
    returns.push({ symbol, returns, amount, mean, variance, stdev, close })
    }

    const correlations = {}
    for (let i = 0; i < assets.length; i++) {
    for (let j = 0; j < assets.length; j++) {
    if (typeof correlations[assets[i].symbol] === 'undefined') {
    correlations[assets[i].symbol] = {}
    }
    correlations[assets[i].symbol][assets[j].symbol] = correlation(
    assets[i].returns,
    assets[i].mean,
    assets[j].returns,
    assets[j].mean
    )
    }
    }
    const stdevs = assets.reduce(
    (acc, asset) => ({ ...acc, [asset.symbol]: asset.stdev }),
    {}
    )
    const covariances = covariancesFromCorrelations(correlations, stdevs)

    const total = assets.reduce(
    (acc, { amount, close }) => acc + amount * close,
    0
    )
    const w = assets.map(({ amount, close }) => (amount * close) / total)
    const Ω = Object.keys(covariances).map(k =>
    Object.keys(covariances[k]).map(l => covariances[k][l])
    )

    let r = 0
    for (let i = 0; i < w.length; i++) {
    let sum = 0
    for (let j = 0; j < w.length; j++) {
    sum += Ω[i][j] * w[j]
    }
    r += sum * w[i]
    }
    return r ** 0.5
    }