Skip to content

Commit

Permalink
424 update sharpe ratio (#425)
Browse files Browse the repository at this point in the history
* Sharpe flexible

* Sharpe for portfolio
  • Loading branch information
tschm authored Nov 7, 2024
1 parent 4490d0e commit 1baa3b2
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 32 deletions.
8 changes: 5 additions & 3 deletions cvx/simulator/portfolio.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

from dataclasses import dataclass
from datetime import datetime
from math import sqrt
from typing import Any

import numpy as np
Expand Down Expand Up @@ -396,10 +395,13 @@ def snapshot(

return fig

def sharpe(self, n=252):
def sharpe(self, n=None):
"""Simple Sharpe ratio"""

ts = self.nav.pct_change().dropna()
return ts.mean() / ts.std() * sqrt(n)
return sharpe(ts, n=n)

# return ts.mean() / ts.std() * sqrt(n)

@classmethod
def from_cashpos_prices(
Expand Down
13 changes: 12 additions & 1 deletion cvx/simulator/utils/metric.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
from math import sqrt

import pandas as pd

def sharpe(ts, n=252):

def _periods(ts):
"""
compute the number of periods in a time series
"""
series = pd.Series(data=ts.index)
return 365 * 24 * 60 * 60 / (series.diff().mean().total_seconds())


def sharpe(ts, n=None):
"""
compute the sharpe ratio of a time series
"""
n = n or _periods(ts)
return ts.mean() / ts.std() * sqrt(n)
10 changes: 10 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,13 @@ def prices(resource_dir):
return pd.read_csv(
resource_dir / "price.csv", index_col=0, parse_dates=True, header=0
).ffill()


@pytest.fixture()
def nav():
return pd.read_csv(
Path(__file__).parent / "resources" / "nav.csv",
index_col=0,
parse_dates=True,
header=0,
).squeeze()
2 changes: 1 addition & 1 deletion tests/test_applications/test_talk/test_experiment1.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ def test_portfolio(prices):
prices=prices, cashposition=1e6 * f(prices), aum=1e6
)
assert sharpe(portfolio.nav.pct_change().dropna()) == pytest.approx(
0.5285239056785145
0.5375955959644553
)
2 changes: 1 addition & 1 deletion tests/test_applications/test_talk/test_experiment2.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ def test_portfolio(prices):
portfolio = Portfolio.from_cashpos_prices(
prices=prices, cashposition=1e6 * f(prices), aum=1e8
)
assert sharpe(portfolio.nav.pct_change()) == pytest.approx(0.6132309781658799)
assert sharpe(portfolio.nav.pct_change()) == pytest.approx(0.6237309693693432)
2 changes: 1 addition & 1 deletion tests/test_applications/test_talk/test_experiment3.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ def test_portfolio(prices):
portfolio = Portfolio.from_cashpos_prices(
prices=prices, cashposition=1e6 * f(prices), aum=1e8
)
assert sharpe(portfolio.nav.pct_change()) == pytest.approx(0.8999500486718532)
assert sharpe(portfolio.nav.pct_change()) == pytest.approx(0.9153593608740396)
2 changes: 1 addition & 1 deletion tests/test_applications/test_talk/test_experiment4.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ def test_portfolio(prices):
portfolio = Portfolio.from_cashpos_prices(
prices=prices, cashposition=1e6 * f(prices), aum=1e8
)
assert sharpe(portfolio.nav.pct_change()) == pytest.approx(0.9679528514122532)
assert sharpe(portfolio.nav.pct_change()) == pytest.approx(0.98452653536996)
2 changes: 1 addition & 1 deletion tests/test_applications/test_talk/test_experiment5.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def test_portfolio(prices):
portfolio = builder.build()

assert sharpe(portfolio.nav.pct_change().dropna()) == pytest.approx(
1.3163233581460896
1.338916996187723
)

# portfolio.metrics()["Sharpe"] == pytest.approx(1.2778671597915794)
21 changes: 9 additions & 12 deletions tests/test_portfolio.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
from pathlib import Path

import pandas as pd
import pytest

from cvx.simulator.portfolio import Portfolio
from cvx.simulator.utils.metric import sharpe


@pytest.fixture()
def nav():
return pd.read_csv(
Path(__file__).parent / "resources" / "nav.csv",
index_col=0,
parse_dates=True,
header=0,
).squeeze()
# @pytest.fixture()
# def nav():
# return pd.read_csv(
# Path(__file__).parent / "resources" / "nav.csv",
# index_col=0,
# parse_dates=True,
# header=0,
# ).squeeze()


@pytest.fixture()
Expand Down Expand Up @@ -182,4 +179,4 @@ def test_profit_metrics(portfolio):
assert portfolio.profit.sum() == pytest.approx(-3492.4000000000033)
assert sharpe(portfolio.profit, n=252) == pytest.approx(-0.10965282385614909)
# profit is replacing NaNs with 0?!
assert portfolio.sharpe() == pytest.approx(-0.10210959124482079)
assert portfolio.sharpe() == pytest.approx(-0.1038600869081656)
9 changes: 9 additions & 0 deletions tests/test_utils/test_metric.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import pytest

from cvx.simulator.utils.metric import sharpe


def test_sharpe(nav):
s = sharpe(nav.pct_change())
print(s)
assert s == pytest.approx(-0.10388478316042028)
11 changes: 0 additions & 11 deletions tests/test_utils/test_month.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
import pandas as pd
import pytest

from cvx.simulator.utils.month import Aggregate, monthlytable


@pytest.fixture()
def nav(resource_dir):
"""nav fixture"""
return pd.read_csv(
resource_dir / "nav.csv", index_col=0, parse_dates=True, header=0
).squeeze()


def test_month_compounded(nav):
table = monthlytable(nav.pct_change().fillna(0.0), Aggregate.COMPOUND)
print(table)
Expand Down

0 comments on commit 1baa3b2

Please sign in to comment.