fumitoh / modelx

Use Python like a spreadsheet!
https://modelx.io
GNU Lesser General Public License v3.0
89 stars 20 forks source link

FormulaError #72

Open SunnyHillSpaces opened 1 year ago

SunnyHillSpaces commented 1 year ago

Hi

do you please know what can cause this error ?

FormulaError: Error raised during formula execution ValueError: ('Lengths must match to compare', (164,), (3,))

Formula traceback: 0: m_2022_06_30.xxx.bs[-1].Dividend(t=0, proxy_flag=False), line 5 ... 24: m_2022_06_30.xxx.asset[-1, True].BV(t=0, step=2, AoS_step=0, level=4), line 8 25: m_2022_06_30.xxx.asset[-1, True].BV_Instrument(t=0), line 10 26: m_2022_06_30.xxx.asset[-1, True].BV_Yield(t=0), line 18

Formula source:

def BV_Yield(t):
    step = 4
    pos = Position(t - 1, step=step) if t > 0 else Position(0, 0)
    out = pd.Series(0.0, pos.index)
    if t > 0:
        prev = Position(t - 1, step=step - 1)
        pos_change = pos.sub(prev, fill_value=0)
        ind_zero = pos_change.index[pos_change == 0]
        out[ind_zero] = BV_Yield(t - 1)[ind_zero]
        ind = pos_change[pos_change != 0].index
        prev_ind = prev.index
    else:
        ind = out.index
        prev_ind = []

    bvs = BV(t - 1, step=step, level=4) if t > 0 else data.BV_t0() / 1e6
    # ind = ind[instr.param.Fixed_Flag()[ind.droplevel('Portfolio')]]
    ind = ind[ind.droplevel('Portfolio') != cash_index]
    pos = pos[ind]

    for index, bv in bvs[ind].iteritems():
        cf = instr.CF_vec(t - 1 * (t > 0))[index[1:]] * pos[index]
        out[index] = sf.xirr(bv, cf.values, cf.index,
                             guess=(BV_Yield(t-1)[index] if index in prev_ind else 0), sec_id=index)
    return out

       prev_ind = prev.index
    else:
        ind = out.index
        prev_ind = []

    bvs = BV(t - 1, step=step, level=4) if t > 0 else data.BV_t0() / 1e6
    # ind = ind[instr.param.Fixed_Flag()[ind.droplevel('Portfolio')]]
    ind = ind[ind.droplevel('Portfolio') != cash_index]
    pos = pos[ind]

    for index, bv in bvs[ind].iteritems():
        cf = instr.CF_vec(t - 1 * (t > 0))[index[1:]] * pos[index]
        out[index] = sf.xirr(bv, cf.values, cf.index,
                             guess=(BV_Yield(t-1)[index] if index in prev_ind else 0), sec_id=index)
    return out
fumitoh commented 1 year ago

The error message says line 18 ind = ind[ind.droplevel('Portfolio') != cash_index] is wrong becasue the length of ind.droplevel('Portfolio') is 64 and the length of cash_index is 3 so pandas can't compare them.

fumitoh commented 1 year ago

modelx v0.21.0 would show local variabls such as ind and pos in the case above. See #73.