def create_stock_overview(self): irr = -self.balance["Fees"] for s in self.stocks: self.stock_stats.loc[s.display_name] = [ s.total_number, s.events["Sold again"].sum(), s.stats["Invested capital"][-1], s.stats["Value over time"][-1], s.stats["Return absolute"][-1], s.stats["IRR"][-1], np.nan, s.events["Dividend"].sum() ] irr = irr.add(s.stats["IRR-series, current price"], fill_value=0) bm = self.overview["Benchmark"].resample("Y").last().diff(periods=1) bm[0] = -self.overview["Benchmark"].resample("Y").first()[0] bm[-1] += self.overview["Benchmark"].resample("Y").last().iloc[-1] self.stock_stats.loc["Portfolio", "IRR-BM"] = np.irr(bm) self.stock_stats.loc["Portfolio", [ "Currently held", "Prev. sold positions", "Currently invested capital", "Current value", "Dividends" ]] = self.stock_stats[[ "Currently held", "Prev. sold positions", "Currently invested capital", "Current value", "Dividends" ]].sum() self.stock_stats.loc[ "Portfolio", "Return absolute"] = self.overview["Return absolute"][-1] self.stock_stats.loc["Portfolio", "IRR"] = np.irr(irr.resample("Y").sum()) display(self.stock_stats)
def irr(flow, time_index): """Returns the Internal Rate of Return (IRR) of a series of periodic payments (negative values) and inflows (positive values). The IRR is the discount rate at which the Net Present Value (NPV) of the flows equals zero. The variable flow must be indexed by time_index. If the cash flow never changes sign, cp.irr() has no solution and returns NAN (Not A Number). """ import pandas as pd _cube_dimensions = index("flowdims", flow.dims) _rest_of_indexes_labels = subset( _cube_dimensions != time_index.name).values _rest_of_indexes = [flow.axis(xx) for xx in _rest_of_indexes_labels] _cube = None if len(_rest_of_indexes) == 0: _cube = np.irr(flow.values) else: _cube = cube(_rest_of_indexes) _multivalues = [idx.values for idx in _rest_of_indexes] _values = pd.MultiIndex.from_product(_multivalues).values for _item in _values: _filter = [] for _nn in range(len(_item)): _filter.append(_rest_of_indexes[_nn].filter([_item[_nn]])) _irr = np.irr(flow.filter(_filter).squeeze().values) _cube.set_data(_filter, _irr) return _cube
def irr(cf): """ Internal Rate of Return (IRR) cf - cash flow stream (including any initial investment < 0) """ import numpy as np np.irr(cf)
def ESCO(priceReduction, Energy_anual, Fuel_price, Boiler_eff, n_years_sim, Investment, OM_cost_year, incremento, Co2_savings): #Inputs # Energy_anual=636632 #Energy produced annualy by the solar plant in kWh # Fuel_price=0.04 #Price of fossil fuel in €/kWh # Boiler_eff=0.95 #Boiler efficiency to take into account the excess of fuel consumed # n_years_sim=20 #Number of years for the simulation # Investment=130000 #Initial investment in € # OM_cost_year=5000 #Cost of O&M/year in € #SIMULATION #Variable initiation fuelPrizeArray = np.zeros(n_years_sim) Energy_produced = np.zeros(n_years_sim) Energy_savings = np.zeros(n_years_sim) BenefitESCO = np.zeros(n_years_sim) OM_cost = np.zeros(n_years_sim) Net_anual_savings = np.zeros(n_years_sim) Accumulated_savings = np.zeros(n_years_sim) FCF = np.zeros(n_years_sim) Acum_FCF = np.zeros(n_years_sim) for i in range(0, n_years_sim): if i == 0: Energy_produced[i] = 0 Energy_savings[i] = 0 OM_cost[i] = 0 Net_anual_savings[i] = 0 Accumulated_savings[i] = 0 Acum_FCF[i] = 0 #There is no investment FCF[i] = 0 fuelPrizeArray[i] = Fuel_price else: Energy_produced[i] = Energy_anual BenefitESCO[i] = priceReduction * ( Energy_anual * (Fuel_price * (1 + incremento)**(i - 1)) / Boiler_eff) #€ benefit for the ESCO Energy_savings[i] = (1 - priceReduction) * ( Energy_anual * (Fuel_price * (1 + incremento)**(i - 1)) / Boiler_eff) + Co2_savings #€ benefit for the industry OM_cost[i] = OM_cost_year Net_anual_savings[i] = BenefitESCO[i] - OM_cost[i] Accumulated_savings[i] = Accumulated_savings[ i - 1] + Net_anual_savings[i] Acum_FCF[i] = Acum_FCF[i - 1] + Net_anual_savings[i] FCF[i] = Net_anual_savings[i] fuelPrizeArray[i] = (Fuel_price * (1 + incremento)**(i - 1)) IRR10 = 100 * np.irr(FCF[:10]) IRR = 100 * np.irr(FCF) Amort_year = (Acum_FCF <= 0).sum() return [ IRR, IRR10, Amort_year, Acum_FCF, FCF, BenefitESCO, OM_cost, fuelPrizeArray, Energy_savings, Net_anual_savings ]
def irr(list_cash, x, sale): cash_flow = list_cash[0:(int(x))] last_value = cash_flow[(int(x) - 1)] replacement = sale + last_value cash_flow[(int(x) - 1)] = replacement irr = np.irr(cash_flow) return irr * 1200.0
def outputRow(): #NOTE: The fields of the db row, such a loan_id, are no longer available when this is called. discountRate = principalDiscountRates[finalStatus] numeratorNARdiscount = prev_balance_end * discountRate cashflowLen = len(cashflow) while cashflow[cashflowLen-1]==0: cashflowLen -= 1 cashflow.resize(max(cashflowLen, receivedMonthIndex+1)) npv = np.npv(monthlyDiscountRate-1, cashflow) if printCashflow: print(cashflow) if finalStatus != 'Charged Off': cashflow[receivedMonthIndex] += prev_balance_end * (1-discountRate) / prev_investment if printCashflow: print(cashflow) npvForecast = np.npv(monthlyDiscountRate-1, cashflow) irrForecast = (1+np.irr(cashflow))**12 - 1 finalStatusIsComplete = finalStatus in ["Charged Off", "Default", "Fully Paid"] output.append(( prev_loan_id, finalStatus, prev_mob, missedPayment, firstMissed, dueWhenFirstMissed, receivedAfterMissed, riskFreeRate, npv, npvForecast, firstMissedOrLastObserved, (numeratorNAR-numeratorNARdiscount)/prev_investment, denominatorNAR/prev_investment, finalStatusIsComplete, irrForecast, #cashflow ))
def getIRR(cashflow): """get Internal Rate of Return. Args: cashflow: cashflow """ return round(np.irr(cashflow), 5) * 100
def calcTrialStats(self): """post-processing: calculate the returns, vol etc. of the sim paths""" volfactor = np.sqrt(self.frequency) T = len(self.price.iloc[:, 0]) for trial in range(0, self.trials): self.trialStats.iloc[trial]['HPA Return'] = ( self.price.iloc[-1, trial] / self.price.iloc[0, trial])**(1 / (T / self.frequency)) - 1 irrSeries = self.dividend.iloc[:, trial] + self.residualCashFlow.iloc[:, trial] - self.ramp self.trialStats.iloc[trial]['Investment IRR'] = np.irr( irrSeries.iloc[:self.processLife]) * self.frequency self.trialStats.iloc[trial][ 'HPA Vol'] = self.price.iloc[:, trial].pct_change().std( ) * volfactor self.trialStats.iloc[trial][ 'Investment Vol'] = self.totalInvestorValue.iloc[:, trial].pct_change( ).std( ) * volfactor self.trialStats.iloc[trial]['Average Life'] = np.dot( self.residualCashFlow.iloc[:, trial], self.residualCashFlow.iloc[:, trial].index ) / self.residualCashFlow.iloc[:, trial].sum() / self.frequency return self.trialStats
def main(): rng = pd.date_range('2/28/2018', periods=300, freq='M') Escalator = 0.029 Recurring_Payment = 95 Committed_Capital = -1500 CC_date = pd.to_datetime('01/31/2018') Start_Date = pd.to_datetime('02/28/2018') df2 = pd.DataFrame(index=rng, columns=['Cash Flow']) #df2['Start Date'] = pd.to_datetime('02/28/2018') df2['Date Diff'] = df2.index - Start_Date #rng - pd.to_datetime('02/28/2018') #df2['Recurring Payment'] = 95 #df2['Escalator'] = 0.029 df2['Year Diff'] = (df2.index - Start_Date) / np.timedelta64(365, 'D') df2['Year Diff'] = df2['Year Diff'].astype(int) df2['Cash Flow'] = (Recurring_Payment * (1 + Escalator)**df2['Year Diff']) df2.to_csv( r'C:\Users\denny.lehman\Documents\18_01 Monthly Portfolio Report\test.csv' ) print('numpy npv model:') print(np.npv(0.06, df2['Cash Flow'])) print('Denny npv model:') print(npv(0.06, df2['Cash Flow'])) # df2['Curr Date'] = df2.index df2.loc[CC_date] = [Committed_Capital, 0, 0] df2 = df2.sort_index() #df2.append(pd.DataFrame([CC_date, Committed_Capital, 0, 0])) print('numpy irr:') print(np.irr(df2['Cash Flow']))
def ytm_calculation(price, maturity, coupon, face_value, freq): """ :param price: current price of the bond :param maturity: number of years to maturity :param coupon: coupon rate of the bond :param face_value: faceValue of the bond :param freq: frequency of the compounding :return: the irr (YTM) of the bond Notes: The yield to maturity (irr) calculation uses the numpy.irr library, which adopts a method that finds the root of a polynomial by solving the eigenvalue of the companion matrix. For a detailed explanation, please see http://web.mit.edu/18.06/www/Spring17/Eigenvalue-Polynomials.pdf There are other faster, and generic ways to solve for the root of polynomial. i.e. the Newton-Raphson method. For an example of YTM calculation using this method please see https://github.com/jamesmawm/ Mastering-Python-for-Finance-source-codes/blob/master/B03898_05_Codes/bond_ytm.py """ cash_flow = [-1 * price] cash_flow.extend([face_value * coupon / freq] * (maturity * freq - 2)) cash_flow.append(face_value * (1 + coupon / freq)) ytm = np.irr(cash_flow) return ytm
def computeIRR(dfForMonthlyVintage): initialCashOutlay = dfForMonthlyVintage[ _g.VINTAGE_PRINCIPAL].unique()[0] cashFlows = dfForMonthlyVintage[_g.VINTAGE_CASHFLOW_FOR_IRR].values cashFlows = np.insert(cashFlows, 0, [-1 * initialCashOutlay]) irrDecimal = np.irr(cashFlows) return irrDecimal * 100 # Map from decimal to %
def cal_annual_rate_5(total_money, total_month, per_day_rate): # total_money 总计借款数量 # total_month 总共分期期数 load_infos = [-total_money] month_rates = (per_day_rate / 10000.0 * total_money) * 360.0 / 12.0 for month_index in range(total_month - 1): load_infos.append(month_rates) load_infos.append(month_rates + total_money) per_month_rate = np.irr(load_infos) # 计算年化收益率(复利公式) year_rate = (per_month_rate + 1)**12 - 1 #还款利息总和 t_total_rate_money = (per_day_rate / 10000.0 * total_money) * 360.0 print("\n\n{:^70}\n\n\n贷款总额:{}, 总分 {} 期, 日息 万分之{},还款方式:先息后本:\n".format( "信用卡分期利息计算", total_money, total_month, per_day_rate)) print("利息如下:实际月利息 = {}%, 名义年利率 = {}%,实际年利率 = {}%\n".format( r(per_month_rate * 100), r(12 * per_month_rate * 100), r(year_rate * 100))) print("还款细节:每 1 - {} 月月供为 {:.2f}, 第 {} 个月月供为 {}, 总利息 {:.2f}\n".format( total_month - 1, r(month_rates), total_month, r(total_money + month_rates), r(month_rates) * 12.0))
def cashflow(purchase_price=PURCHASE_PRICE, rent=RENT, years=5): net_cash_flow = [] df = pd.DataFrame(columns=[range(0, years)], index=INDEXES) net_purchase_price = purchase_price * (1 + ACQUISITION_COST) net_cash_flow.append(net_purchase_price * -1.0) series = [] for year in xrange(0, years): series.append( cal_current_operation_flow(purchase_price, rent, year)) df = pd.concat(series, axis=1, keys=range(1, years + 1)) df = pd.DataFrame.transpose(df) net_sale_price = purchase_price * math.pow( 1 + HOME_PRICE_APPRECIATION, years) * (1 - DISPOSTITION_COST) net_cash_flow += df[UNLEVERAGED_CASH_FLOW_STR].tolist() net_cash_flow[-1] += net_sale_price # print net_cash_flow irr_value = round(irr(net_cash_flow), 4) cap_rate = round(abs(1.0 * net_cash_flow[1] / net_cash_flow[0]), 4) #print cap_rate * 100, irr_value * 100 returns = [df[INDEXES[0]].tolist()] revenue = [df[INDEXES[i]].tolist() for i in range(1, 4)] expenses = [df[INDEXES[i]].tolist() for i in range(4, 13)] return { "flow": { "returns": returns, "revenue": revenue, "expenses": expenses }, "cap_rate": cap_rate * 100, "irr": irr_value * 100 }
def get_duration_dispersion_convexity(self, periods=1, current_period=0): """ Computes duration and convexity using loan cashflows. At the moment this is not accounting for prepayments """ discounted_cashflow = [ self.payment / (1 + self.interest)**i for i in self.index[current_period:] ] discount_sum = sum(discounted_cashflow) weight = [cf / discount_sum for cf in discounted_cashflow] time_weight = [weight[i] * i for i in range(1, len(weight))] sum_time_weight = sum(time_weight) dispersion_array = [((i - sum_time_weight)**2) * weight[i] for i in range(1, len(weight))] dispersion_statistic = sum(dispersion_array) cashflow_yield = np.irr([-self.table["balance"][current_period]] + [self.payment] * (self.maturity - current_period)) convexity_array = [ i * (i + 1) * weight[i] for i in range(1, len(weight)) ] convexity_statistic = sum(convexity_array) / (1 + cashflow_yield)**2 convexity = (sum_time_weight**2 + sum_time_weight + dispersion_statistic) / (1 + cashflow_yield)**2 return {"duration":sum_time_weight/periods,\ "dispersion":dispersion_statistic/periods,\ "convexity":convexity_statistic/periods}
def irr(values, guess=None): """ Function to calculate the internal rate of return (IRR) using payments and periodic dates. It resembles the excel function IRR(). Excel reference: https://support.office.com/en-us/article/IRR-function-64925eaa-9988-495b-b290-3ad0c163c1bc :param values: the payments of which at least one has to be negative. :param guess: an initial guess which is required by Excel but isn't used by this function. :return: a float being the IRR. """ if isinstance(values, Range): values = values.values if is_not_number_input(values): return numeric_error(values, 'values') if guess is not None and guess != 0: raise ValueError('guess value for excellib.irr() is %s and not 0' % guess) else: try: return np.irr(values) except Exception as e: return ExcelError('#NUM!', e)
def irr(cflo): """Computes the internal rate of return of a generic cashflow as a periodic interest rate. Args: cflo (pandas.Series): Generic cashflow. Returns: Float or list of floats. **Examples.** >>> cflo = cashflow([-200] + [100]*4, start='2000Q1', freq='Q') >>> irr(cflo) # doctest: +ELLIPSIS 34.90... >>> irr([cflo, cflo]) # doctest: +ELLIPSIS 0 34.90... 1 34.90... dtype: float64 """ if isinstance(cflo, pd.Series): cflo = [cflo] retval = pd.Series([0] * len(cflo), dtype=np.float64) for index, xcflo in enumerate(cflo): retval[index] = (100 * np.irr(xcflo)) if len(retval) == 1: return retval[0] return retval
def getCohortIRR(df, cancelRsv, discountAmt): #select cohort installments cohort = df.copy() cashflows = [0] * 24 #identify what transaction times are and label them as time 0,1,2,3,4...etc. #iterrate by rows/contracts for i, row in cohort.iterrows(): term = row.Installments paylink_fee = 4.0 instAmt = row.CurrentInstallmentAmount ppAmt = term * instAmt paymentsMade = row.PaymentsMade for i in range(term): if i == 0: #initial amount @ t0 T0 = instAmt - (paylink_fee + ppAmt - discountAmt - cancelRsv) cashflows[i] += round(T0, 2) elif i < paymentsMade: #amt received each month from customer, if not cancelled T = instAmt - paylink_fee cashflows[i] += round(T, 2) else: #if contract is cancelled, last cashflow is returned premium cashflows[i] += row.ReturnedPremium break cashflows = [round(x, 2) for x in cashflows] #print cashflows result = filter(lambda x: x != 0, cashflows) return np.irr(result)
def f_comp_IRR(trchDCF, n, trchSize): ''' n表示第0期第n档对应的PV的索引 ''' DCF = np.insert(trchDCF, 0, -trchSize[n]) # 插入第0期 re = np.irr(DCF) return re
def irr(self): cashFlow = [-self._notional] for i in range(1, self._period): totalPayment = self._principalPayments[i] + self._interestPayments[ i] cashFlow.append(totalPayment) return np.irr(cashFlow) * 12
def on_strategy_end(context): g.cash_income.append(context.portfolio.positions_value) month_rate = np.irr(g.cash_income) year_rate = (1 + month_rate)**12 - 1 log.info('回测结束,策略按月内部收益率 = ' + str(month_rate) + ',实际年收益率 = ' + str(year_rate)) log.info('策略执行结束总资产 = ' + str(context.portfolio.total_value))
def economic_summary(df_cashFlow): NPV = np.npv(discount_rate, df_cashFlow['Net']) / 1000 NPV_CO2_storage = np.npv(discount_rate, df_cashFlow['with_CO2']) / 1000 NPV_CO2_storage_RC = np.npv(discount_rate, df_cashFlow['with_CO2_RC']) / 1000 IRR = np.irr(df_cashFlow['Net']) return [NPV, NPV_CO2_storage, NPV_CO2_storage_RC, IRR]
def pd_to_rate(pd_365, selic_360, margem_360): juros_tot_360 = (1 + selic_360)*(1 + margem_360)-1 print('juros_tot_360 = ' + str('{0:.4%}'.format((juros_tot_360)))) juros_tot_30 = (1 + juros_tot_360)**(1/12)-1 print('juros_tot_30 = ' + str('{0:.4%}'.format((juros_tot_30)))) xpmt = 1/(1/((1+juros_tot_30)**1)+1/((1+juros_tot_30)**2)) adimp_1 = (1-pd_365)**(30/365) adimp_2 = (1-pd_365)**(60/365) print('xpmt = ' + str(xpmt)) print('pd_365 = ' + str('{0:.4%}'.format(pd_365))) print('1-pd_365 = ' + str(1-pd_365)) print('adimp_1 = ' + str(adimp_1)) print('adimp_2 = ' + str(adimp_2)) cf_1 = xpmt/adimp_1 print('cf_1 = ' + str(cf_1)) cf_2 = xpmt/adimp_2 print('cf_2 = ' + str(cf_2)) taxa_30 = np.irr([-1, cf_1, cf_2]) taxa_30_1 = (1+juros_tot_30)/adimp_1-1 taxa_30_2 = (1+juros_tot_30)/((1-pd_365)**(30/365))-1 return taxa_30_2
def f_metricas_financieras(utilidad, param_inversion, param_tasa, n_sim): """ Parameters ---------- utilidad : DataFrame : utilidades de todas las simulaciones param_inversion : int : inversion inicial param_tasa : float : tasa de descuento n_sim : int : numero de simulaciones Returns ------- vpn : list : valor presente neto tir : list : tasa interna de retorno Debugging ------- utilidad = pd.DataFrame([100, 200, 300], [100, 150, 350]) param_inversion = 9000 param_tasa = 0.10 n_sim = 10 """ inversion = pd.DataFrame(np.full(shape=n_sim, fill_value=-param_inversion)) flujo = pd.concat([inversion.T, utilidad]).reset_index(drop=True) vpn = [np.npv(param_tasa, flujo.iloc[:, i]) for i in range(n_sim)] tir = [round(np.irr(flujo.iloc[:, i]) * 100, 2) for i in range(n_sim)] return vpn, tir
def calcIrr(self, initial_growth=0.035, terminal_growth=0.02, discount_rate=0.04): ''' Assumptions: Five near year growth rate = 0.035 Terminal growth rate = 0.02 Cost of capital = 0.04 ''' self.operCost = self.calcOperatingCost() rental_cf = [self.rentalPrice - self.operCost] * 60 rental_cf = [ rental_cf[i] * (1 + initial_growth)**i for i in range(len(rental_cf)) ] rental_cf.insert(0, -unitCost) try: terminal_val = rental_cf[-1] * (1 + terminal_growth) / ( discount_rate - terminal_growth) except ZeroDivisionError: terminal_val = rental_cf[-1] * (1 + terminal_growth) / (0.04 - 0.02) print( "Discount rate cannot be equal to the terminal growth rate, rendering division by 0 for terminal value.\nUse today's typical 30 year morgage rate and 2 percent terminal growth." ) rental_cf.append(terminal_val) self.rental_income_stream = np.array(rental_cf) mont_irr = np.irr(np.array(rental_cf)) year_irr = (1 + mont_irr)**12.0 - 1 self.year_irr = year_irr return year_irr
def stress_case_5_timed_expense(model): # Defining rows acct_bal_BOP = 0 income = 1 expenses = 2 additional_expenses = 3 loan_expense = 4 loan_principal = 5 acct_bal_EOP = 6 CF = 7 info_array = np.zeros((CF + 1, model.loan_tenor + 1)) info_array[acct_bal_EOP, 0] = model.current_account_balance info_array[CF, 0] = -model.loan_amount for week in range(1, model.loan_tenor + 1): info_array[acct_bal_BOP, week] = info_array[acct_bal_EOP, week - 1] info_array[income, week] = model.account_balance_base_case.info_array[1, week] info_array[expenses, week] = model.account_balance_base_case.info_array[2, week] if week == model.timed_expense_shock_1_weeks or week == model.timed_expense_shock_2_weeks: info_array[additional_expenses, week] = model.avg_weekly_expense_3mth * ( 1 - model.timed_expense_shock) else: info_array[additional_expenses, week] = 0 if info_array[:loan_expense, week].sum() < 0: info_array[loan_expense, week] = 0 else: info_array[loan_expense, week] = -min( info_array[:loan_expense, week].sum(), model.base_loan_cf.info_array[1:3, week].sum()) if info_array[:loan_principal, week].sum() < 0: info_array[loan_principal, week] = 0 else: info_array[loan_principal, week] = -min(info_array[:loan_principal, week].sum(), model.base_loan_cf.info_array[3, week]) info_array[acct_bal_EOP, week] = info_array[:acct_bal_EOP, week].sum() info_array[CF, week] = -info_array[loan_expense:acct_bal_EOP].sum() # MOI moi = info_array[CF, 1:].sum() / -info_array[CF, 0] # IRR in years, converted to weeks irr = (1 + np.irr(info_array[CF]))**52 - 1 return info_array, moi, irr
def model_irr(entry_price, exit_price, year): cash_flows = [] for y in range(0, year + 1): cash_flows.append(0) cash_flows[0] = np.negative(entry_price) cash_flows[year] = exit_price irr_output = np.irr(cash_flows) return irr_output
def internal_rate_of_return_aggregate_for_portfolio(self): """ Calculates the portfolio's aggregate internal rate of return. Returns: The portfolio's aggregate internal rate of return. """ agg_irr = np.irr(list(self.aggregate_flows_df['total_payments'])) return float(agg_irr)
def measure_judgment(self): self.cost_pv = round(self.costs['Discounted Cash Flow'].sum(), 2) self.benefit_pv = round(self.benefits['Discounted Cash Flow'].sum(), 2) self.npv = round(self.benefit_pv - self.cost_pv, 2) self.b_to_c = round(self.benefit_pv / self.cost_pv, 2) self.irr = round(np.irr(self.pure_cash_flow), 2) self.pbp = round(self.calculate_simplePBP(), 2) self.dpbp = round(self.calculate_discountedPBP(), 2)
def IRR(self, other=False): if other: if len(self.pos) != len(other.pos): raise SyntaxError("mismatched study periods, cannot calculate IRR") toCheck = [j-i for i,j in zip(self.get_mergedSeries(),other.get_mergedSeries())] else: toCheck = self.get_mergedSeries() return irr(toCheck)
def test_npv_irr_congruence(self): # IRR is defined as the rate required for the present value of a # a series of cashflows to be zero i.e. NPV(IRR(x), x) = 0 cashflows = np.array([-40000, 5000, 8000, 12000, 30000]) assert_allclose(np.npv(np.irr(cashflows), cashflows), 0, atol=1e-10, rtol=0)
def irr_calc(fundings_array_IN, cf_array_IN, frequency_IN=12, px=100): if sum(cf_array_IN) < 0.5 * sum( fundings_array_IN ) * px * 1.0 / 100: # less than half of investment is returned return -1 else: return np.irr(-1 * fundings_array_IN * px * 1.0 / 100 + cf_array_IN) * frequency_IN
def loanIRR(ID): Time = years(ID) Z = np.zeros(Time + 1) Z[0] = -1 A = initialArray(ID) C = payoffArray(ID) for i in range(1, (Time + 1)): Z[i] = A.dot(matrixPower(i)).dot(C) return np.irr(Z)
def irr(values, guess = None): # Excel reference: https://support.office.com/en-us/article/IRR-function-64925eaa-9988-495b-b290-3ad0c163c1bc # Numpy reference: http://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.irr.html if (isinstance(values, Range)): values = values.values if guess is not None and guess != 0: raise ValueError('guess value for excellib.irr() is %s and not 0' % guess) else: try: return np.irr(values) except Exception as e: return ExcelError('#NUM!', e)
def internal_rate_of_return_for_loan(self, loan): """ Calculates a loan's internal rate of return from its cash flows. Args: loan: The loan which is being considered. Returns: The internal rate of return of the loan. """ cash_flows = self.cash_flows_df[self.cash_flows_df['loan_df_pk'] == loan.name] total_payments_list = list(cash_flows['total_payments']) internal_rate_of_return = np.irr(total_payments_list) return internal_rate_of_return
def metrics(price, percentDown, closingCosts,repairCosts,rate,term,fedTaxRate,stTaxRate,capitalGains,propTaxRate,insPremiumYr, HOA,hoaIncRate, repairsYr, vacancyPc, propMgmtMo, rent, rentIncRate,appreciationRate, inflation,bldgValPct,sellYear): years = linspace(0, term, term+1) cashflowND = [0]*len(years) for year in years: y = int(year) if y <= sellYear: payment, downPayment, cashToClose, cashToOperate = loanCalcs(price, percentDown, closingCosts, repairCosts, rate, term) equity, mortBal, appVal, interestYr = equityCalcs(y, price, downPayment, payment, rate, appreciationRate) capex = capexF(y, sellYear, repairsYr, cashToOperate, appVal, price) revenue, vacancy = revenueF(rent, rentIncRate, vacancyPc, y) opexTotal, opexLessDS, deductibles = opexF(payment, propTaxRate, insPremiumYr, HOA, hoaIncRate, propMgmtMo, price, y, interestYr, vacancy) NOI = NOIF(revenue, opexLessDS) if y is 1: NOI1=NOI deductions = deductionsF(deductibles, price, bldgValPct) taxes = taxesF(price, appVal, revenue, deductions, capex, fedTaxRate, stTaxRate, capitalGains, y, sellYear) cashflowND[y] = cashflowATF(revenue, opexTotal, taxes, capex, equity, y, sellYear) capRateYr1 = price/NOI1 NFV = sum(cashflowND) PV10 = npv(.1,cashflowND) ROR = irr(cashflowND) cashPayout = payoutCalc(cashflowND, cashToOperate) cashOnCashYr1 = cashToOperate/cashflowND[1] moCashflowYr1 = cashflowND[1]/12. metricsDict = { "NFV" : NFV, "PV10" : PV10, "ROR" : ROR, "capRateYr1" : capRateYr1, "cashPayout" : cashPayout, "cashOnCashYr1" : cashOnCashYr1, "moCashflowYr1" : moCashflowYr1, "cashToClose" : cashToClose, "cashToOperate" : cashToOperate, } # print "NFV = $%s" %"{:,}".format(int(NFV)) # print "PV10 = $%s" %"{:,}".format(int(PV10)) # print "IRR = %s" %round(ROR*100,2) + '%' # print "Cash payout occurs in year %s" %cashPayout # print "Cash on cash return in year 1 = %s" %int(cashOnCashYr1)+'%' # print "Monthly cashflow in year 1 = $%s" % int(moCashflowYr1) #return NFV, PV10, ROR, capRateYr1, cashPayout, cashOnCashYr1, moCashflowYr1, cashToClose, cashToOperate return metricsDict
def test_irr(self): v = [-150000, 15000, 25000, 35000, 45000, 60000] assert_almost_equal(np.irr(v), 0.0524, 2) v = [-100, 0, 0, 74] assert_almost_equal(np.irr(v), -0.0955, 2) v = [-100, 39, 59, 55, 20] assert_almost_equal(np.irr(v), 0.28095, 2) v = [-100, 100, 0, -7] assert_almost_equal(np.irr(v), -0.0833, 2) v = [-100, 100, 0, 7] assert_almost_equal(np.irr(v), 0.06206, 2) v = [-5, 10.5, 1, -8, 1] assert_almost_equal(np.irr(v), 0.0886, 2)
def test_irr(self): v = [-150000, 15000, 25000, 35000, 45000, 60000] assert_almost_equal(np.irr(v), 0.0524, 2) v = [-100, 0, 0, 74] assert_almost_equal(np.irr(v), -0.0955, 2) v = [-100, 39, 59, 55, 20] assert_almost_equal(np.irr(v), 0.28095, 2) v = [-100, 100, 0, -7] assert_almost_equal(np.irr(v), -0.0833, 2) v = [-100, 100, 0, 7] assert_almost_equal(np.irr(v), 0.06206, 2) v = [-5, 10.5, 1, -8, 1] assert_almost_equal(np.irr(v), 0.0886, 2) # Test that if there is no solution then np.irr returns nan # Fixes gh-6744 v = [-1, -2, -3] assert_equal(np.irr(v), np.nan)
def irr(values, guess = None): """ Function to calculate the internal rate of return (IRR) using payments and periodic dates. It resembles the excel function IRR(). Excel reference: https://support.office.com/en-us/article/IRR-function-64925eaa-9988-495b-b290-3ad0c163c1bc :param values: the payments of which at least one has to be negative. :param guess: an initial guess which is required by Excel but isn't used by this function. :return: a float being the IRR. """ if isinstance(values, Range): values = values.values if guess is not None and guess != 0: raise ValueError('guess value for excellib.irr() is %s and not 0' % guess) else: try: return np.irr(values) except Exception as e: return ExcelError('#NUM!', e)
def mwrr(self, start, end, annualize=False): """ calculate money weighted rate of return portfolio value right before start is considered initial cost and portfolio is assumed to sell at the end to calculate final value """ drange = pd.bdate_range(start+1, end, offset='B') values = np.zeros(len(drange)+1) values[0] = -self.position(start).total_value() for i, d in enumerate(drange): values[i+1] = self.cash_flow(d) values[-1] += float(self.position(end).total_value()) values = np.trim_zeros(values, 'f') # remove zeros from the front which represents days without any holding or transactions # this will not impact np.irr but changes the data length when calculate total mwrr irr = np.irr(values) if annualize: irr = np.power(irr+1, DAYS_IN_A_YEAR) - 1 else: irr = np.power(irr+1, len(values)-1) - 1 return Decimal(irr)
def test_irr(self): v = [-150000, 15000, 25000, 35000, 45000, 60000] assert_almost_equal(np.irr(v), 0.0524, 2)
discountRate = float(inputDict.get("discountRate", 7))/100 outData["oneYearGenerationWh"] = sum(outData["powerOutputAc"]) outData["lifeGenerationDollars"] = [retailCost*(1.0/1000)*outData["oneYearGenerationWh"]*(1.0-(x*degradation)) for x in lifeYears] outData["lifeOmCosts"] = [-1.0*float(inputDict["omCost"]) for x in lifeYears] outData["lifePurchaseCosts"] = [-1.0 * installCost] + [0 for x in lifeYears[1:]] srec = inputDict.get("srecCashFlow", "").split(",") outData["srecCashFlow"] = map(float,srec) + [0 for x in lifeYears[len(srec):]] outData["netCashFlow"] = [x+y+z+a for (x,y,z,a) in zip(outData["lifeGenerationDollars"], outData["lifeOmCosts"], outData["lifePurchaseCosts"], outData["srecCashFlow"])] outData["cumCashFlow"] = map(lambda x:x, _runningSum(outData["netCashFlow"])) outData["ROI"] = roundSig(sum(outData["netCashFlow"]), 3) / (-1*roundSig(sum(outData["lifeOmCosts"]), 3) + -1*roundSig(sum(outData["lifePurchaseCosts"], 3))) outData["NPV"] = roundSig(npv(discountRate, outData["netCashFlow"]), 3) outData["lifeGenerationWh"] = sum(outData["powerOutputAc"])*lifeSpan outData["lifeEnergySales"] = sum(outData["lifeGenerationDollars"]) try: # The IRR function is very bad. outData["IRR"] = roundSig(irr(outData["netCashFlow"]), 3) except: outData["IRR"] = "Undefined" # Monthly aggregation outputs. months = {"Jan":0,"Feb":1,"Mar":2,"Apr":3,"May":4,"Jun":5,"Jul":6,"Aug":7,"Sep":8,"Oct":9,"Nov":10,"Dec":11} totMonNum = lambda x:sum([z for (y,z) in zip(outData["timeStamps"], outData["powerOutputAc"]) if y.startswith(simStartDate[0:4] + "-{0:02d}".format(x+1))]) outData["monthlyGeneration"] = [[a, totMonNum(b)] for (a,b) in sorted(months.items(), key=lambda x:x[1])] # Heatmaped hour+month outputs. hours = range(24) from calendar import monthrange totHourMon = lambda h,m:sum([z for (y,z) in zip(outData["timeStamps"], outData["powerOutputAc"]) if y[5:7]=="{0:02d}".format(m+1) and y[11:13]=="{0:02d}".format(h+1)]) outData["seasonalPerformance"] = [[x,y,totHourMon(x,y) / monthrange(int(simStartDate[:4]), y+1)[1]] for x in hours for y in months.values()] # Stdout/stderr. outData["stdout"] = "Success" outData["stderr"] = "" # Write the output.
from numpy import irr t=int(input()) for i in range(t): n=int(input()) l=list(map(int,input().split())) l[0]=-l[0] print("Case #%d: %.12f" % (i+1,round(irr(l),12)))
def test_irr(self): I = [-29, 20, 30] assert_almost_equal(np.irr(I), 0.418787000165341, 5)
def calculate(): try: city = str(request.form['city']) customer_type = str(request.form['cust_type']) # residentaial-> R, commercial-> C, industrial -> I connection_type = str(request.form['conn_type']) # LT, HT rooftop_area = int(request.form['area']) # sqft # rooftop_type = 0 # 450 monthly_bill = int(request.form['bill']) # Rs. sanction_load = int(request.form['load']) # kVA except: flash('Wrong Information!') return redirect(url_for('calculator')) print(city, customer_type, connection_type, rooftop_area, monthly_bill, sanction_load) # customer_type = 'R' # residentaial-> R, commercial-> C, industrial -> I # connection_type = 'LT' # LT, HT # rooftop_area = 200 # sqft # rooftop_type = 0 # 450 # monthly_bill = 1000 # Rs. # sanction_load = 3 # kVA if (customer_type == 'R') & (connection_type == 'LT'): # Residential and LT total_units = lt2a(monthly_bill) sys_type = 'Grid-tie' elif (customer_type == 'C') & (connection_type == 'LT'): # Commercial & LT total_units = lt3(monthly_bill) sys_type = 'Grid-tie' elif (customer_type == 'I') & (connection_type == 'LT'): # Industrial & LT total_units = lt3(monthly_bill) sys_type = 'Grid-interactive' elif (customer_type == 'R') & (connection_type == 'HT'): # Residential and HT total_units = ht4(monthly_bill) sys_type = 'Grid-tie' elif (customer_type == 'C') & (connection_type == 'HT'): # Commercial & HT total_units = ht2b(monthly_bill) sys_type = 'Grid-interactive' elif (customer_type == 'I') & (connection_type == 'HT'): # Industrial & HT total_units = ht2a(monthly_bill) sys_type = 'Grid-interactive' elif (customer_type == 'R') & (connection_type == 0): # Residential and - total_units = lt2a(monthly_bill) sys_type = 'Grid-tie' elif (customer_type == 'C') & (connection_type == 0): # Commercial & - total_units = lt3(monthly_bill) sys_type = 'Grid-tie' elif (customer_type == 'I') & (connection_type == 0): # Industrial & - total_units = ht2a(monthly_bill) sys_type = 'Grid-interactive' else: flash('Wrong Information!') return redirect(url_for('index')) size_of_rooftop_sys = ((total_units / 5) / 30) if size_of_rooftop_sys <= (rooftop_area / 100): system_size = math.ceil( size_of_rooftop_sys * 10) / 10.0 # math.ceil(num * 100) / 100.0 returns roundup to a float # print(1, system_size) else: system_size = math.ceil((rooftop_area / 100) * 10) / 10.0 # print(2) system_size = min(sanction_load, system_size) total_cost = system_size * 90000 units_prod_year = system_size * 5 * 300 # produced from solar units_used_year = total_units * 12 # from grid net_units_consumed = units_used_year - units_prod_year if net_units_consumed > 0: net_yearly_bill = net_units_consumed * 5.25 else: net_yearly_bill = net_units_consumed * 9.56 fst_year_bill = 12 * monthly_bill yearly_bills = [0, fst_year_bill] savings = [-total_cost, round(fst_year_bill - net_yearly_bill)] # round(fst_year_bill - net_yearly_bill) for i in range(2, 14): # print(i) yearly_bills.append(round(yearly_bills[i - 1] * 1.025)) savings.append(round(yearly_bills[i] - net_yearly_bill)) sum1 = 0 for i in range(1, len(savings)): # print(i) if sum1 > total_cost: i -= 1 break else: sum1 += savings[i] sum2 = sum1 sum1 = sum1 - savings[i] i = i - 1 months = (total_cost - sum1) / savings[i + 1] roi = math.ceil((i + months) * 10) / 10.0 print(sum1, sum2, i, roi) savings_irr = [] for j in range(i + 2): savings_irr.append(savings[j]) print(yearly_bills) print(savings) print(savings_irr) average_savings = 0 for i in range(1, 11): # print(i) average_savings += savings[i] average_savings = average_savings / 10 irr = round((numpy.irr(savings_irr) * 100.0), 2) print(irr) temp = { 'total_units': total_units, 'sys_type': sys_type, 'size_of_rooftop_sys': size_of_rooftop_sys, 'system_size': system_size, 'total_cost': total_cost, 'units_prod_year': units_prod_year, 'units_used_year': units_used_year, 'net_units_consumed': net_units_consumed, 'irr': irr, 'roi': roi, 'average_savings': average_savings } res = { 'system_size': system_size, 'sys_type': sys_type, 'total_cost': total_cost, 'irr': irr, 'roi': roi, 'average_savings': average_savings } result = resultClass(system_size, sys_type, total_cost, irr, roi, average_savings) return render_template('results.html', result=result)
def run(modelDir, inputDict): ''' Run the model in its directory. ''' # Check whether model exist or not if not os.path.isdir(modelDir): os.makedirs(modelDir) inputDict["created"] = str(dt.datetime.now()) # MAYBEFIX: remove this data dump. Check showModel in web.py and renderTemplate() with open(pJoin(modelDir, "allInputData.json"),"w") as inputFile: json.dump(inputDict, inputFile, indent = 4) # Copy spcific climate data into model directory shutil.copy(pJoin(__metaModel__._omfDir, "data", "Climate", inputDict["climateName"] + ".tmy2"), pJoin(modelDir, "climate.tmy2")) # Ready to run startTime = dt.datetime.now() # Set up SAM data structures. ssc = nrelsam.SSCAPI() dat = ssc.ssc_data_create() # Required user inputs. ssc.ssc_data_set_string(dat, "file_name", modelDir + "/climate.tmy2") ssc.ssc_data_set_number(dat, "system_size", float(inputDict.get("systemSize", 100))) derate = float(inputDict.get("pvModuleDerate", 0.995)) \ * float(inputDict.get("mismatch", 0.995)) \ * float(inputDict.get("diodes", 0.995)) \ * float(inputDict.get("dcWiring", 0.995)) \ * float(inputDict.get("acWiring", 0.995)) \ * float(inputDict.get("soiling", 0.995)) \ * float(inputDict.get("shading", 0.995)) \ * float(inputDict.get("sysAvail", 0.995)) \ * float(inputDict.get("age", 0.995)) ssc.ssc_data_set_number(dat, "derate", float(inputDict.get("derate", derate))) ssc.ssc_data_set_number(dat, "track_mode", float(inputDict.get("trackingMode", 0))) ssc.ssc_data_set_number(dat, "azimuth", float(inputDict.get("azimuth", 180))) # Advanced inputs with defaults. ssc.ssc_data_set_number(dat, "rotlim", float(inputDict.get("rotlim", 45))) # ssc.ssc_data_set_number(dat, "t_noct", float(inputDict.get("t_noct", 45))) # ssc.ssc_data_set_number(dat, "t_ref", float(inputDict.get("t_ref", 25))) ssc.ssc_data_set_number(dat, "gamma", float(inputDict.get("gamma", 0.5))) # ssc.ssc_data_set_number(dat, "inv_eff", float(inputDict.get("inv_eff", 0.92))) # ssc.ssc_data_set_number(dat, "fd", float(inputDict.get("fd", 1))) # ssc.ssc_data_set_number(dat, "i_ref", float(inputDict.get("i_ref", 1000))) # ssc.ssc_data_set_number(dat, "poa_cutin", float(inputDict.get("poa_cutin", 0))) ssc.ssc_data_set_number(dat, "w_stow", float(inputDict.get("w_stow", 0))) # Complicated optional inputs. ssc.ssc_data_set_number(dat, "tilt_eq_lat", 1) # ssc.ssc_data_set_array(dat, 'shading_hourly', ...) # Hourly beam shading factors # ssc.ssc_data_set_matrix(dat, 'shading_mxh', ...) # Month x Hour beam shading factors # ssc.ssc_data_set_matrix(dat, ' shading_azal', ...) # Azimuth x altitude beam shading factors # ssc.ssc_data_set_number(dat, 'shading_diff', ...) # Diffuse shading factor # ssc.ssc_data_set_number(dat, 'enable_user_poa', ...) # Enable user-defined POA irradiance input = 0 or 1 # ssc.ssc_data_set_array(dat, 'user_poa', ...) # User-defined POA irradiance in W/m2 # ssc.ssc_data_set_number(dat, 'tilt', 999) # Run PV system simulation. mod = ssc.ssc_module_create("pvwattsv1") ssc.ssc_module_exec(mod, dat) # Setting options for start time. simLengthUnits = inputDict.get("simLengthUnits","hours") simStartDate = inputDict.get("simStartDate", "2014-01-01") # Set the timezone to be UTC, it won't affect calculation and display, relative offset handled in pvWatts.html startDateTime = simStartDate + " 00:00:00 UTC" # Set aggregation function constants. agg = lambda x,y:_aggData(x,y,inputDict["simStartDate"], int(inputDict["simLength"]), inputDict.get("simLengthUnits","hours"), ssc, dat) avg = lambda x:sum(x)/len(x) # Timestamp output. outData = {} outData["timeStamps"] = [dt.datetime.strftime( dt.datetime.strptime(startDateTime[0:19],"%Y-%m-%d %H:%M:%S") + dt.timedelta(**{simLengthUnits:x}),"%Y-%m-%d %H:%M:%S") + " UTC" for x in range(int(inputDict.get("simLength", 8760)))] # Geodata output. outData["city"] = ssc.ssc_data_get_string(dat, "city") outData["state"] = ssc.ssc_data_get_string(dat, "state") outData["lat"] = ssc.ssc_data_get_number(dat, "lat") outData["lon"] = ssc.ssc_data_get_number(dat, "lon") outData["elev"] = ssc.ssc_data_get_number(dat, "elev") # Weather output. outData["climate"] = {} outData["climate"]["Direct Irradiance (W/m^2)"] = agg("dn", avg) outData["climate"]["Difuse Irradiance (W/m^2)"] = agg("df", avg) outData["climate"]["Ambient Temperature (F)"] = agg("tamb", avg) outData["climate"]["Cell Temperature (F)"] = agg("tcell", avg) outData["climate"]["Wind Speed (m/s)"] = agg("wspd", avg) # Power generation. outData["powerOutputAc"] = [x for x in agg("ac", avg)] # Cashflow outputs. lifeSpan = int(inputDict.get("lifeSpan",30)) lifeYears = range(1, 1 + lifeSpan) retailCost = float(inputDict.get("retailCost",0.0)) degradation = float(inputDict.get("degradation",0.5))/100 installCost = float(inputDict.get("installCost",0.0)) discountRate = float(inputDict.get("discountRate", 7))/100 outData["oneYearGenerationWh"] = sum(outData["powerOutputAc"]) outData["lifeGenerationDollars"] = [roundSig(retailCost*(1.0/1000.0)*outData["oneYearGenerationWh"]*(1.0-(x*degradation)),2) for x in lifeYears] outData["lifeOmCosts"] = [-1.0*float(inputDict["omCost"]) for x in lifeYears] outData["lifePurchaseCosts"] = [-1.0 * installCost] + [0 for x in lifeYears[1:]] srec = inputDict.get("srecCashFlow", "").split(",") outData["srecCashFlow"] = map(float,srec) + [0 for x in lifeYears[len(srec):]] outData["netCashFlow"] = [roundSig(x+y+z+a,2) for (x,y,z,a) in zip(outData["lifeGenerationDollars"], outData["lifeOmCosts"], outData["lifePurchaseCosts"], outData["srecCashFlow"])] outData["cumCashFlow"] = map(lambda x:roundSig(x,2), _runningSum(outData["netCashFlow"])) outData["ROI"] = roundSig(sum(outData["netCashFlow"]), 2) outData["NPV"] = roundSig(npv(discountRate, outData["netCashFlow"]), 2) outData["IRR"] = roundSig(irr(outData["netCashFlow"]), 2) # Monthly aggregation outputs. months = {"Jan":0,"Feb":1,"Mar":2,"Apr":3,"May":4,"Jun":5,"Jul":6,"Aug":7,"Sep":8,"Oct":9,"Nov":10,"Dec":11} totMonNum = lambda x:sum([z for (y,z) in zip(outData["timeStamps"], outData["powerOutputAc"]) if y.startswith(simStartDate[0:4] + "-{0:02d}".format(x+1))]) outData["monthlyGeneration"] = [[a, roundSig(totMonNum(b),2)] for (a,b) in sorted(months.items(), key=lambda x:x[1])] # Heatmaped hour+month outputs. hours = range(24) from calendar import monthrange totHourMon = lambda h,m:sum([z for (y,z) in zip(outData["timeStamps"], outData["powerOutputAc"]) if y[5:7]=="{0:02d}".format(m+1) and y[11:13]=="{0:02d}".format(h+1)]) outData["seasonalPerformance"] = [[x,y,totHourMon(x,y) / monthrange(int(simStartDate[:4]), y+1)[1]] for x in hours for y in months.values()] # Stdout/stderr. outData["stdout"] = "Success" outData["stderr"] = "" # Write the output. with open(pJoin(modelDir,"allOutputData.json"),"w") as outFile: json.dump(outData, outFile, indent=4) # Update the runTime in the input file. endTime = dt.datetime.now() inputDict["runTime"] = str(dt.timedelta(seconds=int((endTime - startTime).total_seconds()))) with open(pJoin(modelDir,"allInputData.json"),"w") as inFile: json.dump(inputDict, inFile, indent=4) _dumpDataToExcel(modelDir)
def taxEquityFlip(PPARateSixYearsTE, discRate, totalCost, allYearGenerationMWh, distAdderDirect, loanYears, firstYearLandLeaseCosts, firstYearOPMainCosts, firstYearInsuranceCosts, numberPanels): # Output Tax Equity Flip [C] coopInvestmentTaxEquity = -totalCost * (1 - 0.53) # Output Tax Equity Flip [D] financeCostCashTaxEquity = 0 # Output Tax Equity Flip [E] cashToSPEOForPPATE = [] # Output Tax Equity Flip [F] derivedCostEnergyTE = 0 # Output Tax Equity Flip [G] OMInsuranceETCTE = [] # Output Tax Equity Flip [H] cashFromSPEToBlockerTE = [] # Output Tax Equity Flip [I] cashFromBlockerTE = 0 # Output Tax Equity Flip [J] distAdderTaxEquity = distAdderDirect # Output Tax Equity Flip [K] netCoopPaymentsTaxEquity = [] # Output Tax Equity Flip [L] costToCustomerTaxEquity = [] # Output Tax Equity Flip [L64] NPVLoanTaxEquity = 0 # Output Tax Equity Flip [F72] Rate_Levelized_Equity = 0 # Tax Equity Flip Formulas # Output Tax Equity Flip [D] # TEI Calcs [E] financeCostOfCashTE = 0 coopFinanceRateTE = 2.7 / 100 if (coopFinanceRateTE == 0): financeCostOfCashTE = 0 else: payment = pmt( coopFinanceRateTE, loanYears, -coopInvestmentTaxEquity) financeCostCashTaxEquity = payment # Output Tax Equity Flip [E] SPERevenueTE = [] for i in range(1, len(allYearGenerationMWh) + 1): SPERevenueTE.append( PPARateSixYearsTE * allYearGenerationMWh[i]) if ((i >= 1) and (i <= 6)): cashToSPEOForPPATE.append(-SPERevenueTE[i - 1]) else: cashToSPEOForPPATE.append(0) # Output Tax Equity Flip [F] derivedCostEnergyTE = cashToSPEOForPPATE[ 0] / allYearGenerationMWh[1] # Output Tax Equity Flip [G] # TEI Calcs [F] [U] [V] landLeaseTE = [] OMTE = [] insuranceTE = [] for i in range(1, len(allYearGenerationMWh) + 1): landLeaseTE.append( firstYearLandLeaseCosts * math.pow((1 + .01), (i - 1))) OMTE.append(-firstYearOPMainCosts * math.pow((1 + .01), (i - 1))) insuranceTE.append(- firstYearInsuranceCosts * math.pow((1 + .025), (i - 1))) if (i < 7): OMInsuranceETCTE.append(float(landLeaseTE[i - 1])) else: OMInsuranceETCTE.append( float(OMTE[i - 1]) + float(insuranceTE[i - 1]) + float(landLeaseTE[i - 1])) # Output Tax Equity Flip [H] # TEI Calcs [T] SPEMgmtFeeTE = [] EBITDATE = [] EBITDATEREDUCED = [] managementFee = 10000 for i in range(1, len(SPERevenueTE) + 1): SPEMgmtFeeTE.append(-managementFee * math.pow((1 + .01), (i - 1))) EBITDATE.append(float(SPERevenueTE[ i - 1]) + float(OMTE[i - 1]) + float(insuranceTE[i - 1]) + float(SPEMgmtFeeTE[i - 1])) if (i <= 6): cashFromSPEToBlockerTE.append(float(EBITDATE[i - 1]) * .01) else: cashFromSPEToBlockerTE.append(0) EBITDATEREDUCED.append(EBITDATE[i - 1]) # Output Tax Equity Flip [I] # TEI Calcs [Y21] cashRevenueTE = -totalCost * (1 - 0.53) buyoutAmountTE = 0 for i in range(1, len(EBITDATEREDUCED) + 1): buyoutAmountTE = buyoutAmountTE + \ EBITDATEREDUCED[i - 1] / (math.pow(1 + 0.12, i)) buyoutAmountTE = buyoutAmountTE * 0.05 cashFromBlockerTE = - (buyoutAmountTE) + 0.0725 * cashRevenueTE # Output Tax Equity Flip [K] [L] for i in range(1, len(allYearGenerationMWh) + 1): if (i == 6): netCoopPaymentsTaxEquity.append(financeCostCashTaxEquity + cashToSPEOForPPATE[ i - 1] + cashFromSPEToBlockerTE[i - 1] + OMInsuranceETCTE[i - 1] + cashFromBlockerTE) else: netCoopPaymentsTaxEquity.append(financeCostCashTaxEquity + cashFromSPEToBlockerTE[ i - 1] + cashToSPEOForPPATE[i - 1] + OMInsuranceETCTE[i - 1]) costToCustomerTaxEquity.append( netCoopPaymentsTaxEquity[i - 1] - distAdderTaxEquity[i - 1]) # Output Tax Equity Flip [L37] NPVLoanTaxEquity = npv( float(inputDict.get("discRate", 0)) / 100, [0, 0] + costToCustomerTaxEquity) # Output - Tax Equity [F42] Rate_Levelized_TaxEquity = - \ NPVLoanTaxEquity / NPVallYearGenerationMWh # TEI Calcs - Achieved Return [AW 21] #[AK] MACRDepreciation = [] MACRDepreciation.append(-0.99 * 0.2 * (totalCost - totalCost * 0.5 * 0.9822 * 0.3)) MACRDepreciation.append(-0.99 * 0.32 * (totalCost - totalCost * 0.5 * 0.9822 * 0.3)) MACRDepreciation.append(-0.99 * 0.192 * (totalCost - totalCost * 0.5 * 0.9822 * 0.3)) MACRDepreciation.append(-0.99 * 0.1152 * (totalCost - totalCost * 0.5 * 0.9822 * 0.3)) MACRDepreciation.append(-0.99 * 0.1152 * (totalCost - totalCost * 0.5 * 0.9822 * 0.3)) MACRDepreciation.append(-0.99 * 0.0576 * (totalCost - totalCost * 0.5 * 0.9822 * 0.3)) #[AI] [AL] [AN] cashRevenueTEI = [] # [AI] slDepreciation = [] # [AL] totalDistributions = [] # [AN] cashRevenueTEI.append(-totalCost * 0.53) for i in range(1, 7): cashRevenueTEI.append(EBITDATE[i - 1] * 0.99) slDepreciation.append(totalCost / 25) totalDistributions.append(-cashRevenueTEI[i]) #[AJ] ITC = totalCost * 0.9822 * 0.3 * 0.99 #[AM] taxableIncLoss = [0] taxableIncLoss.append(cashRevenueTEI[1] + MACRDepreciation[0]) #[AO] capitalAcct = [] capitalAcct.append(totalCost * 0.53) condition = capitalAcct[0] - 0.5 * ITC + \ taxableIncLoss[1] + totalDistributions[0] if condition > 0: capitalAcct.append(condition) else: capitalAcct.append(0) #[AQ] ratioTE = [0] #[AP] reallocatedIncLoss = [] #AO-1 + AN + AI + AK + AJ for i in range(0, 5): reallocatedIncLoss.append(capitalAcct[ i + 1] + totalDistributions[i + 1] + MACRDepreciation[i + 1] + cashRevenueTEI[i + 2]) ratioTE.append( reallocatedIncLoss[i] / (cashRevenueTEI[i + 2] + MACRDepreciation[i + 1])) taxableIncLoss.append(cashRevenueTEI[i + 2] + MACRDepreciation[i + 1] - ratioTE[ i + 1] * (MACRDepreciation[i + 1] - totalDistributions[i + 1])) condition = capitalAcct[ i + 1] + taxableIncLoss[i + 2] + totalDistributions[i + 1] if condition > 0: capitalAcct.append(condition) else: capitalAcct.append(0) #[AR] taxesBenefitLiab = [0] for i in range(1, 7): taxesBenefitLiab.append(-taxableIncLoss[i] * 0.35) #[AS] [AT] buyoutAmount = 0 taxFromBuyout = 0 for i in range(0, len(EBITDATEREDUCED)): buyoutAmount = buyoutAmount + .05 * \ EBITDATEREDUCED[i] / (math.pow(1.12, (i + 1))) taxFromBuyout = -buyoutAmount * 0.35 #[AU] [AV] totalCashTax = [] cumulativeCashTax = [0] for i in range(0, 7): if i == 1: totalCashTax.append( cashRevenueTEI[i] + ITC + taxesBenefitLiab[i] + 0 + 0) cumulativeCashTax.append( cumulativeCashTax[i] + totalCashTax[i]) elif i == 6: totalCashTax.append( cashRevenueTEI[i] + 0 + taxesBenefitLiab[i] + buyoutAmount + taxFromBuyout) cumulativeCashTax.append( cumulativeCashTax[i] + totalCashTax[i] + buyoutAmount + taxFromBuyout) else: totalCashTax.append( cashRevenueTEI[i] + 0 + taxesBenefitLiab[i] + 0 + 0) cumulativeCashTax.append( cumulativeCashTax[i] + totalCashTax[i]) #[AW21] if (cumulativeCashTax[7] > 0): cumulativeIRR = round(irr(totalCashTax), 4) else: cumulativeIRR = 0 # Deleteme: Variable Dump for debugging # variableDump = {} # variableDump["TaxEquity"] = {} # variableDump["TaxEquity"]["coopInvestmentTaxEquity"] = coopInvestmentTaxEquity # variableDump["TaxEquity"]["financeCostCashTaxEquity"] = financeCostCashTaxEquity # variableDump["TaxEquity"]["cashToSPEOForPPATE"] = cashToSPEOForPPATE # variableDump["TaxEquity"]["derivedCostEnergyTE"] = derivedCostEnergyTE # variableDump["TaxEquity"]["OMInsuranceETCTE"] = OMInsuranceETCTE # variableDump["TaxEquity"]["cashFromSPEToBlockerTE"] = cashFromSPEToBlockerTE # variableDump["TaxEquity"]["cashFromBlockerTE"] = cashFromBlockerTE # variableDump["TaxEquity"]["distAdderTaxEquity"] = distAdderTaxEquity # variableDump["TaxEquity"]["netCoopPaymentsTaxEquity"] = netCoopPaymentsTaxEquity # variableDump["TaxEquity"]["NPVLoanTaxEquity"] = NPVLoanTaxEquity return cumulativeIRR, Rate_Levelized_TaxEquity, NPVLoanTaxEquity
econ['expenses_variable']=(config['expenses']['variable']['oil']*econ['gross_sales_oil']+config['expenses']['variable']['gas']*econ['gross_sales_gas']+config['expenses']['variable']['ngl']*econ['gross_sales_ngl'])*config['working_interest'] econ['expenses_total']=(econ['expenses_variable']+config['expenses']['fixed'])*config['working_interest'] econ['gross_revenue_after_sevtax_and_expenses']=econ['gross_sales_total']-econ['severance_total']-econ['expenses_total'] econ['ad_valorum_tax']=econ['gross_revenue_after_sevtax_and_expenses']*config['taxes']['ad_valorum'] econ['gross_revenue_after_sevtax_and_expenses_and_advaltax']=econ['gross_revenue_after_sevtax_and_expenses']-econ['ad_valorum_tax'] econ['capital']=0.0 econ.ix[0,'capital']=(config['capital']['idc']+config['capital']['icc']+config['capital']['land'])*config['working_interest'] econ['gross_cash_flow']=econ['gross_revenue_after_sevtax_and_expenses_and_advaltax']-econ['capital'] econ['net_nondiscounted_cash_flow']=(econ['gross_revenue_after_sevtax_and_expenses_and_advaltax']*config['net_revenue_interest'])-econ['capital'] econ['cum_net_nondiscounted_cashflow']=econ['net_nondiscounted_cash_flow'].cumsum() econ['net_discounted_cashflow']=econ['net_nondiscounted_cash_flow']/(1+annual_to_monthly_rate(config['discount_rate_annual']))**econ['standard_time'] econ['cum_net_discounted_cashflow']=econ['net_discounted_cashflow'].cumsum() econ.to_excel(r'C:\Users\WaltN\Desktop\GitHub\curvey\output\econ.xlsx') npv=round(np.npv(annual_to_monthly_rate(config['discount_rate_annual']),econ['net_nondiscounted_cash_flow']), 2) irr=round(np.irr(econ['net_discounted_cashflow']), 2) print(''' NPV: ${} IRR: {} '''.format(npv, irr))
import numpy as np cashflows = [-45.45, 50] irr = round(np.irr(cashflows), 2) print(irr)
def work(modelDir, inputDict): ''' Run the model in its directory. ''' # Copy spcific climate data into model directory inputDict["climateName"] = zipCodeToClimateName(inputDict["zipCode"]) shutil.copy(pJoin(__neoMetaModel__._omfDir, "data", "Climate", inputDict["climateName"] + ".tmy2"), pJoin(modelDir, "climate.tmy2")) # Set up SAM data structures. ssc = nrelsam2013.SSCAPI() dat = ssc.ssc_data_create() # Required user inputs. ssc.ssc_data_set_string(dat, "file_name", modelDir + "/climate.tmy2") ssc.ssc_data_set_number(dat, "system_size", float(inputDict.get("systemSize", 100))) derate = float(inputDict.get("pvModuleDerate", 99.5))/100 \ * float(inputDict.get("mismatch", 99.5))/100 \ * float(inputDict.get("diodes", 99.5))/100 \ * float(inputDict.get("dcWiring", 99.5))/100 \ * float(inputDict.get("acWiring", 99.5))/100 \ * float(inputDict.get("soiling", 99.5))/100 \ * float(inputDict.get("shading", 99.5))/100 \ * float(inputDict.get("sysAvail", 99.5))/100 \ * float(inputDict.get("age", 99.5))/100 \ * float(inputDict.get("inverterEfficiency", 92))/100 ssc.ssc_data_set_number(dat, "derate", derate) # TODO: Should we move inverter efficiency to 'inv_eff' below (as done in PVWatts?) # Doesn't seem to affect output very much # ssc.ssc_data_set_number(dat, "inv_eff", float(inputDict.get("inverterEfficiency", 92))/100) ssc.ssc_data_set_number(dat, "track_mode", float(inputDict.get("trackingMode", 0))) ssc.ssc_data_set_number(dat, "azimuth", float(inputDict.get("azimuth", 180))) # Advanced inputs with defaults. ssc.ssc_data_set_number(dat, "rotlim", float(inputDict.get("rotlim", 45))) ssc.ssc_data_set_number(dat, "gamma", float(inputDict.get("gamma", 0.5))/100) # Complicated optional inputs. if (inputDict.get("tilt",0) == "-"): tilt_eq_lat = 1.0 manualTilt = 0.0 else: tilt_eq_lat = 0.0 manualTilt = float(inputDict.get("tilt",0)) ssc.ssc_data_set_number(dat, "tilt", manualTilt) ssc.ssc_data_set_number(dat, "tilt_eq_lat", tilt_eq_lat) # Run PV system simulation. mod = ssc.ssc_module_create("pvwattsv1") ssc.ssc_module_exec(mod, dat) # Setting options for start time. simLengthUnits = inputDict.get("simLengthUnits","hours") simStartDate = inputDict.get("simStartDate", "2014-01-01") # Set the timezone to be UTC, it won't affect calculation and display, relative offset handled in pvWatts.html startDateTime = simStartDate + " 00:00:00 UTC" # Timestamp output. outData = {} outData["timeStamps"] = [dt.datetime.strftime( dt.datetime.strptime(startDateTime[0:19],"%Y-%m-%d %H:%M:%S") + dt.timedelta(**{simLengthUnits:x}),"%Y-%m-%d %H:%M:%S") + " UTC" for x in range(int(inputDict.get("simLength", 8760)))] # Geodata output. outData["city"] = ssc.ssc_data_get_string(dat, "city") outData["state"] = ssc.ssc_data_get_string(dat, "state") outData["lat"] = ssc.ssc_data_get_number(dat, "lat") outData["lon"] = ssc.ssc_data_get_number(dat, "lon") outData["elev"] = ssc.ssc_data_get_number(dat, "elev") # Weather output. outData["climate"] = {} outData["climate"]["Global Horizontal Radiation (W/m^2)"] = ssc.ssc_data_get_array(dat, "gh") outData["climate"]["Plane of Array Irradiance (W/m^2)"] = ssc.ssc_data_get_array(dat, "poa") outData["climate"]["Ambient Temperature (F)"] = ssc.ssc_data_get_array(dat, "tamb") outData["climate"]["Cell Temperature (F)"] = ssc.ssc_data_get_array(dat, "tcell") outData["climate"]["Wind Speed (m/s)"] = ssc.ssc_data_get_array(dat, "wspd") # Power generation and clipping. outData["powerOutputAc"] = ssc.ssc_data_get_array(dat, "ac") invSizeWatts = float(inputDict.get("inverterSize", 0)) * 1000 outData["InvClipped"] = [x if x < invSizeWatts else invSizeWatts for x in outData["powerOutputAc"]] try: outData["percentClipped"] = 100 * (1.0 - sum(outData["InvClipped"]) / sum(outData["powerOutputAc"])) except ZeroDivisionError: outData["percentClipped"] = 0.0 # Cashflow outputs. lifeSpan = int(inputDict.get("lifeSpan",30)) lifeYears = range(1, 1 + lifeSpan) retailCost = float(inputDict.get("retailCost",0.0)) degradation = float(inputDict.get("degradation",0.5))/100 installCost = float(inputDict.get("installCost",0.0)) discountRate = float(inputDict.get("discountRate", 7))/100 outData["oneYearGenerationWh"] = sum(outData["powerOutputAc"]) outData["lifeGenerationDollars"] = [retailCost*(1.0/1000)*outData["oneYearGenerationWh"]*(1.0-(x*degradation)) for x in lifeYears] outData["lifeOmCosts"] = [-1.0*float(inputDict["omCost"]) for x in lifeYears] outData["lifePurchaseCosts"] = [-1.0 * installCost] + [0 for x in lifeYears[1:]] srec = inputDict.get("srecCashFlow", "").split(",") outData["srecCashFlow"] = map(float,srec) + [0 for x in lifeYears[len(srec):]] outData["netCashFlow"] = [x+y+z+a for (x,y,z,a) in zip(outData["lifeGenerationDollars"], outData["lifeOmCosts"], outData["lifePurchaseCosts"], outData["srecCashFlow"])] outData["cumCashFlow"] = map(lambda x:x, _runningSum(outData["netCashFlow"])) outData["ROI"] = roundSig(sum(outData["netCashFlow"]), 3) / (-1*roundSig(sum(outData["lifeOmCosts"]), 3) + -1*roundSig(sum(outData["lifePurchaseCosts"], 3))) outData["NPV"] = roundSig(npv(discountRate, outData["netCashFlow"]), 3) outData["lifeGenerationWh"] = sum(outData["powerOutputAc"])*lifeSpan outData["lifeEnergySales"] = sum(outData["lifeGenerationDollars"]) try: # The IRR function is very bad. outData["IRR"] = roundSig(irr(outData["netCashFlow"]), 3) except: outData["IRR"] = "Undefined" # Monthly aggregation outputs. months = {"Jan":0,"Feb":1,"Mar":2,"Apr":3,"May":4,"Jun":5,"Jul":6,"Aug":7,"Sep":8,"Oct":9,"Nov":10,"Dec":11} totMonNum = lambda x:sum([z for (y,z) in zip(outData["timeStamps"], outData["powerOutputAc"]) if y.startswith(simStartDate[0:4] + "-{0:02d}".format(x+1))]) outData["monthlyGeneration"] = [[a, totMonNum(b)] for (a,b) in sorted(months.items(), key=lambda x:x[1])] # Heatmaped hour+month outputs. hours = range(24) from calendar import monthrange totHourMon = lambda h,m:sum([z for (y,z) in zip(outData["timeStamps"], outData["powerOutputAc"]) if y[5:7]=="{0:02d}".format(m+1) and y[11:13]=="{0:02d}".format(h+1)]) outData["seasonalPerformance"] = [[x,y,totHourMon(x,y) / monthrange(int(simStartDate[:4]), y+1)[1]] for x in hours for y in months.values()] # Stdout/stderr. outData["stdout"] = "Success" outData["stderr"] = "" return outData
def irr(values): return np.irr(values)
#If net_cash_flow <0, we lost money. For taxes we made $0, cannot deduct losses. So add this to money spent on house if net_cash_flow < 0: total_money_spent_on_house+=abs(net_cash_flow) ###### At the end of n years calculate net earning and ROI ###### print "Selling House Numbers" print "Appreciated House Value after " + str(analysis_for_n_years) + " years: " + str(appreciated_house_value) earning_from_selling_house = (1-selling_costs)*appreciated_house_value - loan_principal_balance gain_from_selling_house_after_tax = 0.85*earning_from_selling_house - 0.25*total_depreciation_claimed total_earnings_after_n_years= gain_from_selling_house_after_tax + net_earnings_over_analysis_years_from_rent_after_tax roi = (total_earnings_after_n_years - total_money_spent_on_house)*100/(total_money_spent_on_house*analysis_for_n_years) ########## IRR ################################# net_cash_flow_arr.append(gain_from_selling_house_after_tax) final_irr = numpy.irr(net_cash_flow_arr)*100 print "After Tax IRR: " + str(final_irr) print "Earnings after " + str(analysis_for_n_years) + " years -> " + "Total: " + str(total_earnings_after_n_years) + \ ", From yearly rent - expenses: " + str(net_earnings_over_analysis_years_from_rent_after_tax) + ", Selling house: " + str(gain_from_selling_house_after_tax) print "Total Money spent on house: " + str(total_money_spent_on_house) print "Simple ROI per year (after tax): " + str(roi)
def do_proforma(proposal, proposal_component): p = proposal c = proposal_component max_periods = max_periods_of_sale + asscalar(p['sales_start_period']) revenues = zeros(max_periods) costs = zeros(max_periods) #cash_flow = zeros(max_periods) construction_loan_balance = p['construction_cost'] * construction_loan_size perm_loan_size = 0 perm_loan_interest_payment = 0 perm_loan_repayment = 0 perm_loan_proceeds = 0.0 full_rent_periods = 0 sold_for_rent = 0 component_sales_revenue = c['sales_revenue'].copy() component_rent_revenue = c['rent_revenue_per_period'].copy() component_leases_revenue = c['leases_revenue_per_period'].copy() construction_periods = p['sales_start_period'] - p['construction_start_period'] for period in arange(max_periods): if period == 1: land_equity = p['land_cost'] costs[period] += land_equity elif component_rent_revenue.sum() >= c['rent_revenue'].sum() and \ component_leases_revenue.sum() >= c['leases_revenue'].sum(): full_rent_periods += 1 if period < p['sales_start_period']: #revenues public_contribution = 0 if p['public_contribution'] == 0 \ else p['public_contribution'] / \ float(construction_periods) sales_revenue = 0 rent_revenue = 0 leases_revenue = 0 revenues[period] += public_contribution #costs operating_cost = 0 vacancy = 0 tax = p['property_tax'] * p['land_cost'] construction_equity = p['construction_cost'] * (1 - construction_loan_size) \ / (p['sales_start_period'] - 1) construction_loan_interest_payment = construction_loan_balance * construction_loan_rate construction_loan_repayment = revenues[period] \ if construction_loan_balance > revenues[period] \ else construction_loan_balance costs[period] += tax + construction_equity + \ construction_loan_interest_payment + construction_loan_repayment construction_loan_balance -= construction_loan_repayment else: if any(component_sales_revenue): # TODO this would not work when we do proforma on multiple proposals at once sales_revenue = np.min(column_stack((c['sales_absorption'], component_sales_revenue)), axis=1 ).sum() component_sales_revenue -= c['sales_absorption'] np.clip(component_sales_revenue, 0, component_sales_revenue.max(), out=component_sales_revenue) else: sales_revenue = 0 if sales_revenue < 0: sales_revenue = 0 # before reaching full occupancy for rent property if not sold_for_rent and any(component_rent_revenue <= c['rent_revenue']): rent_revenue = np.min(column_stack((c['rent_revenue'], component_rent_revenue)), axis=1 ) operating_cost = (rent_revenue * c['operating_cost']).sum() vacancy = (rent_revenue * c['vacancy_rates']).sum() rent_revenue = rent_revenue.sum() component_rent_revenue += c['rent_revenue_per_period'] np.clip(component_rent_revenue, 0, c['rent_revenue'], out=component_rent_revenue) if not sold_for_rent and any(component_leases_revenue <= c['leases_revenue']): leases_revenue = np.min(column_stack((c['leases_revenue'], component_leases_revenue)), axis=1 ) operating_cost += (leases_revenue * c['operating_cost']).sum() vacancy += (leases_revenue * c['vacancy_rates']).sum() leases_revenue = leases_revenue.sum() component_leases_revenue += c['leases_revenue_per_period'] np.clip(component_leases_revenue, 0, c['leases_revenue'], out=component_leases_revenue) #revenues if not sold_for_rent: revenues[period] += sales_revenue + rent_revenue + leases_revenue else: revenues[period] = sales_revenue if revenues[period] == 0: break #costs taxable_proportion = p['rent_sqft'] / p['total_sqft'].astype(float32) tax = p['property_tax'] * (p['land_cost'] + p['construction_cost']) * taxable_proportion insurance = p['rent_sqft'] * property_insurance construction_equity = 0 construction_loan_interest_payment = construction_loan_balance * construction_loan_rate construction_loan_repayment = revenues[period] \ if construction_loan_balance > revenues[period] \ else construction_loan_balance #adjustment to revenues/costs for_rent_noi = rent_revenue + leases_revenue - tax - insurance - operating_cost - vacancy meets_perm_load_occupancy_threshold = rent_revenue + leases_revenue > \ ( p['rent_revenue'] + p['leases_revenue']) * \ perm_load_occupancy_threshold if perm_loan_size == 0 and \ for_rent_noi > 0 and \ meets_perm_load_occupancy_threshold: perm_loan_size = min((for_rent_noi / cap_rate) * ltv_max, -np.pv(perm_loan_rate, perm_loan_term, for_rent_noi / dcr_max) ) perm_loan_proceeds = perm_loan_size revenues[period] += perm_loan_proceeds if perm_loan_size > 0: perm_loan_interest_payment = -np.pmt(perm_loan_rate, perm_loan_term, perm_loan_size) if not sold_for_rent: costs[period] += tax + insurance + operating_cost + vacancy + \ construction_loan_interest_payment + construction_loan_repayment + \ perm_loan_interest_payment else: costs[period] = 0 construction_loan_balance -= construction_loan_repayment if DEBUG: print period, sales_revenue, full_rent_periods, for_rent_seasoning_threshold if full_rent_periods > for_rent_seasoning_threshold+1 and \ sales_revenue <= 0 and \ not sold_for_rent: #sell_for_rent = 1 perm_loan_repayment = perm_loan_size for_rent_sale = for_rent_noi / cap_rate revenues[period] += for_rent_sale costs[period] += perm_loan_repayment sold_for_rent = 1 #break if DEBUG: print "REVENUES:", revenues costs = costs * (1.0-p['costdiscount']) if DEBUG: print "COSTS:", costs cash_flow = (revenues - costs)[1:period] npv = np.npv(discount_rate, cash_flow) if DEBUG: print "CASHFLOW:", cash_flow if DEBUG: print "NPV:", npv irr = np.irr(cash_flow) return asarray(npv)
from numpy import irr round(irr([-100, 39, 59, 55, 20]), 5) round(irr([-100, 0, 0, 74]), 5) round(irr([-100, 100, 0, -7]), 5) round(irr([-100, 100, 0, 7]), 5) round(irr([-5, 10.5, 1, -8, 1]), 5)
#!/usr/bin/python import numpy print "Internal rate of return", numpy.irr([-100, 38, 48, 90, 17, 36])
change_opex = labor_savings+forklift_savings+floor_salaries ## Gather income statements income_0 = income_statement(name='Year 0', sales=0, cogs=0, sga=0, da=0, interest=0, tax_rate=tax_rate).get_income_statement( depreciation_rate=0, delta_capex=equipment_buy, delta_workingcap=0) income_1 = income_statement(name='Year 1', sales=0, cogs=0, sga=change_opex, da=depreciation_rate, interest=0, tax_rate=tax_rate).get_income_statement( depreciation_rate=depreciation_rate, delta_capex=0, delta_workingcap=0) income_2 = income_statement(name='Year 2', sales=0, cogs=0, sga=change_opex, da=depreciation_rate, interest=0, tax_rate=tax_rate).get_income_statement(depreciation_rate=depreciation_rate, delta_capex=0, delta_workingcap=0) income_3 = income_statement(name='Year 3', sales=0, cogs=0, sga=change_opex, da=depreciation_rate, interest=0, tax_rate=tax_rate).get_income_statement(depreciation_rate=depreciation_rate, delta_capex=equipment_sell, delta_workingcap=0) income = pd.concat([income_0, income_1, income_2, income_3], axis=1) print(income) NPV = np.npv(discount_rate, income.ix['FreeCashFlow']) IRR = np.irr(income.ix['FreeCashFlow']) payback_period = abs(income.ix['FreeCashFlow'][0]) / income.ix['FreeCashFlow'][1:].sum() print(''' NPV ................................ %.2f IRR ................................ %.2f Payback Period ................................ %.2f '''%(NPV, IRR, payback_period)) # In[167]: income.ix['FreeCashFlow'][1:] # In[ ]: