Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed expectancy criterion calculation, updated unit tests, noted in … #928

Conversation

TheCookieLab
Copy link
Contributor

@TheCookieLab TheCookieLab commented Jan 6, 2023

Fixes #926

Changes proposed in this pull request:

  • Fixed ExpectancyCriterion calculation

  • Updated unit tests

  • updated changelog

  • added an entry with related ticket number(s) to the unreleased section of CHANGES.md

@team172011
Copy link
Member

team172011 commented Jan 8, 2023

@TheCookieLab I agree that the calculation of the expectancy looks wrong. But I am also not sure if your fix produces the correct results when looking into the fixed unit tests.

For example the first unit tests that was only looking at winning trades had a result value of 0. I do not know what this should mean. With your fix it results in 1, but I do not know how to interpret this value as well?

@Test
public void calculateOnlyWithProfitPositions() {
    MockBarSeries series = new MockBarSeries(numFunction, 100, 110, 120, 130, 150, 160);
    TradingRecord tradingRecord = new BaseTradingRecord(Trade.buyAt(0, series), Trade.sellAt(2, series),
             Trade.buyAt(3, series), Trade.sellAt(5, series));

     AnalysisCriterion avgLoss = getCriterion();
     assertNumEquals(0, avgLoss.calculate(series, tradingRecord)); // 0 is wrong,  but I think 1 as well
 }

In my understanding the formula of the expectancy should look like:

e = (% of winning positions X % of avg. profit per position) – (% of losing positions X % of avg. loss per position)

In the mentioned unit tests we have two trades. Both are winning trades so the % of winning positions is 100% and the % of losing positions is 0%. The first trades has a profit of 20% (120/100-1) and the second trade has a profit of 23.08% (160/130-1). That means the % of avg. profit per position is 21.54% ((20% + 23.08%) / 2) and the % of avg. loss per position is 0%. This results in:

(100% * 21.54) - (0% * 0%) = 21.54%

I would interpret this as: The expectancy is positive with a win of 21.54% per trade.

EDIT 1: Fix decimal places of percentage calculation

Copy link
Member

@team172011 team172011 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments

@TheCookieLab
Copy link
Contributor Author

@team172011 If I'm not mistaken, the AW and AL terms are not percentages but rather raw values. In the link provided in the comments they define:

AW = Average winning trade in terms of $
AL = Average losing trade in terms of $

The current implementation produces an expectancy of 0.446 when using the params found in the link so that matches up.

Here is a second example of calculating expectancy which also uses "raw" values rather than percentages: https://evilspeculator.com/key-concepts-in-risk-management/

An exercise using the values in the 2nd example also produces the matching result of 0.8

@Test
    public void calculateWith30PercentWinRateFor5REachAnd70PercentLoseRateFor1REach() {
        MockBarSeries series = new MockBarSeries(numFunction, 1, 6, 1, 6, 1, 6, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1);
        TradingRecord tradingRecord = new BaseTradingRecord(Trade.buyAt(0, series), Trade.sellAt(1, series),
                Trade.buyAt(2, series), Trade.sellAt(3, series),
                Trade.buyAt(4, series), Trade.sellAt(5, series),
                Trade.buyAt(6, series), Trade.sellAt(7, series),
                Trade.buyAt(8, series), Trade.sellAt(9, series),
                Trade.buyAt(10, series), Trade.sellAt(11, series),
                Trade.buyAt(12, series), Trade.sellAt(13, series),
                Trade.buyAt(14, series), Trade.sellAt(15, series),
                Trade.buyAt(16, series), Trade.sellAt(17, series),
                Trade.buyAt(18, series), Trade.sellAt(19, series));

        AnalysisCriterion expectancy = getCriterion();
        assertNumEquals(0.8, expectancy.calculate(series, tradingRecord));
    }

@team172011
Copy link
Member

@TheCookieLab, okay I understand, raw values. But I am still wondering about the first unit test calculateOnlyWithProfitPositions resulting in 1.0? I think the definition of the result of the ExpectancyCriterion is a value that describes how much to expect to win or lose on average per trade.

@TheCookieLab
Copy link
Contributor Author

@team172011 I certainly could be mistaken but my impression is that expectancy should be thought of as the probability of a win weighted by expected payout. It's useful for decision making in the face of uncertainty (i.e. how much to wager on a bet) but not really designed for scenarios that are guaranteed (i.e. 100% success rate).

@team172011 team172011 merged commit 457136c into ta4j:develop Jan 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants