Esempio n. 1
0
def test_get_returns_default_when_key_not_set() -> None:
    path = Path.cwd() / "config.json"
    with path.open("w+", encoding="utf-8") as file:
        file.write('{ "key": "value" }')

    storage = Storage(str(path))

    assert storage.get("key2", "my-default") == "my-default"
Esempio n. 2
0
def test_has_returns_false_when_key_does_not_exist_in_file() -> None:
    path = Path.cwd() / "config.json"
    with path.open("w+", encoding="utf-8") as file:
        file.write('{ "key": "value" }')

    storage = Storage(str(path))

    assert not storage.has("key2")
Esempio n. 3
0
def test_get_reads_key_from_file() -> None:
    path = Path.cwd() / "config.json"
    with path.open("w+", encoding="utf-8") as file:
        file.write('{ "key": "value" }')

    storage = Storage(str(path))

    assert storage.get("key") == "value"
Esempio n. 4
0
def test_set_creates_new_file_when_file_does_not_exist() -> None:
    path = Path.cwd() / "config.json"

    storage = Storage(str(path))
    storage.set("key", "value")

    data = json.loads(path.read_text(encoding="utf-8"))
    assert data == {"key": "value"}
Esempio n. 5
0
def test_clear_deletes_file() -> None:
    path = Path.cwd() / "config.json"
    with path.open("w+", encoding="utf-8") as file:
        file.write('{ "key": "value" }')

    storage = Storage(str(path))
    storage.clear()

    assert not path.exists()
def test_create_new_project_sets_parameters_in_project_config() -> None:
    project_path = Path.cwd() / "Python Project"

    project_manager = _create_project_manager()
    project_manager.create_new_project(project_path, QCLanguage.Python)

    config = Storage(str(project_path / "config.json"))

    assert config.get("parameters") == {}
Esempio n. 7
0
def test_create_new_project_sets_description_in_project_config() -> None:
    project_path = Path.cwd() / "Python Project"

    project_manager = ProjectManager(ProjectConfigManager())
    project_manager.create_new_project(project_path, QCLanguage.Python)

    config = Storage(str(project_path / "config.json"))

    assert config.get("description") == ""
Esempio n. 8
0
def test_set_overrides_values_in_existing_file() -> None:
    path = Path.cwd() / "config.json"
    with path.open("w+", encoding="utf-8") as file:
        file.write('{ "key": "value" }')

    storage = Storage(str(path))
    storage.set("key", "new-value")

    data = json.loads(path.read_text(encoding="utf-8"))
    assert data == {"key": "new-value"}
Esempio n. 9
0
def test_create_new_project_sets_language_in_project_config(
        language: QCLanguage) -> None:
    project_path = Path.cwd() / f"{language.name} Project"

    project_manager = ProjectManager(ProjectConfigManager())
    project_manager.create_new_project(project_path, language)

    config = Storage(str(project_path / "config.json"))

    assert config.get("algorithm-language") == language.name
Esempio n. 10
0
def test_report_uses_description_from_config_when_strategy_description_not_given(
) -> None:
    docker_manager = mock.Mock()
    docker_manager.run_image.side_effect = run_image
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "description", "My description")

    result = CliRunner().invoke(lean, [
        "report", "--backtest-results",
        "Python Project/backtests/2020-01-01_00-00-00/results.json"
    ])

    assert result.exit_code == 0

    docker_manager.run_image.assert_called_once()
    args, kwargs = docker_manager.run_image.call_args

    config_mount = [
        mount for mount in kwargs["mounts"]
        if mount["Target"] == "/Lean/Report/bin/Debug/config.json"
    ][0]
    config = json.loads(
        Path(config_mount["Source"]).read_text(encoding="utf-8"))

    assert config["strategy-description"] == "My description"
    def get_output_config(self, output_directory: Path) -> Storage:
        """Returns a Storage instance to get/set the configuration of the contents of an output directory.

        :param output_directory: the path to the project to retrieve the configuration of
        :return: the Storage instance containing the configuration of the given backtest/optimization/live trading
        """
        return Storage(str(output_directory / "config"))
Esempio n. 12
0
def test_optimize_mounts_output_directory() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    docker_manager.run_image.side_effect = run_image
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(
        lean, ["optimize", "Python Project", "--output", "output"])

    assert result.exit_code == 0

    docker_manager.run_image.assert_called_once()
    args, kwargs = docker_manager.run_image.call_args

    assert any([
        volume["bind"] == "/Results" for volume in kwargs["volumes"].values()
    ])

    key = next(key for key in kwargs["volumes"].keys()
               if kwargs["volumes"][key]["bind"] == "/Results")
    assert key == str(Path.cwd() / "output")
    def get_project_config(self, project_directory: Path) -> Storage:
        """Returns a Storage instance to get/set the configuration for a project.

        :param project_directory: the path to the project to retrieve the configuration of
        :return: the Storage instance containing the project-specific configuration of the given project
        """
        return Storage(str(project_directory / PROJECT_CONFIG_FILE_NAME))
Esempio n. 14
0
def create_lean_runner(docker_manager: mock.Mock) -> LeanRunner:
    logger = mock.Mock()
    logger.debug_logging_enabled = False

    cli_config_manager = mock.Mock()
    cli_config_manager.user_id.get_value.return_value = "123"
    cli_config_manager.api_token.get_value.return_value = "456"

    project_config_manager = ProjectConfigManager(XMLManager())

    cache_storage = Storage(str(Path("~/.lean/cache").expanduser()))
    lean_config_manager = LeanConfigManager(logger, cli_config_manager,
                                            project_config_manager,
                                            mock.Mock(), cache_storage)
    output_config_manager = OutputConfigManager(lean_config_manager)

    module_manager = mock.Mock()
    module_manager.get_installed_packages.return_value = [
        NuGetPackage(name="QuantConnect.Brokerages", version="1.0.0")
    ]

    xml_manager = XMLManager()
    project_manager = ProjectManager(project_config_manager,
                                     lean_config_manager, xml_manager,
                                     PlatformManager())

    return LeanRunner(logger, project_config_manager, lean_config_manager,
                      output_config_manager, docker_manager, module_manager,
                      project_manager, TempManager(), xml_manager)
Esempio n. 15
0
def test_optimize_checks_for_updates(update_manager_mock: mock.Mock,
                                     image_option: Optional[str],
                                     update_flag: bool,
                                     update_check_expected: bool) -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    options = []
    if image_option is not None:
        options.extend(["--image", image_option])
    if update_flag:
        options.extend(["--update"])

    result = CliRunner().invoke(lean, ["optimize", "Python Project", *options])

    assert result.exit_code == 0

    if update_check_expected:
        update_manager_mock.warn_if_docker_image_outdated.assert_called_once_with(
            ENGINE_IMAGE)
    else:
        update_manager_mock.warn_if_docker_image_outdated.assert_not_called()
Esempio n. 16
0
def create_objects() -> Tuple[mock.Mock, Storage, mock.Mock, UpdateManager]:
    logger = mock.Mock()
    storage = Storage(str(Path("~/.lean/cache").expanduser()))
    docker_manager = mock.Mock()

    update_manager = UpdateManager(logger, storage, docker_manager)

    return logger, storage, docker_manager, update_manager
Esempio n. 17
0
def test_delete_unsets_value() -> None:
    path = Path.cwd() / "config.json"

    storage = Storage(str(path))
    storage.set("key1", "value1")
    storage.set("key2", "value2")
    storage.set("key3", "value3")
    storage.delete("key2")

    data = json.loads(path.read_text(encoding="utf-8"))
    assert data == {"key1": "value1", "key3": "value3"}
def _create_project_manager() -> ProjectManager:
    xml_manager = XMLManager()
    project_config_manager = ProjectConfigManager(xml_manager)
    cache_storage = Storage(str(Path("~/.lean/cache").expanduser()))

    return ProjectManager(
        project_config_manager,
        LeanConfigManager(mock.Mock(), mock.Mock(), project_config_manager,
                          mock.Mock(), cache_storage), xml_manager,
        PlatformManager())
Esempio n. 19
0
def test_delete_deletes_file_when_last_key() -> None:
    path = Path.cwd() / "config.json"

    storage = Storage(str(path))
    storage.set("key", "value")
    storage.delete("key")

    assert not path.exists()
Esempio n. 20
0
def test_optimize_aborts_when_project_has_no_parameters() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {})

    result = CliRunner().invoke(lean, ["optimize", "Python Project"])

    assert result.exit_code != 0

    docker_manager.run_image.assert_not_called()
Esempio n. 21
0
def test_optimize_creates_output_directory_when_not_existing_yet() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(
        lean, ["optimize", "Python Project", "--output", "output"])

    assert result.exit_code == 0

    assert (Path.cwd() / "output").is_dir()
Esempio n. 22
0
def test_optimize_forces_update_when_update_option_given() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(lean,
                                ["optimize", "Python Project", "--update"])

    assert result.exit_code == 0

    docker_manager.pull_image.assert_called_once_with(ENGINE_IMAGE)
    docker_manager.run_image.assert_called_once()
Esempio n. 23
0
def test_optimize_runs_lean_container() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(lean, ["optimize", "Python Project"])

    assert result.exit_code == 0

    docker_manager.run_image.assert_called_once()
    args, kwargs = docker_manager.run_image.call_args

    assert args[0] == ENGINE_IMAGE
Esempio n. 24
0
def test_optimize_creates_correct_config_from_optimizer_config_manager_output(
) -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    docker_manager.run_image.side_effect = run_image
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(lean, ["optimize", "Python Project"])

    assert result.exit_code == 0

    docker_manager.run_image.assert_called_once()
    args, kwargs = docker_manager.run_image.call_args

    mount = next(
        m for m in kwargs["mounts"]
        if m["Target"] == "/Lean/Optimizer.Launcher/bin/Debug/config.json")
    config = json.loads(Path(mount["Source"]).read_text(encoding="utf-8"))

    assert config["results-destination-folder"] == "/Results"

    assert config[
        "optimization-strategy"] == "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy"
    assert config["optimization-criterion"] == {
        "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
        "extremum": "max"
    }

    assert config["parameters"] == [{
        "name": "param1",
        "min": 1.0,
        "max": 10.0,
        "step": 0.5
    }]

    assert config["constraints"] == [{
        "target": "TotalPerformance.PortfolioStatistics.Drawdown",
        "operator": "less",
        "target-value": 0.25
    }]
Esempio n. 25
0
def test_optimize_runs_optimizer() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(lean, ["optimize", "Python Project"])

    assert result.exit_code == 0

    docker_manager.run_image.assert_called_once()
    args, kwargs = docker_manager.run_image.call_args

    assert kwargs["working_dir"] == "/Lean/Optimizer.Launcher/bin/Debug"
    assert kwargs["entrypoint"][0] == "dotnet"
    assert kwargs["entrypoint"][1] == "QuantConnect.Optimizer.Launcher.dll"
Esempio n. 26
0
def test_optimize_runs_custom_image_when_set_in_config() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    container.docker_manager.override(providers.Object(docker_manager))

    container.cli_config_manager().engine_image.set_value("custom/lean:123")

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(lean, ["optimize", "Python Project"])

    assert result.exit_code == 0

    docker_manager.run_image.assert_called_once()
    args, kwargs = docker_manager.run_image.call_args

    assert args[0] == DockerImage(name="custom/lean", tag="123")
Esempio n. 27
0
def test_optimize_mounts_lean_config() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(lean, ["optimize", "Python Project"])

    assert result.exit_code == 0

    docker_manager.run_image.assert_called_once()
    args, kwargs = docker_manager.run_image.call_args

    assert any([
        mount["Target"] == "/Lean/Launcher/bin/Debug/config.json"
        for mount in kwargs["mounts"]
    ])
Esempio n. 28
0
def test_get_complete_lean_config_sets_parameters() -> None:
    create_fake_lean_cli_directory()

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {
            "key1": "value1",
            "key2": "value2",
            "key3": "value3"
        })

    manager = LeanConfigManager(mock.Mock(), ProjectConfigManager())
    config = manager.get_complete_lean_config(
        "my-environment",
        Path.cwd() / "Python Project" / "main.py", None)

    assert config["parameters"] == {
        "key1": "value1",
        "key2": "value2",
        "key3": "value3"
    }
Esempio n. 29
0
def test_optimize_writes_config_to_output_directory() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    docker_manager.run_image.side_effect = run_image
    container.docker_manager.override(providers.Object(docker_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(
        lean, ["optimize", "Python Project", "--output", "output"])

    assert result.exit_code == 0

    assert (Path.cwd() / "output" / "optimizer-config.json").exists()
    config = json.loads((Path.cwd() / "output" /
                         "optimizer-config.json").read_text(encoding="utf-8"))

    assert config["results-destination-folder"] == "/Results"

    assert config[
        "optimization-strategy"] == "QuantConnect.Optimizer.Strategies.GridSearchOptimizationStrategy"
    assert config["optimization-criterion"] == {
        "target": "TotalPerformance.PortfolioStatistics.SharpeRatio",
        "extremum": "max"
    }

    assert config["parameters"] == [{
        "name": "param1",
        "min": 1.0,
        "max": 10.0,
        "step": 0.5
    }]

    assert config["constraints"] == [{
        "target": "TotalPerformance.PortfolioStatistics.Drawdown",
        "operator": "less",
        "target-value": 0.25
    }]
Esempio n. 30
0
def test_optimize_copies_code_to_output_directory() -> None:
    create_fake_lean_cli_directory()

    docker_manager = mock.Mock()
    docker_manager.run_image.side_effect = run_image
    container.docker_manager.override(providers.Object(docker_manager))

    project_manager = mock.Mock()
    project_manager.find_algorithm_file.return_value = Path.cwd(
    ) / "Python Project" / "main.py"
    container.project_manager.override(providers.Object(project_manager))

    Storage(str(Path.cwd() / "Python Project" / "config.json")).set(
        "parameters", {"param1": "1"})

    result = CliRunner().invoke(
        lean, ["optimize", "Python Project", "--output", "output"])

    assert result.exit_code == 0

    project_manager.copy_code.assert_called_once_with(
        Path.cwd() / "Python Project",
        Path.cwd() / "output" / "code")