diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..f7b6a8f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,34 @@ +name: Publish Python 🐍 distributions πŸ“¦ to PyPI and TestPyPI + +on: + release: + types: + - published # upload build tar when publish + +jobs: + build-n-publish: + name: Build and publish Python 🐍 distributions πŸ“¦ to PyPI and TestPyPI + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Set up Python 3.7 + uses: actions/setup-python@v1 + with: + python-version: 3.7 + - name: Install pypa/build + run: >- + python -m + pip install + build + --user + - name: Build a source tarball + run: >- + python -m + build + --sdist + --outdir dist/ + - name: Publish distribution πŸ“¦ to PyPI + if: startsWith(github.ref, 'refs/tags/') + uses: pypa/gh-action-pypi-publish@master + with: + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/rqrisk/risk.py b/rqrisk/risk.py index 72b769e..8a6ef5b 100644 --- a/rqrisk/risk.py +++ b/rqrisk/risk.py @@ -201,6 +201,10 @@ def param_var(self, alpha): @indicator_property(min_period_count=1) def win_rate(self): + return len(self._portfolio[self._portfolio > 0]) / self.period_count + + @indicator_property(min_period_count=1) + def excess_win_rate(self): return len(self._portfolio[self._portfolio > self._benchmark]) / self.period_count def all(self): diff --git a/setup.cfg b/setup.cfg index d0c7cbb..9b66261 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,7 +5,7 @@ [metadata] name = rqrisk -version = 1.0.2 +version = 1.0.3 [versioneer] VCS = git diff --git a/test.py b/test.py index eaca7ee..a5be4bd 100644 --- a/test.py +++ b/test.py @@ -242,3 +242,23 @@ def test_natural_daily(): assert_almost_equal(r.information_ratio, 97.92626812366308) assert_almost_equal(r.sharpe, -0.23942084288518412) + +def test_win_rate(): + """ ζ΅‹θ―•θƒœηŽ‡ """ + def _assert(returns, benchmark, desired_win_rate): + assert_almost_equal(_r(returns, benchmark, 0).win_rate, desired_win_rate) + + _assert(volatile_returns, volatile_benchmark, 0.6666666666666666) + _assert(positive_returns, volatile_benchmark, 1) + _assert(negative_returns, volatile_benchmark, 0) + + +def test_excess_win_rate(): + """ ζ΅‹θ―•θΆ…ι’θƒœηŽ‡ """ + def _assert(returns, benchmark, desired_win_rate): + assert_almost_equal(_r(returns, benchmark, 0).excess_win_rate, desired_win_rate) + + _assert(volatile_returns, volatile_benchmark, 0.4444444444444444) + _assert(positive_returns, zero_benchmark, 1) + _assert(negative_returns, zero_benchmark, 0) +