Skip to content

Commit

Permalink
Fix live existing cash or holdings state (#504)
Browse files Browse the repository at this point in the history
- Minor fix for missing live existing cash holdings state check. Adding
  unit test reproducing issue
  • Loading branch information
Martin-Molinero authored Sep 26, 2024
1 parent 435f9b1 commit 90984b5
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
12 changes: 7 additions & 5 deletions lean/components/util/live_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,13 @@ def get_last_portfolio_cash_holdings(api_client: APIClient, brokerage_instance:
if cash_balance_option != LiveInitialStateInput.NotSupported or holdings_option != LiveInitialStateInput.NotSupported:
last_portfolio = _get_last_portfolio(api_client, project_id, project)
if last_portfolio is not None:
for key, value in last_portfolio["cash"].items():
last_cash[key] = InsensitiveCaseDict(value)
for key, value in last_portfolio["holdings"].items():
last_holdings[key] = InsensitiveCaseDict(value)
last_holdings[key]["symbol"] = InsensitiveCaseDict(last_holdings[key]["symbol"])
if "cash" in last_portfolio:
for key, value in last_portfolio["cash"].items():
last_cash[key] = InsensitiveCaseDict(value)
if "holdings" in last_portfolio:
for key, value in last_portfolio["holdings"].items():
last_holdings[key] = InsensitiveCaseDict(value)
last_holdings[key]["symbol"] = InsensitiveCaseDict(last_holdings[key]["symbol"])
else:
last_cash = None
last_holdings = None
Expand Down
37 changes: 36 additions & 1 deletion tests/commands/test_live.py
Original file line number Diff line number Diff line change
Expand Up @@ -1139,11 +1139,16 @@ def test_live_non_interactive_deploy_with_real_brokerage_without_credentials() -
assert "--oanda-environment" in error_msg
assert "--iex-price-plan" not in error_msg

def create_lean_option(brokerage_name: str, data_provider_live_name: str, data_provider_historical_name: str, api_client: any) -> Result:

def create_lean_option(brokerage_name: str, data_provider_live_name: str, data_provider_historical_name: str,
api_client: any, environment_modifier=None) -> Result:
reset_state_installed_modules()
create_fake_lean_cli_directory()
create_fake_environment("live-paper", True)

if environment_modifier:
environment_modifier()

initialize_container(api_client_to_use=api_client)

option = ["--brokerage", brokerage_name]
Expand Down Expand Up @@ -1249,3 +1254,33 @@ def test_live_non_interactive_deploy_paper_brokerage_different_live_data_provide
is_exist = True

assert is_exist


@pytest.mark.parametrize("brokerage_name,data_provider_live_name,existing_cash,existing_holdings",
[("Paper Trading", "Polygon", "True", "True"),
("Paper Trading", "Polygon", "True", "False"),
("Paper Trading", "Polygon", "False", "True"),
("Paper Trading", "Polygon", "False", "False")])
def test_live_state_file(brokerage_name: str, data_provider_live_name: str,
existing_cash: bool, existing_holdings: bool) -> None:
api_client = mock.MagicMock()

def environment_modifier():
result_directory = Path.cwd() / "Python Project" / "live" / "2024-09-26_17-25-28"
result_file = result_directory / f"L-3875119070.json"
result_file.parent.mkdir(parents=True, exist_ok=True)
with open(result_file, "w+") as out_file:
state = {}
if existing_cash:
state["cash"] = {"USD": {"symbol": "USD", "amount": 100000.0}}
if existing_holdings:
state["holdings"] = {"BTCUSD 2XR":{"symbol":{"value":"BTCUSD","id":"BTCUSD 2XR","permtick":"BTCUSD"},
"type":7,"currencySymbol":"$","averagePrice":64778.92,"quantity":0.3,
"marketPrice":63425.05,"conversionRate":1.0,"marketValue":19027.515,
"unrealizedPnl":-25.98,"unrealizedPnLPercent":-0.13}}
json.dump(state, out_file)
with open(result_directory / "config", "w+") as out_file:
json.dump({"algorithm-language": "Python", "parameters": {}, "id": "3875119070"}, out_file)

create_lean_option(brokerage_name, data_provider_live_name, None, api_client,
environment_modifier=environment_modifier)
3 changes: 3 additions & 0 deletions tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ def create_fake_lean_cli_directory() -> None:

_write_fake_directory(files)


def create_fake_lean_cli_project(name: str, language: str) -> None:
"""Creates a directory structure similar to the one created by `lean init` with a given project info"""
(Path.cwd() / "data").mkdir()
Expand All @@ -121,6 +122,7 @@ def create_fake_lean_cli_project(name: str, language: str) -> None:

_write_fake_directory(files)


def create_fake_lean_cli_directory_with_subdirectories(depth: int) -> None:
"""Creates a directory structure similar to the one created by `lean init` with a Python and a C# project,
and a Python and a C# library"""
Expand Down Expand Up @@ -229,6 +231,7 @@ def create_lean_environments() -> List[QCLeanEnvironment]:
public=True)
]


def reset_state_installed_modules() -> None:
for data_provider in (cli_brokerages + cli_data_downloaders + cli_data_queue_handlers
+ cli_addon_modules + cli_history_provider):
Expand Down

0 comments on commit 90984b5

Please sign in to comment.