public override string ToString()
 {
     base.ToString();
     winners.Name = Name + " Winners";
     losers.Name  = Name + " Losers";
     return(base.ToString() +
            winners.Count.ToString("N0") + " winners. " +
            losers.Count.ToString("N0") + " losers. " +
            WinRate.ToString("P2") + " win ratio. " +
            ProfitFactor.ToString("N2") + " profit factor.\n" +
            Expectancy.ToString("N2") + " expectancy.\n" +
            winners.ToString() +
            losers.ToString());
 }
    public Expectancy ComputeExpectancy()
    {
        Expectancy expectancy = new Expectancy
        {
            Owner    = this,
            valence  = Expectancy.Valence.Reward,
            change   = Expectancy.Change.AsExpected,
            salience = 0
        };

        if (_values.Count <= 1 || _predictions.Count == 0)
        {
            return(expectancy);
        }

        float prediction = _predictions.Last(),
              value      = _values.Last(),
              lastValue  = _values[_values.Count - 2];

        float expectedResult = prediction - lastValue;

        // if expectedResult < 0 then we expect punishment
        // if expectedResult >= 0 then we expect reward
        expectancy.valence = expectedResult < 0 ? Expectancy.Valence.Punishment : Expectancy.Valence.Reward;

        float sensedResult = value - lastValue;

        // if sensedResult < 0 then we sensed punishment
        // if sensedResult >= 0 then we sensed reward

        if (MathUtils.DeltaAbs(expectedResult, sensedResult) < Epsilon)
        {
            expectancy.change = Expectancy.Change.AsExpected;
        }
        else
        {
            expectancy.change = sensedResult < expectedResult
                ? Expectancy.Change.WorseThanExpected
                : Expectancy.Change.BetterThanExpected;
        }

        expectancy.salience = MathUtils.Exogenous(value, prediction);

        return(expectancy);
    }