Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

utils.make_index : TypeError: unsupported operand type(s) for +: 'float' and 'str' #349

Open
Sav-Coelho opened this issue Apr 26, 2024 · 6 comments

Comments

@Sav-Coelho
Copy link

While trying to use make_index I am getting a TypeError: unsupported operand type(s) for +: 'float' and 'str' message. This is my code that caused the error:

import quantstats as qs
qs.extend_pandas()

IAC = {"SPY": 1.3, "AGG": -.3}

portfolio = qs.utils.make_index(IAC)

I even tested with other ticker combinations and directly entering the ticker and weights in make_index and the error repeats in the same way. I also tested in previous versions and the error repeats again. Does anyone know if there is an error in the package or is it my code?

imagem_2024-04-26_084831587

@FPALMAG
Copy link

FPALMAG commented Apr 29, 2024

I have the same error, it is not posible to run the tickers and weights of a portfolio

@benjoergens
Copy link

I am also encountering this issue... nothing I have done is fixing it.

@baobach
Copy link

baobach commented Apr 30, 2024

Can you use a different way to generate the dictionary?
try

IAC = dict(SPY = 1.3, AGG = -0.3)

Also it would be useful if you can copy the output error code as a text and paste it in here.

@benjoergens
Copy link

Can you use a different way to generate the dictionary? try

IAC = dict(SPY = 1.3, AGG = -0.3)

Also it would be useful if you can copy the output error code as a text and paste it in here.

I tried generating the dict as above, but to no avail... Here is my error code as text:

/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/quantstats/utils.py:379: FutureWarning: 'M' is deprecated and will be removed in a future version, please use 'ME' instead.
rbdf = index.resample(rebalance).first()
Traceback (most recent call last):
File "/Users/benjoergens/PycharmProjects/Assignment/Assignment.py", line 117, in
qs.utils.make_index(strategy)
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/quantstats/utils.py", line 400, in make_index
return index[index.index <= last_day].sum(axis=1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/frame.py", line 11670, in sum
result = super().sum(axis, skipna, numeric_only, min_count, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/generic.py", line 12506, in sum
return self._min_count_stat_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/generic.py", line 12489, in _min_count_stat_function
return self._reduce(
^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/frame.py", line 11562, in _reduce
res = df._mgr.reduce(blk_func)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/internals/managers.py", line 1500, in reduce
nbs = blk.reduce(func)
^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/internals/blocks.py", line 404, in reduce
result = func(self.values)
^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/frame.py", line 11481, in blk_func
return op(values, axis=axis, skipna=skipna, **kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/nanops.py", line 85, in _f
return f(*args, **kwargs)
^^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/nanops.py", line 404, in new_func
result = func(values, axis=axis, skipna=skipna, mask=mask, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/nanops.py", line 477, in newfunc
return func(values, axis=axis, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/pandas/core/nanops.py", line 646, in nansum
the_sum = values.sum(axis, dtype=dtype_sum)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/benjoergens/PycharmProjects/Assignment/.venv/lib/python3.12/site-packages/numpy/core/_methods.py", line 49, in _sum
return umr_sum(a, axis, dtype, out, keepdims, initial, where)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: unsupported operand type(s) for +: 'float' and 'str'

@RobertHH-IS
Copy link

Same error

Simplest code, latest 0.0.62 version

%matplotlib inline
import quantstats as qs
import pandas as pd

extend pandas functionality with metrics, etc.

qs.extend_pandas()

conservative = {"IVV": 0.5,"URTH": 0.5}
qs.utils.make_index(ticker_weights=conservative, period="1y")

@RobertHH-IS
Copy link

I did a quick fix in the code and it works now. Fork, uninstall library, git clone, pip install -e . , make changes, save, works.

`def make_index(
ticker_weights, rebalance="1M", period="max", returns=None, match_dates=False
):
"""
Makes an index out of the given tickers and weights.
Optionally you can pass a dataframe with the returns.
If returns is not given it try to download them with yfinance

Args:
    * ticker_weights (Dict): A python dict with tickers as keys
        and weights as values
    * rebalance: Pandas resample interval or None for never
    * period: time period of the returns to be downloaded
    * returns (Series, DataFrame): Optional. Returns If provided,
        it will fist check if returns for the given ticker are in
        this dataframe, if not it will try to download them with
        yfinance
Returns:
    * index_returns (Series, DataFrame): Returns for the index
"""
# Declare a returns variable
index = None
portfolio = {}

# Iterate over weights
for ticker in ticker_weights.keys():
    if (returns is None) or (ticker not in returns.columns):
        # Download the returns for this ticker, e.g. GOOG
        ticker_returns = download_returns(ticker, period)
    else:
        ticker_returns = returns[ticker]

    portfolio[ticker] = ticker_returns

# index members time-series
index = _pd.DataFrame(portfolio).dropna()

if match_dates:
    index = index[max(index.ne(0).idxmax()) :]

# no rebalance?
if rebalance is None:
    for ticker, weight in ticker_weights.items():
        index[ticker] = weight * index[ticker]
    return index.sum(axis=1)

last_day = index.index[-1]

# rebalance marker
rbdf = index.resample(rebalance).first()
rbdf["break"] = rbdf.index.strftime("%s")

# index returns with rebalance markers
index = _pd.concat([index, rbdf["break"]], axis=1)

# mark first day day
index["first_day"] = _pd.isna(index["break"]) & ~_pd.isna(index["break"].shift(1))
index.loc[index.index[0], "first_day"] = True

# multiply first day of each rebalance period by the weight
for ticker, weight in ticker_weights.items():
    index[ticker] = _np.where(
        index["first_day"], weight * index[ticker], index[ticker]
    )

# drop first marker and break column
index.drop(columns=["first_day", "break"], inplace=True)

# drop when all are NaN
index.dropna(how="all", inplace=True)

# Ensure only numeric columns are summed
numeric_cols = index.select_dtypes(include=[_np.number]).columns
return index[numeric_cols][index.index <= last_day].sum(axis=1)`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants