-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmargin_loan.py
executable file
·107 lines (87 loc) · 3.4 KB
/
margin_loan.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/usr/bin/env python3
"""Calculate the maximum balance on pledged asset line given a monthly payment."""
import io
import subprocess
import pandas as pd
import common
import ledger_amounts
import stock_options
LEDGER_LOAN_BALANCE_HISTORY_IBKR = f"{common.LEDGER_CURRENCIES_OPTIONS_CMD} -J -E bal ^Assets:Investments:'Interactive Brokers'"
LEDGER_BALANCE_HISTORY_IBKR = (
f"{common.LEDGER_PREFIX} {ledger_amounts.LEDGER_LIMIT_ETFS} "
+ "-J -E bal ^Assets:Investments:'Interactive Brokers'"
)
LEDGER_BALANCE_HISTORY_SCHWAB_NONPAL = (
f"{common.LEDGER_PREFIX} {ledger_amounts.LEDGER_LIMIT_ETFS} "
+ "-J -E bal ^Assets:Investments:'Charles Schwab Brokerage'"
)
LEDGER_LOAN_BALANCE_HISTORY_SCHWAB_NONPAL = f"{common.LEDGER_CURRENCIES_OPTIONS_CMD} -J -E bal ^Assets:Investments:'Charles Schwab Brokerage'"
def get_options_value(broker: str) -> float:
options_df = stock_options.options_df(with_value=True).query(
f'(account == "{broker}") & (ticker != ["SPX", "SMI"])'
)
options_value = options_df["value"].sum()
return options_value
def get_balances_broker(
broker: str, loan_balance_cmd: str, balance_cmd: str
) -> pd.DataFrame:
loan_df = load_loan_balance_df(loan_balance_cmd)
equity_df = load_ledger_equity_balance_df(balance_cmd)
equity_df.iloc[-1, equity_df.columns.get_loc("Equity Balance")] += ( # type: ignore
get_options_value(broker)
)
equity_df["Loan Balance"] = loan_df.iloc[-1]["Loan Balance"]
equity_df["Distance to 30%"] = (
equity_df["Loan Balance"] + equity_df["30% Equity Balance"]
)
equity_df["Distance to 50%"] = (
equity_df["Loan Balance"] + equity_df["50% Equity Balance"]
)
return equity_df
def get_balances_ibkr() -> pd.DataFrame:
return get_balances_broker(
"Interactive Brokers",
LEDGER_LOAN_BALANCE_HISTORY_IBKR,
LEDGER_BALANCE_HISTORY_IBKR,
)
def get_balances_schwab_nonpal() -> pd.DataFrame:
return get_balances_broker(
"Charles Schwab Brokerage",
LEDGER_LOAN_BALANCE_HISTORY_SCHWAB_NONPAL,
LEDGER_BALANCE_HISTORY_SCHWAB_NONPAL,
)
def load_ledger_equity_balance_df(ledger_balance_cmd: str) -> pd.DataFrame:
"""Get dataframe of equity balance."""
equity_balance_df = pd.read_csv(
io.StringIO(subprocess.check_output(ledger_balance_cmd, shell=True, text=True)),
sep=" ",
index_col=0,
parse_dates=True,
names=["date", "Equity Balance"],
)
equity_balance_df["30% Equity Balance"] = equity_balance_df["Equity Balance"] * 0.3
equity_balance_df["50% Equity Balance"] = equity_balance_df["Equity Balance"] * 0.5
return equity_balance_df
def load_loan_balance_df(ledger_loan_balance_cmd: str) -> pd.DataFrame:
"""Get dataframe of margin loan balance."""
loan_balance_df = pd.read_csv(
io.StringIO(
subprocess.check_output(ledger_loan_balance_cmd, shell=True, text=True)
),
sep=" ",
index_col=0,
parse_dates=True,
names=["date", "Loan Balance"],
)
loan_balance_df.loc[loan_balance_df["Loan Balance"] > 0, "Loan Balance"] = 0
return loan_balance_df
def main():
"""Main."""
for title, get_balances in [
("Interactive Brokers", get_balances_ibkr),
("Charles Schwab", get_balances_schwab_nonpal),
]:
df = get_balances()
print(title, "\n", df, "\n")
if __name__ == "__main__":
main()