Создание реактивных доверительных интервалов для ожидаемого максимума / минимума - PullRequest
0 голосов
/ 12 марта 2020

Я пытаюсь создать доверительные интервалы для моего ожидаемого среднего значения, чтобы предсказать максимум / минимум следующего бара OHL C. Я не очень разбираюсь в статистике, и я могу только предположить, что я поступаю об этом избитым способом. Из-за медленно реагирующей средней оценки я не думаю, что симметричный интервал является разумным; моя текущая реализация дает несколько плохие результаты.

poor results

Фиолетовая линия - ожидаемое среднее. Как видите, среднее значение не реагирует на переоценку / недооценку. В любом случае, однако, ожидаемые максимумы / минимумы также не реагируют на соответствующие ошибки. Период с апреля 2019 года имеет ожидаемый максимум, который неизменно слишком далеко от фактических значений и слишком консервативных минимумов.

Я рассчитал «точку контроля» для каждого бара (цена @ максимальный объем) так что, если это поможет как-то спрогнозировать среднее, я буду признателен за некоторые указатели.

Во-первых, я не понимаю, как функция биномиального распределения возвращает верхний и нижний интервал, учитывая, что для работы используется только% alpha с. Что на самом деле означают эти возвращаемые значения? Я понимаю, что более точный прогноз среднего значения и волатильности будет лучшим способом продвижения вперед.

# `frame` contains pandas data on open/high/low/close/volume/hl2 as well as
# expected_high and expected_low values previously generated by this script
from statsmodels.stats.proportion import proportion_confint
error_lookback = 300
slippage = 0.05
confidence = 0.05
slow_period = 5


def _estimate_error(side):
    # Overestimation is when the estimate lies
    # above the high or below the low. Underestimation
    # is the reciprocal inclusive of slippage (ex., $0.05 below high/above low)
    # Everything else is considered to be an on-point estimate.
    # The notion is to quantify the errors of overestimation and
    # underestimation separately
    if side == 'upper':
        actual = frame.high.tail(error_lookback)
        estimate = frame.expected_high.shift(1).fillna(actual).tail(error_lookback)
        adjustment = bool(estimate.iloc[0] < actual.iloc[0] - slippage) - bool(estimate.iloc[0] > actual.iloc[0])
        overestimated = actual[estimate > actual].count()
        underestimated = actual[estimate < actual - slippage].count()
    else:
        actual = frame.low.tail(error_lookback)
        estimate = frame.expected_low.shift(1).fillna(actual).tail(error_lookback)
        adjustment = bool(estimate.iloc[0] > actual.iloc[0]) - bool(estimate.iloc[0] < actual.iloc[0] + slippage)
        overestimated = actual[estimate < actual].count()
        underestimated = actual[estimate > actual + slippage].count()

    on_point = actual.size - (overestimated if adjustment > 0 else (underestimated if adjustment < 0 else 0))
    return proportion_confint(on_point, actual.size, alpha=confidence)[1]


# As per: https://sixfigureinvesting.com/2018/11/predicting-price-ranges-with-historic-volatility/
def ci_forecast(source, mean, sigma, k_samples, steps):
    return np.exp(mean.iloc[-1] * steps + sigma * np.std(source.iloc[-k_samples:]) * np.sqrt(steps))


# Apply CI forecasting to to the mean
# Scale back up to source data
# --- velocity is the lognormal return
# --- expected_return is the forecasted lognormal return
real_mean = frame.hl2.iloc[-1]
expected_mean = real_mean + real_mean * expected_return.iloc[-1]

frame.expected_high.iloc[-1] = expected_mean * ci_forecast(velocity, expected_return, _estimate_error('upper'), slow_period, 1))
frame.expected_low.iloc[-1] = expected_mean * ci_forecast(velocity, expected_return, -_estimate_error('lower'), slow_period, 1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...