def test_portfolio(monkeypatch): monkeypatch.setattr(config, "TURNOVER_PERIOD", 7) monkeypatch.setattr(config, "TURNOVER_CUT_OFF", 0.6) port = portfolio.Portfolio(**PARAMS) assert "Дата - 2018-03-19" in str(port) assert port.date == pd.Timestamp("2018-03-19") assert port.index.tolist() == ["GAZP", "TTLK", "VSMO", CASH, PORTFOLIO] assert np.allclose(port.shares, [6820, 1_230_000, 145, 1000, 1]) assert np.allclose(port.lot_size, [10, 10000, 1, 1, 1]) assert np.allclose(port.lots, [682, 123, 145, 1000, 1]) assert np.allclose(port.price, [139.91, 0.1525, 17630, 1, 3_699_111]) assert np.allclose(port.value, [954_186, 187_575, 2_556_350, 1000, 3_699_111]) assert np.allclose( port.weight, [ 0.257_950_085_844_95, 0.050_708_129_601_95, 0.691_071_449_329_312, 0.000_270_335_223_788, 1, ], ) assert np.allclose(port.turnover_factor, [1, 0, 0.693_130_358_498_49, 1, 1])
def test_std_gradient(): pos = dict(PRTK=100, RTKM=200, SIBN=300) port = portfolio.Portfolio("2018-12-17", 1000, pos) metrics3 = metrics.Metrics(port, months=3) metrics12 = metrics.Metrics(port, months=12) assert metrics12.std_gradient == pytest.approx(metrics12.std[PORTFOLIO]) assert metrics3.std_gradient == pytest.approx(metrics12.std[PORTFOLIO] / 2) assert metrics3.std_gradient == pytest.approx(metrics3.std[PORTFOLIO] / 2)
def test_find_better_model_fake_base(monkeypatch, capsys): monkeypatch.setattr(cv, "MAX_SEARCHES", 10) monkeypatch.setattr(cv, "print_result", lambda x, y, z: 1 if x == "Базовая модель" else 0) pos = dict(LSNGP=10, KZOS=20, GMKN=30) port = portfolio.Portfolio(pd.Timestamp("2018-12-19"), 100, pos) cv.find_better_model(port) captured = capsys.readouterr() assert "ЛУЧШАЯ МОДЕЛЬ - Базовая модель" in captured.out
def test_update_data_bad_investor_name(): port = portfolio.Portfolio(name=["test"], date=DATE_NEW, cash=CASH, positions=POSITIONS) with pytest.raises(POptimizerError) as error: pdf.update_data("test", port.date, port.value[PORTFOLIO], dict(WLMike1=1000), 1234) assert str(error.value) == "Неверное имя инвестора - WLMike1"
def test_find_better_model(monkeypatch, capsys): monkeypatch.setattr(cv, "MAX_SEARCHES", 10) monkeypatch.setattr(cv, "MAX_DEPTH", 7) pos = dict(LSNGP=10, KZOS=20, GMKN=30) port = portfolio.Portfolio(pd.Timestamp("2018-12-19"), 100, pos) cv.find_better_model(port, PARAMS) captured = capsys.readouterr() assert "Базовая модель" in captured.out assert "Найденная модель" in captured.out assert "ЛУЧШАЯ МОДЕЛЬ - Найденная модель" in captured.out
def test_forecast_func(monkeypatch): monkeypatch.setattr(config, "ML_PARAMS", ML_PARAMS) pos = dict(SIBN=300, PRTK=100, RTKM=200) port = portfolio.Portfolio("2018-12-17", 1000, pos) result = metrics.Metrics(port) # noinspection PyProtectedMember forecast = result._forecast_func() assert isinstance(forecast, Forecast) assert forecast.date == pd.Timestamp("2018-12-17") assert forecast.tickers == ("PRTK", "RTKM", "SIBN") assert forecast.shrinkage == pytest.approx(0.6972112123349591)
def test_update_data_bad_date(): port = portfolio.Portfolio(date=DATE_OLD, cash=CASH, positions=POSITIONS) with pytest.raises(POptimizerError) as error: pdf.update_data( "test", port.date, port.value[PORTFOLIO], dict(WLMike=1000, Igor=-2000), 1234, ) assert str(error.value) == "В этом месяце данные уже вносились в отчет"
def test_report_new_month(): port = portfolio.Portfolio(date=DATE_NEW, cash=CASH, positions=POSITIONS) pdf.report("test", port, dict(WLMike=10000, Igor=-5000), 4321) df = pdf.read_data("test") date = port.date assert df.index[-1] == date assert df.loc[date, "WLMike"] == pytest.approx(10000) assert df.loc[date, "Igor"] == pytest.approx(-5000) assert df.loc[date, "Value_WLMike"] == pytest.approx(387_550.829_708_377) assert df.loc[date, "Value_Igor"] == pytest.approx(4972.170_292) assert df.loc[date, "Value"] == pytest.approx(392_523) assert df.loc[date, "Dividends"] == pytest.approx(4321)
def test_update_data(): port = portfolio.Portfolio(date=DATE_NEW, cash=CASH, positions=POSITIONS) pdf.update_data("test", port.date, port.value[PORTFOLIO], dict(WLMike=1000, Igor=-2000), 1234) df = pdf.read_data("test") assert df.shape == (241, 6) assert df.index[-1] == pd.Timestamp("2018-05-07") assert df.loc["2018-05-07", "WLMike"] == pytest.approx(1000) assert df.loc["2018-05-07", "Igor"] == pytest.approx(-2000) assert df.loc["2018-05-07", "Value_WLMike"] == pytest.approx(384_396.431_074_62) assert df.loc["2018-05-07", "Value_Igor"] == pytest.approx(8126.568_925_380_33) assert df.loc["2018-05-07", "Value"] == pytest.approx(392_523) assert df.loc["2018-05-07", "Dividends"] == pytest.approx(1234)
def make_metrics(): """Подготовка тестовых данных.""" positions = {"BSPB": 4890, "FESH": 1300, "KZOS": 5080} port = portfolio.Portfolio(["test"], "2020-05-14", 84449, positions) mean = pd.Series([0.09, 0.06, 0.07], index=list(positions)) cov = np.array([ [0.04, 0.005, 0.01], [0.005, 0.0625, 0.00625], [0.01, 0.00625, 0.0625], ], ) fake_forecast = SimpleNamespace() fake_forecast.mean = mean fake_forecast.cov = cov fake_forecast.max_std = 0.11 # noinspection PyTypeChecker yield metrics.MetricsSingle(port, fake_forecast)
def make_resample(): """Данне для тестов.""" positions = {"BSPB": 4890, "FESH": 1300} port = portfolio.Portfolio("test", "2020-05-14", 84449, positions) mean1 = pd.Series([0.09, 0.06], index=list(positions)) cov1 = np.array([[0.04, 0.005], [0.005, 0.0625]]) mean2 = pd.Series([0.05, 0.09], index=list(positions)) cov12 = np.array([[0.0225, 0.0042], [0.0042, 0.0196]]) def fake_get_forecasts(*_): yield from ( SimpleNamespace( mean=mean1, cov=cov1, history_days=1, cor=0.4, shrinkage=0.3, risk_aversion=1, error_tolerance=0, ), SimpleNamespace( mean=mean2, cov=cov12, history_days=2, cor=0.5, shrinkage=0.2, risk_aversion=1, error_tolerance=0, ), ) saved_get_forecast = metrics.evolve.get_forecasts metrics.evolve.get_forecasts = fake_get_forecasts yield metrics.MetricsResample(port) metrics.evolve.get_forecasts = saved_get_forecast
def test_portfolio_wrong_date(): PARAMS["date"] = "2018-12-09" with pytest.raises(POptimizerError) as error: portfolio.Portfolio(**PARAMS) assert "Для даты 2018-12-09 отсутствуют исторические котировки" == str( error.value)
def test_portfolio_wrong_value(): with pytest.raises(POptimizerError) as error: PARAMS["value"] = 123 portfolio.Portfolio(**PARAMS) assert "Введенная стоимость портфеля 123" in str(error.value)
def make_portfolio(): return portfolio.Portfolio(**PARAMS)
MTSS=7490, MVID=3260, NMTP=0, PHOR=0, PMSBP=17290, RSTIP=87000, RTKM=0, RTKMP=182_600, SNGSP=23500, TTLK=0, UPRO=1_267_000, VSMO=73, ) CASH = 1_548_264 DATE = "2018-04-19" TEST_PORTFOLIO = portfolio.Portfolio(date=DATE, cash=CASH, positions=POSITIONS) def test_drop_small_positions(): df = pdf_lower.drop_small_positions(TEST_PORTFOLIO) index = df.index assert len(df) == pdf_lower.MAX_TABLE_ROWS + 2 assert index[-1] == PORTFOLIO assert df[PORTFOLIO] == pytest.approx(38525478) assert index[-2] == OTHER assert df[OTHER] == pytest.approx(5822654) assert index[0] == "RTKMP" assert df.iloc[0] == pytest.approx(11_167_816) assert index[-3] == "MVID" assert df.iloc[-3] == pytest.approx(1_310_520)