SigmaField
Mathematical Foundations for Quant Finance
0 of 256 lessons
      1. 5.8.1 Estimators: bias, variance and consistencyConcept · 35 min
      2. 5.8.2 Sampling distributions and confidence intervalsConcept · 35 min
      3. 5.8.3 Hypothesis testsConcept · 30 min
      4. 5.8.4 Practice set: statistical inferencePractice set · 25 min
      5. 5.8.5 Case study: is this Sharpe ratio significant?Case study · 35 min

Level 5, Probability and statistics 5.8 Statistical inference Lesson 4 of 5

Practice setLesson 5.8.4 in Level 5, Probability and statistics. About 25 minutes.

Practice set: statistical inference

Estimators

Estimators: bias, variance and consistency (lesson 5.8.1)

0 of 8 correct

  1. 1.
  2. 2.
  3. 3.
  4. 4.
  5. 5.
  6. 6.
  7. 7.
  8. 8.
How to type answers
  • Powers with ^: x^7, 2^(1/3), a^-2.
  • Multiply with * or by writing side by side: 3x^2, 2(x+1).
  • ln(x) is the natural log, log(x, 2) is log base 2, e is Euler's number, sqrt(x) is a square root.
  • sin(x), cos(x) and tan(x) take radians; write pi for π and sin(x)^2 for sin²x.
  • Your first answer to each question is saved: it counts towards your score and brings the question back for review.
  • Exact answers like ln(20)/ln(3) are best. Decimals need about 4 significant figures.

Sampling distributions and confidence intervals

Sampling distributions and confidence intervals (lesson 5.8.2)

0 of 8 correct

  1. 1.
  2. 2.
  3. 3.
  4. 4.
  5. 5.
  6. 6.
  7. 7.
  8. 8.
How to type answers
  • Powers with ^: x^7, 2^(1/3), a^-2.
  • Multiply with * or by writing side by side: 3x^2, 2(x+1).
  • ln(x) is the natural log, log(x, 2) is log base 2, e is Euler's number, sqrt(x) is a square root.
  • sin(x), cos(x) and tan(x) take radians; write pi for π and sin(x)^2 for sin²x.
  • Your first answer to each question is saved: it counts towards your score and brings the question back for review.
  • Exact answers like ln(20)/ln(3) are best. Decimals need about 4 significant figures.

Hypothesis tests

Hypothesis tests (lesson 5.8.3)

0 of 8 correct

  1. 1.
  2. 2.
  3. 3.
  4. 4.
  5. 5.
  6. 6.
  7. 7.
  8. 8.
How to type answers
  • Powers with ^: x^7, 2^(1/3), a^-2.
  • Multiply with * or by writing side by side: 3x^2, 2(x+1).
  • ln(x) is the natural log, log(x, 2) is log base 2, e is Euler's number, sqrt(x) is a square root.
  • sin(x), cos(x) and tan(x) take radians; write pi for π and sin(x)^2 for sin²x.
  • Your first answer to each question is saved: it counts towards your score and brings the question back for review.
  • Exact answers like ln(20)/ln(3) are best. Decimals need about 4 significant figures.

Coding exercise

Exercise

A t interval and a t test

Write two functions for a sample x (a list or NumPy array), as in lessons 5.8.2 and 5.8.3. Use the sample standard deviation dividing by n−1n - 1 and the t distribution with n−1n - 1 degrees of freedom (scipy.stats.t).

  1. t_interval(x, level=0.95) returns (low, high), the interval xˉ±t sn\bar{x} \pm t\,\frac{s}{\sqrt{n}}, with tt the 1+level2\frac{1 + \text{level}}{2} quantile.
  2. t_test(x, mu0=0.0, alternative="two-sided") returns (t_stat, p_value) for H0:μ=μ0H_0: \mu = \mu_0. The alternative is "two-sided", "greater" (H1:μ>μ0H_1: \mu > \mu_0) or "less".

Both raise ValueError for fewer than 2 values or when every value is the same, so that the standard error is 0. t_interval also raises it if level is not strictly between 0 and 1, and t_test if alternative is anything else.

The tests use lesson 5.8.2's five measurements and 40 exponential draws, and check your p-values against SciPy's ttest_1samp.

See the tests
import numpy as np
from scipy.stats import ttest_1samp

FIVE = [10.2, 9.6, 10.9, 10.4, 9.9]
EXPO = np.random.default_rng(5829).exponential(1.0, size=40)


def _raises(f, *args, **kwargs):
    try:
        f(*args, **kwargs)
    except ValueError:
        return True
    return False


def test_five_measurements():
    """Lesson 5.8.2's five measurements: the 95% interval runs from about 9.5854 to 10.8146"""
    got = t_interval(FIVE)
    assert got is not None, "t_interval returned None (did you forget to return?)"
    if abs(got[0] - 9.766135505) < 1e-6:
        raise AssertionError("got 9.7661 to 10.6339: that uses 1.96. Use the t quantile with n - 1 degrees of freedom")
    if abs(got[0] - 9.650291915) < 1e-6:
        raise AssertionError("got a lower end of 9.6503: that divides by n. Use the sample standard deviation with ddof=1")
    expect_close(got, (9.585407676840441, 10.814592323159557), what="t_interval(five)", rel=1e-9)


def test_other_level():
    """At 99% the interval widens to about 9.1808 to 11.2192"""
    expect_close(t_interval(FIVE, 0.99), (9.180840155012387, 11.219159844987612), what="t_interval(five, 0.99)", rel=1e-9)


def test_forty_values():
    """Lesson 5.8.2's 40 exponential draws: about 0.6759 to 1.5209"""
    expect_close(t_interval(EXPO), (0.6758823095909889, 1.5208754761807728), what="t_interval(forty draws)", rel=1e-9)


def test_two_sided():
    """Testing 10 gives t about 0.9035 and p about 0.4173; testing 9.5 gives 3.1623 and 0.0341"""
    got = t_test(FIVE, 10)
    assert got is not None, "t_test returned None (did you forget to return?)"
    expect_close(got, (0.9035079029052476, 0.41734905117810633), what="t_test(five, 10)", rel=1e-9)
    expect_close(t_test(FIVE, 9.5), (3.1622776601683746, 0.034109423167409766), what="t_test(five, 9.5)", rel=1e-9)


def test_one_sided():
    """Against 9.5, 'greater' gives p about 0.0171 and 'less' about 0.9829"""
    expect_close(t_test(FIVE, 9.5, "greater"), (3.1622776601683746, 0.017054711583704883), what="t_test(five, 9.5, 'greater')", rel=1e-9)
    expect_close(t_test(FIVE, 9.5, "less"), (3.1622776601683746, 0.9829452884162951), what="t_test(five, 9.5, 'less')", rel=1e-9)


def test_negative_t():
    """A sample below the claimed value gives a negative t and the same two-sided p as SciPy"""
    res = ttest_1samp(EXPO, 1.6)
    expect_close(t_test(EXPO, 1.6), (float(res.statistic), float(res.pvalue)), what="t_test(forty draws, 1.6)", rel=1e-9)


def test_interval_and_test_agree():
    """A claimed value inside the 95% interval has p above 0.05; one outside has p below"""
    low, high = t_interval(FIVE)
    assert t_test(FIVE, (low + high) / 2 + 0.9 * (high - low) / 2)[1] > 0.05, "a value inside the interval should have p > 0.05"
    assert t_test(FIVE, high + 0.01)[1] < 0.05, "a value just outside the interval should have p < 0.05"


def test_bad_inputs():
    """One value, identical values, a level of 0 or 1, or an unknown alternative raise ValueError"""
    assert _raises(t_interval, [3.0]), "t_interval with one value should raise ValueError"
    assert _raises(t_test, [3.0]), "t_test with one value should raise ValueError"
    assert _raises(t_interval, [2.0, 2.0, 2.0]), "t_interval with identical values should raise ValueError"
    assert _raises(t_test, [2.0, 2.0, 2.0], 1.0), "t_test with identical values should raise ValueError"
    for level in (0, 1):
        assert _raises(t_interval, FIVE, level), f"t_interval(level={level}) should raise ValueError"
    assert _raises(t_test, FIVE, 10, "bigger"), "t_test with alternative='bigger' should raise ValueError"

Free further reading

Optional. This lesson covers what you need; these add more examples and practice. All are free to read.