def choose_tech(VE,D,j,N,energy,prices_lamp,tt,interes):

    method=strategy(VE[j,2])
    #returns the strategy to use over the different profiles
    #(1)rational, (2) social, (3) conservative


    #Rational method
    if method==1:   #180 hours of consume in average per month
        cost=np.zeros((3,139)) #Payments over time of the different techs
        cost_present=np.zeros(3) #Total present cost
        
        #Analysis of energy consume
        for i in range(139):
            if VE[j,3]==1:
                cost[0,i]=(-40*180/100)*energy[i+tt]*0.8
                cost[1,i]=(-15*180/100)*energy[i+tt]*0.8
                cost[2,i]=(-9*180/100)*energy[i+tt]*0.8
            elif VE[j,3]==2:
                cost[0,i]=(-40*180/100)*energy[i+tt]*1.2
                cost[1,i]=(-15*180/100)*energy[i+tt]*1.2
                cost[2,i]=(-9*180/100)*energy[i+tt]*1.2
        
        #LED lamp cost
        cost[2,0]=cost[2,0]-prices_lamp[2,tt]
    
        #Fluorescent lamp cost (1:36:139)
        for i in range(0,138,36):
            cost[1,i]=cost[1,i]-prices_lamp[1,tt+i]
    
        #Incandescent lamp cost (i=1:4:139)
        for i in range(0,138,4):
            cost[0,i]=cost[0,i]-prices_lamp[0,tt+i]
            
        #Cost in present value
        cost_present[0]=-np.npv(interes,cost[0,:])
        cost_present[1]=-np.npv(interes,cost[1,:])
        cost_present[2]=-np.npv(interes,cost[2,:])
    
        #Selection of the best npv performance
        tech=cost_present.argmin()
        tech=tech+1
    
    #Conservative method
    if method==3:
        tech=VE[j,0]


    #Social method
    if method==2:
        S_t=np.zeros(3) #Counter of technologies in vicinity
        D_N=D.neighbors(j) #Returns the list of neighbors
        D_N_len=len(D_N) #Dimension of neighbors list
            
        for k in range(D_N_len): #Iteration of evaluation
            S_t[VE[D_N[k],0]-1]=S_t[VE[D_N[k],0]-1]+1
                
        tech=S_t.argmax()+1
        
    return(tech)
 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 net_present_value_aggregate_for_portfolio(self):
        """ Gets the portfolio's aggregate net present value.

        Returns: The portfolio's aggregate net present value.

        """
        npv = np.npv(self.discount_rate / 12, list(self.aggregate_flows_df['total_payments']))
        return float(npv)
    def net_present_value_for_loan(self, loan):
        """ Calculates a loan's net present value from its cash flows.

        Args:
            loan: The loan which is being valued.

        Returns: The net present value of the loan.

        """
        cash_flows = self.cash_flows_df[self.cash_flows_df['loan_df_pk'] == loan.name]
        npv = np.npv(self.discount_rate / 12, cash_flows['total_payments'])
        return npv
Ejemplo n.º 5
0
def create_company_simulation(simulation_id, stock_id):
    getcontext().prec = 4
    mu = 0.02
    sigma = 0.1
    simulation = Simulation.objects.get(pk=simulation_id)
    stock = Stock.objects.get(pk=stock_id)
    ticker = Ticker.objects.get(simulation=simulation)
    company = TickerCompany(ticker=ticker, stock=stock, symbol=stock.symbol, name="Company %s" % stock.symbol)
    company.save()
    rounds = ticker.nb_rounds + 1
    brownian_motion = geometric_brownian(rounds, mu, sigma, ticker.initial_value, rounds/(ticker.nb_days*rounds), stock_id)
    i = 0
    simulation_dividends = []
    simulation_net_income = []
    for sim_round in range(0, rounds):
        round_dividend = 0
        round_net_income = 0
        for sim_day in range(1, ticker.nb_days+1):
            # We have each round/day and the corresponding dividend
            daily_dividend = brownian_motion[i]
            daily_net_income = brownian_motion[i] / float(ticker.dividend_payoff_rate) * 100 * stock.quantity
            c = CompanyFinancial(company=company, daily_dividend=Decimal(daily_dividend), daily_net_income=Decimal(daily_net_income),
                                 sim_round=sim_round, sim_day=sim_day, sim_date=sim_round*100+sim_day)
            c.save()
            round_dividend += daily_dividend
            round_net_income += daily_net_income
            i += 1
        simulation_dividends.append(round_dividend)
        simulation_net_income.append(round_net_income)

    # Share price estimation
    G = simulation_dividends[-1]/simulation_dividends[-2]-1
    R = 0.15
    g = R
    drift = 0
    simulation_stock_price = []
    previous_company_income = None
    for sim_round in range(0, rounds):
        stock_price = np.npv(0.15, simulation_dividends[sim_round:rounds]) + (simulation_dividends[-1]*(1+g)/(R-G))/np.power(1+R, rounds-sim_round)
        simulation_stock_price.append(stock_price)
        if previous_company_income:
            drift = simulation_net_income[sim_round] / float(previous_company_income.net_income) - 1
            previous_company_income.drift = Decimal(drift)
            previous_company_income.save()
        company_share = CompanyShare(company=company, share_value=Decimal(stock_price), dividends=Decimal(simulation_dividends[sim_round]),
                                     net_income=Decimal(simulation_net_income[sim_round]), drift=Decimal(drift), sim_round=sim_round)
        company_share.save()
        previous_company_income = company_share
        if sim_round == 0:
            stock.price = Decimal(stock_price)
            stock.save()
    return company.id
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
def mirr(values, finance_rate, reinvest_rate):
    """
    Modified internal rate of return.

    Parameters
    ----------
    values : array_like
        Cash flows (must contain at least one positive and one negative value)
        or nan is returned.
    finance_rate : scalar
        Interest rate paid on the cash flows
    reinvest_rate : scalar
        Interest rate received on the cash flows upon reinvestment

    Returns
    -------
    out : float
        Modified internal rate of return

    """

    values = np.asarray(values)
    initial = values[0]
    values = values[1:]
    n = values.size
    pos = values * (values>0)
    neg = values * (values<0) 
    if not (pos.size > 0 and neg.size > 0):
        return np.nan

    numer = np.abs(np.npv(reinvest_rate, pos))
    denom = np.abs(np.npv(finance_rate, neg))
    if initial>0:
        return ((initial + numer) / denom)**(1.0/n)*(1+reinvest_rate) - 1
    else:
        return ((numer / (-initial + denom)))**(1.0/n)*(1+reinvest_rate) - 1
Ejemplo n.º 8
0
def eq_subvention(montant, duree, taux):
    """ Calcule l' "équivalent subvention" par rapport à un taux 0%
    pour chacune des différentes combinaisons d'hypothèses possibles"""
    # RAZ des résultats
    equivalent_subvention = np.zeros((len(montant), len(duree), len(taux)))
    part_subventionee = np.zeros((len(montant), len(duree), len(taux)))
    # Calcule de l' "équivalent subvention"
    for i in range(len(montant)):
        for j in range(len(duree)):
            # Périodicité des remboursements
            per = np.arange(duree[j]) + 1
            for k in range(len(taux)):
                # Calcule l'échancier des intérêts perçus
                echeancier_interets = -np.ipmt(taux[k], per, duree[j], montant[i])
                # Calcule et enregistre l' "équivalent subvention" comparé
                # à un taux 0 pour le jeu d'hypothèses considéré, les flux
                # d'intérêt étant actualisés à 4%
                equivalent_subvention[i, j, k] = np.npv(0.04, echeancier_interets)
                # ou alternativemen, sans actualiser:
                # equivalent_subvention[i,j,k]=np.sum(echeancier_interets)
                part_subventionee[i, j, k] = (equivalent_subvention[i, j, k] / montant[i]) * 100
    return equivalent_subvention, part_subventionee
Ejemplo n.º 9
0
def calc_npv(r, ubi, inputs, n):
    x = np.zeros((ubi['Years Post Transfer'], n))
    y = np.zeros((ubi['Years Post Transfer'], n))
    
    # iterate through years of benefits
    for j in range(1, ubi['Years Post Transfer'] + 1):
        # sum benefits during program
        if(j < r):
            x[j - 1] += ubi['Expected baseline per capita consumption (nominal USD)']* \
                np.power((1.0 + inputs['UBI']['Expected annual consumption increase (without the UBI program)']), float(j))* \
                inputs['UBI']['Work participation adjustment'] + \
                ubi['Annual quantity of transfer money used for immediate consumtion (pre-discounting)']
        # benefits after program
        else:
            x[j - 1] += ubi['Expected baseline per capita consumption (nominal USD)']* \
                np.power((1.0 + inputs['UBI']['Expected annual consumption increase (without the UBI program)']), float(j))
        
        # investments calculations
        for k in range(n):
            if(j < r + inputs['UBI']['Duration of investment benefits (in years) - UBI'][k]):
                x[j - 1][k] += ubi['Annual return for each year of transfer investments (pre-discounting)'][k]* \
                    np.min([j, inputs['UBI']['Duration of investment benefits (in years) - UBI'][k], \
                    r, (inputs['UBI']['Duration of investment benefits (in years) - UBI'][k] + r - j)])
            
                if(j > r):
                    x[j - 1][k] += ubi['Value eventually returned from one years investment (pre-discounting)'][k]
                    
        # log transform and subtact baseline
        y[j - 1] = np.log(x[j - 1])
        y[j - 1] -= np.log(ubi['Expected baseline per capita consumption (nominal USD)']* \
            np.power((1.0 + inputs['UBI']['Expected annual consumption increase (without the UBI program)']), float(j)))
    
    # npv on yearly data
    z = np.zeros(n)
    for i in range(n):
        z[i] = np.npv(inputs['Shared']['Discount rate'][i], y[:, i])
    return z
depreciation_rate = 200
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:]

def robust_npv(values, rate=0.03):
	try:
		return np.npv(rate, values)
	except:
		return np.nan
Ejemplo n.º 12
0
 def npv(flow, r=disc_fac):
     sum = 0
     for i in range(flow.shape[1]):
         sum += np.npv(r, flow[:, i])
     return sum
Ejemplo n.º 13
0
 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
Ejemplo n.º 14
0
		energySaleChange = sum(energySaleDRyear) - sum(energySaleArray)
		peakDemandRed = PeakDemandCharge - PeakDemandChargeDR
		# Calculating the Purchase Cost, Operation and Maint. Cost and Total Cost
		outData["AnnualOpCost"] = [- AnnDROM for x in lifeYears[0:]]
		LifetimeOperationCost = (sum(outData["AnnualOpCost"]))
		outData["LifetimeOperationCost"] = abs(LifetimeOperationCost)
		outData["lifePurchaseCosts"] = [-1.0 * DrTechCost] + [0 for x in lifeYears[1:]]
		outData["TotalCost"] = abs(outData["LifetimeOperationCost"] + DrTechCost)
		# Outputs of the Program Lifetime Cash Flow figure
		outData["EnergySaleChangeBenefit"] = [energySaleChange * ScalingAnnual ** x for x in range(lifeSpan)]
		outData["PeakDemandReduction"] = [peakDemandRed * ScalingAnnual ** x for x in range(lifeSpan)]
		BenefitCurve = [x+y for x,y in zip(outData["EnergySaleChangeBenefit"], outData["PeakDemandReduction"])]
		outData["TotalBenefit"] = sum(BenefitCurve)
		outData["BenefittoCostRatio"] = float(outData["TotalBenefit"] / outData["TotalCost"])
		netBenefit = [x+y+z for x,y,z in zip(outData["AnnualOpCost"],outData["lifePurchaseCosts"],BenefitCurve)]
		outData["npv"] = npv(DiscountRate, netBenefit)
		outData["cumulativeNetBenefit"] = [sum(netBenefit[0:i+1]) for i,d in enumerate(netBenefit)]
		outData["SimplePaybackPeriod"] = DrTechCost / (outData["TotalBenefit"] / lifeSpan)
		# 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 = datetime.datetime.now()
		inputDict["runTime"] = str(datetime.timedelta(seconds=int((endTime - startTime).total_seconds())))
		with open(pJoin(modelDir,"allInputData.json"),"w") as inFile:
			json.dump(inputDict, inFile, indent=4)
	except:
		# If input range wasn't valid delete output, write error to disk.
Ejemplo n.º 15
0
def work(modelDir, inputDict):
	''' Run the model in its directory.'''
	if inputDict['dispatch_type'] == 'prediction':
		return workForecast(modelDir, inputDict)

	out = {}
	try:
		with open(pJoin(modelDir, 'demand.csv'), 'w') as f:
			f.write(inputDict['demandCurve'].replace('\r', ''))
		with open(pJoin(modelDir, 'demand.csv')) as f:
			demand = [float(r[0]) for r in csv.reader(f)]
	 		assert len(demand) == 8760	
		
		with open(pJoin(modelDir, 'temp.csv'), 'w') as f:
			lines = inputDict['tempCurve'].split('\n')
			out["tempData"] = [float(x) if x != '999.0' else float(inputDict['setpoint']) for x in lines[:-1]]
			correctData = [x+'\n' if x != '999.0' else inputDict['setpoint']+'\n' for x in lines][:-1]
			f.write(''.join(correctData))
			assert len(correctData) == 8760
	except:
		raise Exception("CSV file is incorrect format. Please see valid format "
			"definition at <a target='_blank' href = 'https://github.com/dpinney/"
			"omf/wiki/Models-~-storagePeakShave#demand-file-csv-format'>\nOMF Wiki "
			"storagePeakShave - Demand File CSV Format</a>")
	
	# # created using calendar = {'1': 31, '2': 28, ..., '12': 31}
	# m = [calendar[key]*24 for key in calendar]
	# monthHours = [(sum(m[:i]), sum(m[:i+1])) for i, _ in enumerate(m)]
	monthHours = [(0, 744), (744, 1416), (1416, 2160), (2160, 2880), 
					(2880, 3624), (3624, 4344), (4344, 5088), (5088, 5832), 
					(5832, 6552), (6552, 7296), (7296, 8016), (8016, 8760)]

	P_lower, P_upper, E_UL = pyVbat(modelDir, inputDict)
	P_lower, P_upper, E_UL = list(P_lower), list(P_upper), list(E_UL)

	out["minPowerSeries"] = [-1*x for x in P_lower]
	out["maxPowerSeries"] = P_upper
	out["minEnergySeries"] = [-1*x for x in E_UL]
	out["maxEnergySeries"] = E_UL
	
	VBpower, out["VBenergy"] = pulpFunc(inputDict, demand, P_lower, P_upper, E_UL, monthHours)
	out["VBpower"] = VBpower
	out["dispatch_number"] = [len([p for p in VBpower[s:f] if p != 0]) for (s, f) in monthHours]

	peakDemand = [max(demand[s:f]) for s, f in monthHours] 
	energyMonthly = [sum(demand[s:f]) for s, f in monthHours]
	demandAdj = [d+p for d, p in zip(demand, out["VBpower"])]
	peakAdjustedDemand = [max(demandAdj[s:f]) for s, f in monthHours]
	energyAdjustedMonthly = [sum(demandAdj[s:f]) for s, f in monthHours]

	rms = all([x == 0 for x in P_lower]) and all([x == 0 for x in P_upper])
	out["dataCheck"] = 'VBAT returns no values for your inputs' if rms else ''
	out["demand"] = demand
	out["peakDemand"] = peakDemand
	out["energyMonthly"] = energyMonthly
	out["demandAdjusted"] = demandAdj
	out["peakAdjustedDemand"] = peakAdjustedDemand
	out["energyAdjustedMonthly"] = energyAdjustedMonthly
	
	cellCost = float(inputDict["unitDeviceCost"])*float(inputDict["number_devices"])
	eCost = float(inputDict["electricityCost"])
	dCharge = float(inputDict["demandChargeCost"])

	out["VBdispatch"] = [dal-d for dal, d in zip(demandAdj, demand)]
	out["energyCost"] = [em*eCost for em in energyMonthly]
	out["energyCostAdjusted"] = [eam*eCost for eam in energyAdjustedMonthly]
	out["demandCharge"] = [peak*dCharge for peak in peakDemand]
	out["demandChargeAdjusted"] = [pad*dCharge for pad in out["peakAdjustedDemand"]]
	out["totalCost"] = [ec+dcm for ec, dcm in zip(out["energyCost"], out["demandCharge"])]
	out["totalCostAdjusted"] = [eca+dca for eca, dca in zip(out["energyCostAdjusted"], out["demandChargeAdjusted"])]
	out["savings"] = [tot-tota for tot, tota in zip(out["totalCost"], out["totalCostAdjusted"])]

	annualEarnings = sum(out["savings"]) - float(inputDict["unitUpkeepCost"])*float(inputDict["number_devices"])
	cashFlowList = [annualEarnings] * int(inputDict["projectionLength"])
	cashFlowList.insert(0, -1*cellCost)

	out["NPV"] = npv(float(inputDict["discountRate"])/100, cashFlowList)
	out["SPP"] = cellCost / annualEarnings
	out["netCashflow"] = cashFlowList
	out["cumulativeCashflow"] = [sum(cashFlowList[:i+1]) for i, d in enumerate(cashFlowList)]

	out["stdout"] = "Success"
	return out
Ejemplo n.º 16
0
#
fv = np.fv(0.01, 5, -100, -1000)
print(round(fv, 2))
#
# 现值 = numpy.pv(利率, 期数, 每期支付, 终值)
# 将多少钱1%的年利率存入银行5年,每年加存100元,
# 到期后本息合计fv元?
#
pv = np.pv(0.01, 5, -100, fv)
print(pv)
#
# 净现值 = numpy.npv(利率, 现金流)
# 将1000元以1%的年利率存入银行5年,每年加存100元,
# 相当于一次存入多少钱?
#
npv = np.npv(0.01, [-1000, -100, -100, -100, -100, -100])
print(round(npv, 2))
fv = np.fv(0.01, 5, 0, npv)
print(round(fv, 2))
#
# 内部收益率 = numpy.irr(现金流)
# 将1000元存入银行5年,以后逐年提现100元、200元、300元、
# 400元、500元,银行利率达到多少,可在最后一次提现后偿
# 清全部本息?
#
irr = np.irr([-1000, 100, 200, 300, 400, 500])
print(round(irr, 2))
npv = np.npv(irr, [-1000, 100, 200, 300, 400, 500])
print(round(npv, 2))
#
# 每期支付 = numpy.pmt(利率, 期数, 现值)
Ejemplo n.º 17
0
def work(modelDir, inputDict):
	''' Model processing done here. '''
	dispatchStrategy = str(inputDict.get('dispatchStrategy'))
	if dispatchStrategy == 'prediction':
		return forecastWork(modelDir, inputDict)

	out = {}  # See bottom of file for out's structure
	cellCapacity, dischargeRate, chargeRate, cellQuantity, demandCharge, cellCost, retailCost = \
		[float(inputDict[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate',
			'cellQuantity', 'demandCharge', 'cellCost', 'retailCost')]

	projYears, batteryCycleLife = [int(inputDict[x]) for x in ('projYears', 'batteryCycleLife')]
	
	discountRate = float(inputDict.get('discountRate')) / 100.0
	dodFactor = float(inputDict.get('dodFactor')) / 100.0

	# Efficiency calculation temporarily removed
	inverterEfficiency = float(inputDict.get('inverterEfficiency')) / 100.0
	# Note: inverterEfficiency is squared to get round trip efficiency.
	battEff = float(inputDict.get('batteryEfficiency')) / 100.0 * (inverterEfficiency ** 2)

	with open(pJoin(modelDir, 'demand.csv'), 'w') as f:
		f.write(inputDict['demandCurve'])
	if dispatchStrategy == 'customDispatch':
		with open(pJoin(modelDir, 'dispatchStrategy.csv'), 'w') as f:
			f.write(inputDict['customDispatchStrategy'])

	dc = [] # main data table
	try:
		dates = [(dt(2011, 1, 1) + timedelta(hours=1)*x) for x in range(8760)]
		with open(pJoin(modelDir, 'demand.csv')) as f:
			reader = csv.reader(f)
			for row, date in zip(reader, dates):
				dc.append({	'power': float(row[0]), # row is a list of length 1
							'month': date.month - 1,
							'hour': date.hour })
		assert len(dc) == 8760
	except:
		if str(sys.exc_info()[0]) != "<type 'exceptions.SystemExit'>":
			raise Exception("CSV file is incorrect format. Please see valid "
				"format definition at <a target='_blank' href = 'https://github.com/"
				"dpinney/omf/wiki/Models-~-storagePeakShave#demand-file-csv-format'>"
				"\nOMF Wiki storagePeakShave - Demand File CSV Format</a>")

	# list of 12 lists of monthly demands
	demandByMonth = [[t['power'] for t in dc if t['month']==x] for x in range(12)]
	monthlyPeakDemand = [max(lDemands) for lDemands in demandByMonth]
	battCapacity = cellQuantity * cellCapacity * dodFactor
	battDischarge = cellQuantity * dischargeRate
	battCharge = cellQuantity * chargeRate

	SoC = battCapacity 
	if dispatchStrategy == 'optimal':
		ps = [battDischarge] * 12
		# keep shrinking peak shave (ps) until every month doesn't fully expend the battery
		while True:
			SoC = battCapacity
			incorrect_shave = [False] * 12
			for row in dc:
				month = row['month']
				if not incorrect_shave[month]:
					powerUnderPeak = monthlyPeakDemand[month] - row['power'] - ps[month]
					charge = (min(powerUnderPeak, battCharge, battCapacity - SoC) if powerUnderPeak > 0
						else -1 * min(abs(powerUnderPeak), battDischarge, SoC))
					if charge == -1 * SoC:
						incorrect_shave[month] = True
					SoC += charge
					row['netpower'] = row['power'] + charge
					row['battSoC'] = SoC
			ps = [s-1 if incorrect else s for s, incorrect in zip(ps, incorrect_shave)]
			if not any(incorrect_shave):
				break
	elif dispatchStrategy == 'daily':
		start = int(inputDict.get('startPeakHour'))
		end = int(inputDict.get('endPeakHour'))
		for r in dc:
			# Discharge if hour is within peak hours otherwise charge
			charge = (-1*min(battDischarge, SoC) if start <= r['hour'] <= end 
				else min(battCharge, battCapacity - SoC))
			r['netpower'] = r['power'] + charge
			SoC += charge
			r['battSoC'] = SoC
	elif dispatchStrategy == 'customDispatch':
		try:
			with open(pJoin(modelDir,'dispatchStrategy.csv')) as f:
				reader = csv.reader(f)
				for d, r in zip(dc, reader):
					d['dispatch'] = int(r[0])
				assert all(['dispatch' in r for r in dc])  # ensure each row is filled
		except:
			if str(sys.exc_info()[0]) != "<type 'exceptions.SystemExit'>":
				raise Exception("Dispatch Strategy file is in an incorrect " 
					"format. Please see valid format definition at <a target "
					"= '_blank' href = 'https://github.com/dpinney/omf/wiki/"
					"Models-~-storagePeakShave#custom-dispatch-strategy-file-"
					"csv-format'>\nOMF Wiki storagePeakShave - Custom "
					"Dispatch Strategy File Format</a>")
		for r in dc:
			# Discharge if there is a 1 in the dispatch strategy csv, otherwise charge the battery.
			charge = (-1*min(battDischarge, SoC) if r['dispatch'] == 1 
				else min(battCharge, battCapacity-SoC))
			r['netpower'] = r['power'] + charge
			SoC += charge
			r['battSoC'] = SoC

	# ------------------------- CALCULATIONS ------------------------- #
	netByMonth = [[t['netpower'] for t in dc if t['month']==x] for x in range(12)]
	monthlyPeakNet = [max(net) for net in netByMonth]
	ps = [h-s for h, s in zip(monthlyPeakDemand, monthlyPeakNet)]
	dischargeByMonth = [[i-j for i, j in zip(k, l) if i-j < 0] for k, l in zip(netByMonth, demandByMonth)]

	# Monthly Cost Comparison Table
	out['monthlyDemand'] = [sum(lDemand)/1000 for lDemand in demandByMonth]
	out['monthlyDemandRed'] = [t-p for t, p in zip(out['monthlyDemand'], ps)]
	out['ps'] = ps
	out['benefitMonthly'] = [x*demandCharge for x in ps]
	
	# Demand Before and After Storage Graph
	out['demand'] = [t['power']*1000.0 for t in dc] # kW -> W
	out['demandAfterBattery'] = [t['netpower']*1000.0 for t in dc] # kW -> W
	out['batteryDischargekW'] = [d-b for d, b in zip(out['demand'], out['demandAfterBattery'])]
	out['batteryDischargekWMax'] = max(out['batteryDischargekW'])

	# Battery State of Charge Graph
	# Turn dc's SoC into a percentage, with dodFactor considered.
	out['batterySoc'] = SoC = [t['battSoC']/battCapacity*100*dodFactor + (100-100*dodFactor) for t in dc]
	# Estimate number of cyles the battery went through. Sums the percent of SoC.
	cycleEquivalents = sum([SoC[i]-SoC[i+1] for i, x in enumerate(SoC[:-1]) if SoC[i+1] < SoC[i]]) / 100.0
	out['cycleEquivalents'] = cycleEquivalents
	out['batteryLife'] = batteryCycleLife / cycleEquivalents

	# Cash Flow Graph
	# inserting battery efficiency only into the cashflow calculation
	# cashFlowCurve is $ in from peak shaving minus the cost to recharge the battery every day of the year
	cashFlowCurve = [sum(ps)*demandCharge for year in range(projYears)]
	cashFlowCurve.insert(0, -1 * cellCost * cellQuantity)  # insert initial investment
	# simplePayback is also affected by the cost to recharge the battery every day of the year
	out['SPP'] = (cellCost*cellQuantity)/(sum(ps)*demandCharge)
	out['netCashflow'] = cashFlowCurve
	out['cumulativeCashflow'] = [sum(cashFlowCurve[:i+1]) for i, d in enumerate(cashFlowCurve)]
	out['NPV'] = npv(discountRate, cashFlowCurve)

	battCostPerCycle = cellQuantity * cellCost / batteryCycleLife
	lcoeTotCost = cycleEquivalents*retailCost + battCostPerCycle*cycleEquivalents
	out['LCOE'] = lcoeTotCost / (cycleEquivalents*battCapacity)

	# Other
	out['startDate'] = '2011-01-01'  # dc[0]['datetime'].isoformat()
	out['stderr'] = ''
	# Seemingly unimportant. Ask permission to delete.
	out['stdout'] = 'Success' 
	out['months'] = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]

	return out
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
import numpy as np
# (1) 生成5个随机数作为现金流的取值。插入-100作为初始值。
cashflows = np.random.randint(100, size=5)
cashflows = np.insert(cashflows, 0, -100)
print("Cashflows", cashflows)
# (2) 根据上一步生成的现金流数据,调用npv函数计算净现值。利率按3%计算
print("Net present value", np.npv(0.03, cashflows))
Ejemplo n.º 20
0
def robust_npv(values, rate=0.03):
	try:
		return np.npv(rate, values)
	except:
		return np.nan
Ejemplo n.º 21
0
def work(modelDir, inputDict):
    ''' Run the model in a separate process. web.py calls this to run the model.
	This function will return fast, but results take a while to hit the file system.'''
    o = {}
    (cellCapacity, dischargeRate, chargeRate, cellQuantity, cellCost) = \
     [float(inputDict[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate', 'cellQuantity', 'cellCost')]
    inverterEfficiency = float(inputDict.get("inverterEfficiency")) / 100.0
    battEff = float(
        inputDict.get("batteryEfficiency")) / 100.0 * (inverterEfficiency**2)
    discountRate = float(inputDict.get('discountRate')) / 100.0
    dodFactor = float(inputDict.get('dodFactor')) / 100.0
    projYears = int(inputDict.get('projYears'))
    dischargePriceThreshold = float(inputDict.get('dischargePriceThreshold'))
    chargePriceThreshold = float(inputDict.get('chargePriceThreshold'))
    batteryCycleLife = int(inputDict.get('batteryCycleLife'))

    # Put demand data in to a file for safe keeping.
    with open(pJoin(modelDir, 'demand.csv'), 'w') as f:
        f.write(inputDict['demandCurve'])
    with open(pJoin(modelDir, 'priceCurve.csv'), 'w') as f:
        f.write(inputDict['priceCurve'])

    # Most of our data goes inside the dc "table"
    dates = [dt(2011, 1, 1) + timedelta(hours=1) * x for x in range(8760)]
    dc = []
    try:
        with open(pJoin(modelDir, 'demand.csv'), newline='') as f:
            for row, date in zip(csv.reader(f), dates):
                dc.append({'month': date.month - 1, 'power': float(row[0])})
        assert len(dc) == 8760
    except:
        if str(sys.exc_info()[0]) != "<type 'exceptions.SystemExit'>":
            raise Exception("Demand CSV file is incorrect format.")
    #Add price to dc table
    try:
        with open(pJoin(modelDir, 'priceCurve.csv'), newline='') as f:
            for row, d in zip(csv.reader(f), dc):
                d['price'] = float(row[0])
        assert all(['price' in r for r in dc])
    except:
        if str(sys.exc_info()[0]) != "<type 'exceptions.SystemExit'>":
            raise Exception("Price Curve File is in an incorrect format.")

    battCapacity = cellQuantity * cellCapacity * dodFactor
    battSoC = battCapacity
    for r in dc:
        #If price of energy is above price threshold and battery has charge, discharge battery
        if r['price'] >= dischargePriceThreshold:
            charge = -1 * min(cellQuantity * dischargeRate, battSoC)
        elif r['price'] <= chargePriceThreshold:
            charge = min(cellQuantity * chargeRate, battCapacity - battSoC)
        else:
            charge = 0
        r['netpower'] = r['power'] + charge
        r['battSoC'] = battSoC
        battSoC += charge

    # There's definitely a nicer way to make this for loop, apologies
    monthlyCharge = []
    monthlyDischarge = []
    monthlyDischargeSavings = []
    monthlyChargeCost = []
    # Calculate the monthly cost to charge and savings by discharging
    for x in range(12):
        chargeCost = 0
        dischargeSavings = 0
        chargePower = 0
        dischargePower = 0
        for r in dc:
            if r['month'] == x:
                diff = r['netpower'] - r['power']
                if diff > 0:
                    chargePower += diff
                    chargeCost += diff * r['price']
                if diff < 0:
                    dischargePower += -1 * diff
                    dischargeSavings += -1 * diff * r['price']
        monthlyCharge.append(chargePower)
        monthlyDischarge.append(dischargePower)
        monthlyDischargeSavings.append(dischargeSavings)
        monthlyChargeCost.append(chargeCost)

    # include BattEff into calculations
    monthlyCharge = [t / battEff for t in monthlyCharge]
    monthlyChargeCost = [t / battEff for t in monthlyChargeCost]

    # Monthly Cost Comparison Table
    o['energyOffset'] = monthlyDischarge
    o['dischargeSavings'] = monthlyDischargeSavings
    o['kWhtoRecharge'] = monthlyCharge
    o['costToRecharge'] = monthlyChargeCost
    # NPV, SPP are below

    # Demand Before and After Storage Graph
    o['demand'] = [t['power'] * 1000.0 for t in dc]
    o['demandAfterBattery'] = [t['netpower'] * 1000.0 for t in dc]
    o['batteryDischargekW'] = [
        d - b for d, b in zip(o['demand'], o['demandAfterBattery'])
    ]
    o['batteryDischargekWMax'] = max(o['batteryDischargekW'])

    # Price Input Graph
    o['price'] = [r['price'] for r in dc]

    # Battery SoC Graph
    o['batterySoc'] = SoC = [
        t['battSoC'] / battCapacity * 100.0 * dodFactor +
        (100 - 100 * dodFactor) for t in dc
    ]
    cycleEquivalents = sum([
        SoC[i] - SoC[i + 1]
        for i, x in enumerate(SoC[:-1]) if SoC[i + 1] < SoC[i]
    ]) / 100.0
    o['cycleEquivalents'] = cycleEquivalents
    o['batteryLife'] = batteryCycleLife / cycleEquivalents

    # Cash Flow Graph
    yearlyDischargeSavings = sum(monthlyDischargeSavings)
    yearlyChargeCost = sum(monthlyChargeCost)
    cashFlowCurve = [yearlyDischargeSavings - yearlyChargeCost] * projYears
    cashFlowCurve.insert(0, -1 * cellCost * cellQuantity)
    o['benefitNet'] = [
        ds - cc for cc, ds in zip(o['costToRecharge'], o['dischargeSavings'])
    ]
    o['netCashflow'] = cashFlowCurve
    o['cumulativeCashflow'] = [
        sum(cashFlowCurve[:i + 1]) for i, d in enumerate(cashFlowCurve)
    ]
    o['NPV'] = npv(discountRate, cashFlowCurve)
    o['SPP'] = (cellCost * cellQuantity) / (yearlyDischargeSavings -
                                            yearlyChargeCost)
    battCostPerCycle = cellQuantity * cellCost / batteryCycleLife
    lcoeTotCost = (cycleEquivalents * cellQuantity * cellCapacity *
                   chargePriceThreshold) + (battCostPerCycle *
                                            cycleEquivalents)
    o['LCOE'] = lcoeTotCost / (cycleEquivalents * cellCapacity * cellQuantity)

    # Other
    o['startDate'] = '2011-01-01'
    o["stdout"] = "Success"
    o["stderr"] = ""
    return o
Ejemplo n.º 22
0
 def pv(self):
     return np.npv(self.interest, [0] + self.cash_flows)
Ejemplo n.º 23
0
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))
Ejemplo n.º 24
0
        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
Ejemplo n.º 25
0
econ_cap['cum_net_nondiscounted_cashflow'] = econ_cap[
    'net_nondiscounted_cash_flow'].cumsum()

econ_cap['net_discounted_cashflow'] = econ_cap.apply(
    lambda row: row['net_nondiscounted_cash_flow'] /
    ((1 + annual_to_monthly_rate(config['discount_rate_annual']))**
     (row['standard_time'])),
    axis=1)

econ_cap['cum_net_discounted_cashflow'] = econ_cap[
    'net_discounted_cashflow'].cumsum()

econ_cap.to_excel(excel_output_file)

npv = round(
    np.npv(annual_to_monthly_rate(config['discount_rate_annual']),
           econ_cap['net_nondiscounted_cash_flow']), 2)
irr = round(np.irr(econ_cap['net_nondiscounted_cash_flow']), 2)
pv5 = round(
    np.npv(annual_to_monthly_rate(0.05),
           econ_cap['net_nondiscounted_cash_flow']), 2)
pv8 = round(
    np.npv(annual_to_monthly_rate(0.08),
           econ_cap['net_nondiscounted_cash_flow']), 2)
pv10 = round(
    np.npv(annual_to_monthly_rate(0.10),
           econ_cap['net_nondiscounted_cash_flow']), 2)
pv15 = round(
    np.npv(annual_to_monthly_rate(0.15),
           econ_cap['net_nondiscounted_cash_flow']), 2)
pv20 = round(
    np.npv(annual_to_monthly_rate(0.20),
Ejemplo n.º 26
0
def work(modelDir, inputDict):
	''' Run the model in its directory. '''
	outData = {}
	# Get variables.
	lifeSpan = int(inputDict.get('lifeSpan',25))
	lifeYears = list(range(1, 1 + lifeSpan))
	hours = list(range(0, 24))
	DrTechCost = float(inputDict.get('DrPurchInstallCost'))
	demandCharge = float(inputDict.get('demandCharge'))
	retailCost = float(inputDict.get('retailCost'))
	AnnDROM = float(inputDict.get('AnnualDROperationCost'))
	SubElas = float(inputDict.get('SubstitutionPriceElasticity'))
	DayElas = float(inputDict.get('DailyPriceElasticity'))
	wholesaleCost = float(inputDict.get('WholesaleEnergyCost'))
	ManagLoad = float(inputDict.get('LoadunderManagement')) / 100.0
	DiscountRate = float(inputDict.get('DiscountRate')) / 100
	ScalingAnnual = float(inputDict.get('ScalingAnnual'))/ 100
	PeakRate = float(inputDict.get('PeakRate'))
	OffPeakRate = float(inputDict.get('OffPeakRate'))
	startmonth= int(inputDict.get('startMonth'))
	stopmonth = int(inputDict.get('stopMonth'))
	starthour = int(inputDict.get('startHour'))
	stophour = int(inputDict.get('stopHour'))
	rateCPP = float(inputDict.get('rateCPP'))
	rate24hourly = [float(x) for x in inputDict.get('rate24hourly').split(',')]
	ratePTR = float(inputDict.get('ratePTR'))
	numCPPDays = int(inputDict.get('numCPPDays'))
	rateStruct = inputDict.get('rateStruct')
	# Price vector creation.
	OffPeakDailyPrice1 = [OffPeakRate for x in hours[0:starthour]]
	PeakDailyPrice = [PeakRate for x in hours[starthour-1:stophour]]
	OffPeakDailyPrice2 = [OffPeakRate for x in hours[stophour+1:24]]
	ProgramPrices =[]
	ProgramPrices.extend(OffPeakDailyPrice1)
	ProgramPrices.extend(PeakDailyPrice)
	ProgramPrices.extend(OffPeakDailyPrice2)
	# Setting up the demand curve.
	with open(pJoin(modelDir,"demand.csv"),"w") as demandFile:
		demandFile.write(inputDict['demandCurve'])
	try:
		demandList = []
		with open(pJoin(modelDir,"demand.csv"), newline='') as inFile:
			reader = csv.reader(inFile)
			for row in reader:
				demandList.append(row) #######demandList.append({'datetime': parse(row['timestamp']), 'power': float(row['power'])})
			if len(demandList)!=8760: raise Exception
	except:
		errorMessage = "CSV file is incorrect format. Please see valid format definition at <a target='_blank' href='https://github.com/dpinney/omf/wiki/Models-~-demandResponse#walkthrough'>OMF Wiki demandResponse</a>"
		raise Exception(errorMessage)

	demandCurve = [float(x[0]) for x in demandList]
	outData['startDate'] = '2011-01-01'######demandList[0]['datetime'].isoformat()
	# Run the PRISM model.
	allPrismOutput = prism({
		'rateStructure': rateStruct, # options: 2tier, 2tierCPP, PTR, 3tier, 24hourly
		'elasticitySubWOCPP': SubElas, # Substitution elasticty during non-CPP days.
		'elasticityDailyWOCPP': DayElas, # Daily elasticity during non-CPP days.
		'elasticitySubWCPP': SubElas, # Substitution elasticty during CPP days. Only required for 2tierCPP
		'elasticityDailyWCPP': DayElas, # Daily elasticity during non-CPP days. Only reuquired for 2tierCPP
		'startMonth': startmonth, # 1-12. Beginning month of the cooling season when the DR program will run.
		'stopMonth': stopmonth, # 1-12. Ending month of the cooling season when the DR program will run.
		'startHour': starthour, # 0-23. Beginning hour for on-peak and CPP rates.
		'stopHour': stophour, # 0-23. Ending hour for on-peak and CPP rates.
		'rateFlat': retailCost, # pre-DR Time-independent rate paid by residential consumers.
		'rateOffPeak': OffPeakRate,
		'rateOnPeak': PeakRate, # Peak hour rate on non-CPP days.
		'rateCPP': rateCPP, # Peak hour rate on CPP days. Only required for 2tierCPP
		'rate24hourly': rate24hourly, #Hourly energy price, only needed for 24hourly
		'ratePTR': ratePTR, # Only required for PTR. $/kWh payment to customers for demand reduction on PTR days. Value is entered as a positive value, just like the other rate values, even though it is a rebate.
		'numCPPDays': numCPPDays, # Number of CPP days in a cooling season. Only required for 2tierCPP
		'origLoad': demandCurve }) # 8760 load values
	fullParticipationModLoad = allPrismOutput['modLoad']
	modifiedLoad = [x*ManagLoad+y*(1-ManagLoad) for x,y in zip(fullParticipationModLoad,demandCurve)]
	# with open('modifiedLoad.csv', 'wb') as outFile:
	# 	for row in modifiedLoad:
	# 		outfile.write(str(row) + '\n')
	diff = [y-x for x,y in zip(modifiedLoad,demandCurve)]
	# Demand Before and After Program Plot
	outData['modifiedLoad'] = modifiedLoad
	outData['demandLoad'] = demandCurve
	outData['difference'] = diff
	outData['differenceMax'] = round(max(diff),0)
	outData['differenceMin'] = round(min(diff),0)
	# Getting the hourly prices for the whole year (8760 prices)
	ProgPricesArrayYear = ProgramPrices*365
	OneYearwholesaleCost = [wholesaleCost for x in range(8760)]
	AnnualEnergy = sum(demandCurve)
	demandCurveJanuary = max(demandCurve[0:744])
	demandCurveFebruary = max(demandCurve[745:1416])
	demandCurveMarch = max(demandCurve[1417:2160])
	demandCurveApril = max(demandCurve[2161:2880])
	demandCurveMay = max(demandCurve[2881:3624])
	demandCurveJune = max(demandCurve[3625:4344])
	demandCurveJuly = max(demandCurve[4345:5088])
	demandCurveAugust = max(demandCurve[5089:5832])
	demandCurveSeptember = max(demandCurve[5833:6552])
	demandCurveOctober = max(demandCurve[6553:7296])
	demandCurveNovmber = max(demandCurve[6553:7296])
	demandCurveDecember = max(demandCurve[7297:8760])
	maxMontlyDemand = [demandCurveJanuary,demandCurveFebruary,demandCurveMarch,
		demandCurveApril,demandCurveMay,demandCurveJune,demandCurveJuly,
		demandCurveAugust,demandCurveSeptember,demandCurveOctober,
		demandCurveNovmber,demandCurveDecember]
	annualDemandCost = demandCharge * sum(maxMontlyDemand)
	PowerCost = - (AnnualEnergy * wholesaleCost + annualDemandCost)
	# Calculating the maximum montly peaks after applying DR
	modifiedLoadJanuary = max(modifiedLoad[0:744])
	modifiedLoadFebruary = max(modifiedLoad[745:1416])
	modifiedLoadMarch = max(modifiedLoad[1417:2160])
	modifiedLoadApril = max(modifiedLoad[2161:2880])
	modifiedLoadMay = max(modifiedLoad[2881:3624])
	modifiedLoadJune = max(modifiedLoad[3625:4344])
	modifiedLoadJuly = max(modifiedLoad[4345:5088])
	modifiedLoadAugust = max(modifiedLoad[5089:5832])
	modifiedLoadSeptember = max(modifiedLoad[5833:6552])
	modifiedLoadOctober = max(modifiedLoad[6553:7296])
	modifiedLoadNovmber = max(modifiedLoad[6553:7296])
	modifiedLoadDecember = max(modifiedLoad[7297:8760])
	maxMontlyDemandDR = [modifiedLoadJanuary,modifiedLoadFebruary,modifiedLoadMarch,
		modifiedLoadApril,modifiedLoadMay,modifiedLoadJune,modifiedLoadJuly,
		modifiedLoadAugust,modifiedLoadSeptember,modifiedLoadOctober,
		modifiedLoadNovmber,modifiedLoadDecember]
	# Calculating the Base Case Profit
	EnergySale = sum(demandCurve) * retailCost
	EnergyCost = sum(demandCurve) * wholesaleCost
	PeakDemandCharge = sum([x*demandCharge for x in maxMontlyDemand])
	BaseCaseProfit = EnergySale - EnergyCost - PeakDemandCharge
	# Calculating the DR Case Profit
	EnergySaleDR = sum([z[0]*z[1] for z in zip(modifiedLoad,ProgPricesArrayYear)])
	PeakDemandChargeDR = sum([x*demandCharge for x in maxMontlyDemandDR])
	energyCostDR = sum(modifiedLoad) * wholesaleCost
	DRCaseProfit = EnergySaleDR - PeakDemandChargeDR
	# Outputs of First Year Financial Impact table.
	outData["BaseCase"] = [AnnualEnergy, EnergySale, abs(EnergyCost), PeakDemandCharge, 0]
	outData["DRCase"] = [sum(modifiedLoad),EnergySaleDR, abs(energyCostDR), PeakDemandChargeDR, DrTechCost]
	# Calculating the Benefit Cashflow and Total benefit
	energySaleDRyear = [x*y for x,y in zip(ProgPricesArrayYear, demandCurve)]
	oneYearRetail = [retailCost for x in range(8760)]
	energySaleArray = [x*y for x,y in zip(oneYearRetail, demandCurve)]
	energySaleChange = sum(energySaleDRyear) - sum(energySaleArray)
	peakDemandRed = PeakDemandCharge - PeakDemandChargeDR
	# Calculating the Purchase Cost, Operation and Maint. Cost and Total Cost
	outData["AnnualOpCost"] = [- AnnDROM for x in lifeYears[0:]]
	LifetimeOperationCost = (sum(outData["AnnualOpCost"]))
	outData["LifetimeOperationCost"] = abs(LifetimeOperationCost)
	outData["lifePurchaseCosts"] = [-1.0 * DrTechCost] + [0 for x in lifeYears[1:]]
	outData["TotalCost"] = abs(outData["LifetimeOperationCost"] + DrTechCost)
	# Outputs of the Program Lifetime Cash Flow figure
	outData["EnergySaleChangeBenefit"] = [energySaleChange * ScalingAnnual ** x for x in range(lifeSpan)]
	outData["PeakDemandReduction"] = [peakDemandRed * ScalingAnnual ** x for x in range(lifeSpan)]
	BenefitCurve = [x+y for x,y in zip(outData["EnergySaleChangeBenefit"], outData["PeakDemandReduction"])]
	outData["TotalBenefit"] = sum(BenefitCurve)
	outData["BenefittoCostRatio"] = float(outData["TotalBenefit"] / outData["TotalCost"])
	netBenefit = [x+y+z for x,y,z in zip(outData["AnnualOpCost"],outData["lifePurchaseCosts"],BenefitCurve)]
	outData["npv"] = npv(DiscountRate, netBenefit)
	outData["cumulativeNetBenefit"] = [sum(netBenefit[0:i+1]) for i,d in enumerate(netBenefit)]
	outData["SimplePaybackPeriod"] = DrTechCost / (outData["TotalBenefit"] / lifeSpan)
	# Stdout/stderr.
	outData["stdout"] = "Success"
	outData["stderr"] = ""
	return outData
Ejemplo n.º 27
0
def forecastWork(modelDir, ind):
	''' Run the model in its directory.'''

	(cellCapacity, dischargeRate, chargeRate, cellQuantity, cellCost) = \
		[float(ind[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate', 'cellQuantity', 'cellCost')]
	demandCharge = float(ind['demandCharge'])
	retailCost = float(ind['retailCost'])

	battEff	= float(ind.get("batteryEfficiency")) / 100.0
	dodFactor = float(ind.get('dodFactor')) / 100.0
	projYears = int(ind.get('projYears'))
	batteryCycleLife = int(ind.get('batteryCycleLife'))
	battCapacity = cellQuantity * float(ind['cellCapacity']) * dodFactor

	o = {}

	try:
		with open(pJoin(modelDir, 'hist.csv'), 'w') as f:
			f.write(ind['histCurve'].replace('\r', ''))
		df = pd.read_csv(pJoin(modelDir, 'hist.csv'), parse_dates=['dates'])
		df['month'] = df['dates'].dt.month
		df['dayOfYear'] = df['dates'].dt.dayofyear
		assert df.shape[0] >= 26280 # must be longer than 3 years
		assert df.shape[1] == 5
	except:
		raise Exception("CSV file is incorrect format.")

	confidence = float(ind['confidence'])/100

	# ---------------------- MAKE PREDICTIONS ------------------------------- #
	# train model on previous data
	all_X = fc.makeUsefulDf(df)
	all_y = df['load']
	predictions = fc.neural_net_predictions(all_X, all_y)

	dailyLoadPredictions = [predictions[i:i+24] for i in range(0, len(predictions), 24)]	
	weather = df['tempc'][-8760:]
	dailyWeatherPredictions = [weather[i:i+24] for i in range(0, len(weather), 24)]
	month = df['month'][-8760:]

	dispatched = [False]*365
	# decide to implement VBAT every day for a year
	VB_power, VB_energy = [], []
	for i, (load24, temp24, m) in enumerate(zip(dailyLoadPredictions, dailyWeatherPredictions, month)):
		peak = max(load24)
		if fc.shouldDispatchPS(peak, m, df, confidence):
			dispatched[i] = True
			vbp, vbe = fc.pulp24hrBattery(load24, dischargeRate*cellQuantity, 
				cellCapacity*cellQuantity, battEff)
			VB_power.extend(vbp)
			VB_energy.extend(vbe)
		else:
			VB_power.extend([0]*24)
			VB_energy.extend([0]*24)

	# -------------------- MODEL ACCURACY ANALYSIS -------------------------- #
	o['predictedLoad'] = predictions
	o['trainAccuracy'] = 0#round(model.score(X_train, y_train) * 100, 2)
	o['testAccuracy'] = 0#round(model.score(X_test, y_test) * 100, 2)

	# PRECISION AND RECALL
	maxDays = []
	for month in range(1, 13):
		test = df[df['month'] == month]
		maxDays.append(test.loc[test['load'].idxmax()]['dayOfYear'])
	
	shouldHaveDispatched = [False]*365
	for day in maxDays:
		shouldHaveDispatched[day] = True

	truePositive = len([b for b in [i and j for (i, j) in zip(dispatched, shouldHaveDispatched)] if b])
	falsePositive = len([b for b in [i and (not j) for (i, j) in zip(dispatched, shouldHaveDispatched)] if b])
	falseNegative = len([b for b in [(not i) and j for (i, j) in zip(dispatched, shouldHaveDispatched)] if b])
	o['precision'] = round(truePositive / float(truePositive + falsePositive) * 100, 2)
	o['recall'] = round(truePositive / float(truePositive + falseNegative) * 100, 2)
	o['number_of_dispatches'] = len([i for i in dispatched if i])
	o['MAE'] = round(sum([abs(l-m)/m*100 for l, m in zip(predictions, list(all_y[-8760:]))])/8760., 2)

	# ---------------------- FINANCIAL ANALYSIS ----------------------------- #

	# Calculate monthHours
	year = df[-8760:].copy()
	year.reset_index(inplace=True)
	year['hour'] = list(year.index)
	start = list(year.groupby('month').first()['hour'])
	finish = list(year.groupby('month').last()['hour'])
	monthHours = [(s, f+1) for (s, f) in zip(start, finish)]

	demand = list(all_y[-8760:])
	peakDemand = [max(demand[s:f]) for s, f in monthHours] 
	demandAdj = [d+p for d, p in zip(demand, VB_power)]
	peakDemandAdj = [max(demandAdj[s:f]) for s, f in monthHours]
	discharges = [f if f < 0 else 0 for f in VB_power]

	# Monthly Cost Comparison Table
	o['monthlyDemand'] = peakDemand
	o['monthlyDemandRed'] = peakDemandAdj
	o['ps'] = [p-s for p, s in zip(peakDemand, peakDemandAdj)]
	o['benefitMonthly'] = [x*demandCharge for x in o['ps']]
	
	# Demand Before and After Storage Graph
	o['demand'] = demand
	o['demandAfterBattery'] = demandAdj
	o['batteryDischargekW'] = VB_power
	o['batteryDischargekWMax'] = max(VB_power)

	batteryCycleLife = float(ind['batteryCycleLife'])
	# Battery State of Charge Graph
	# Turn dc's SoC into a percentage, with dodFactor considered.

	o['batterySoc'] = SoC = [100 - (e / battCapacity * 100) for e in VB_energy]

	# Estimate number of cyles the battery went through. Sums the percent of SoC.
	cycleEquivalents = sum([SoC[i]-SoC[i+1] for i, x in enumerate(SoC[:-1]) if SoC[i+1] < SoC[i]]) / 100.0
	o['cycleEquivalents'] = cycleEquivalents
	o['batteryLife'] = batteryCycleLife / cycleEquivalents

	# Cash Flow Graph
	# inserting battery efficiency only into the cashflow calculation
	# cashFlowCurve is $ in from peak shaving minus the cost to recharge the battery every day of the year
	cashFlowCurve = [sum(o['ps'])*demandCharge for year in range(projYears)]
	cashFlowCurve.insert(0, -1 * cellCost * cellQuantity)  # insert initial investment
	# simplePayback is also affected by the cost to recharge the battery every day of the year
	o['SPP'] = (cellCost*cellQuantity)/(sum(o['ps'])*demandCharge)
	o['netCashflow'] = cashFlowCurve
	o['cumulativeCashflow'] = [sum(cashFlowCurve[:i+1]) for i, d in enumerate(cashFlowCurve)]
	o['NPV'] = npv(float(ind['discountRate']), cashFlowCurve)

	battCostPerCycle = cellQuantity * cellCost / batteryCycleLife
	lcoeTotCost = cycleEquivalents*retailCost + battCostPerCycle*cycleEquivalents
	o['LCOE'] = lcoeTotCost / (cycleEquivalents*battCapacity)

	# Other
	o['startDate'] = '2011-01-01'  # dc[0]['datetime'].isoformat()
	o['stderr'] = ''
	# Seemingly unimportant. Ask permission to delete.
	o['stdout'] = 'Success' 
	o['months'] = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]

	return o
Ejemplo n.º 28
0
    def __init__(self, 数据, 成本收入索引, 工程费用索引, 工程建设其他费用索引, 基本预备费, 收购费用, 建设投资, 维修费):
        # ==========================
        self.数据 = 数据
        self.成本收入索引 = 成本收入索引
        self.工程费用索引 = 工程费用索引
        self.工程建设其他费用索引 = 工程建设其他费用索引
        self.维修费_全年量 = self.成本收入取值(维修费, self.数据.数据索引['维修费_设定值'])
        self.基本预备费 = 基本预备费
        self.收购费用 = 收购费用

        self.供冷收入_税前 = self.成本收入取值(self.成本收入索引['供冷收入'],
                                   self.数据.数据索引['供冷收入_设定值'])
        self.供蒸汽收入_税前 = self.成本收入取值(self.成本收入索引['蒸汽收入'],
                                    self.数据.数据索引['供蒸汽收入_设定值'])
        self.发电收入_税前 = self.成本收入取值(self.成本收入索引['售电收入'],
                                   self.数据.数据索引['发电收入_设定值'])
        self.供热收入_税前 = self.成本收入取值(self.成本收入索引['供热收入'],
                                   self.数据.数据索引['供热收入_设定值'])
        self.光伏发电收入_税前 = self.成本收入取值(self.成本收入索引['光伏发电收入'],
                                     self.数据.数据索引['光伏发电收入_设定值'])
        self.天然气销售收入_税前 = self.数据.数据索引['额外天然气销售年总收入']
        self.供冷配套费收入_税前 = self.成本收入取值(0, self.数据.数据索引['供冷配套费收入_设定值'])
        self.供热配套费收入_税前 = self.成本收入取值(0, self.数据.数据索引['供冷配套费收入_设定值'])

        self.工资支出_全年量 = self.成本收入索引['工资及福利']
        self.光伏运维成本_全年量 = self.成本收入取值(0, self.数据.数据索引['光伏运维成本_设定值'])
        self.天然气支出_税前 = self.成本收入取值(
            self.成本收入索引['燃气费'] + self.数据.数据索引['额外天然气销售年总成本'],
            self.数据.数据索引['天然气支出_设定值'])
        self.水支出_税前 = self.成本收入取值(self.成本收入索引['水费'], self.数据.数据索引['水支出_设定值'])
        self.电支出_税前 = self.成本收入取值(self.成本收入索引['电费'], self.数据.数据索引['电支出_设定值'])
        self.变压器容量费_税前 = self.数据.数据索引['变压器容量费']
        self.系统备用容量费_税前 = self.数据.数据索引['系统备用容量费']
        self.土地租金_全年量_税前 = self.数据.数据索引['土地租金']
        self.设备租金_全年量_税前 = self.数据.数据索引['设备租金']

        #
        self.建筑费用 = 工程费用索引['工程费用']['建筑']
        self.设备费用 = 工程费用索引['工程费用']['设备']
        self.安装费用 = 工程费用索引['工程费用']['安装']
        self.工程建设其他费用总和 = self.工程建设其他费用索引['工程建设其他费用合计']
        # 土地费用
        self.土地费用 = self.工程建设其他费用索引['土地费']
        self.土地购置费投资 = self.工程建设其他费用索引['土地费']
        self.无形资产投资 = 0

        self.建设投资 = 建设投资
        self.借款 = self.建设投资 * self.数据.数据索引['借款比例']
        self.建设期利息 = self.借款 * self.数据.数据索引['借款利率'] * 1.1 / 2

        # 等于工资一半
        self.其他管理费用_全年量 = self.工资支出_全年量 * self.数据.数据索引['其他管理费用占工资比例']

        self.达产率 = self.数据.数据索引['达产率']

        # ========一级目录==========
        self.现金流入dict = {}
        self.现金流出dict = {}
        self.现金流入 = [0] * 21
        self.现金流出 = [0] * 21

        # ========二级目录=========
        self.销售收入 = {}
        self.补贴收入 = [0] * 21
        self.回收固定资产余值 = 0
        self.回收流动资金 = 0
        self.增值税销项税额 = {}

        self.增值税进项税额 = dict()
        self.增值税 = [0] * 21
        self.流动资金 = {}
        self.经营成本 = {}
        # self.销售税金及附加 = {}
        # self.所得税 = {}
        # self.利用原有固定资产 = {}
        # self.特种基金 = {}

        # ========三级目录=========
        # 销售收入
        self.供冷收入 = [0] * 21
        self.供热收入 = [0] * 21
        self.发电收入 = [0] * 21
        self.光伏发电收入 = [0] * 21
        self.供蒸汽收入 = [0] * 21
        self.天然气销售收入 = [0] * 21
        self.供冷配套费收入 = [0] * 21
        self.供热配套费收入 = [0] * 21
        self.销售收入总和 = [0] * 21

        # 固定资产余值
        self.建筑类固定资产余值 = 0
        self.设备及安装类固定资产余值 = 0
        self.回收固定资产余值 = 0

        # 销项税
        self.供冷收入销项税 = [0] * 21
        self.供蒸汽收入销项税 = [0] * 21
        self.发电收入销项税 = [0] * 21
        self.供热收入销项税 = [0] * 21
        self.光伏发电收入销项税 = [0] * 21
        self.天然气销售收入销项税 = [0] * 21
        self.供冷配套费收入销项税 = [0] * 21
        self.供热配套费收入销项税 = [0] * 21
        self.增值税销项税额总和 = [0] * 21

        # 进项税
        self.天然气支出进项税 = [0] * 21
        self.水支出进项税 = [0] * 21
        self.电支出进项税 = [0] * 21
        self.变压器容量费进项税 = [0] * 21
        self.系统备用容量费进项税 = [0] * 21
        self.增值税进项税额总和 = [0] * 21

        # 增值税
        self.增值税总和 = [0] * 21
        # 销售税金及附加总和
        self.销售税金及附加总和 = [0] * 21

        # 流动资金
        self.应收账款 = [0] * 21
        self.天然气存货 = [0] * 21
        self.电存货 = [0] * 21
        self.水存货 = [0] * 21
        self.现金 = [0] * 21
        self.应付账款 = [0] * 21
        self.流动资金总和 = [0] * 21

        # 经营成本
        self.天然气支出 = [0] * 21
        self.水支出 = [0] * 21
        self.电支出 = [0] * 21
        self.变压器容量费 = [0] * 21
        self.系统备用容量费 = [0] * 21
        self.工资支出 = [0] * 21
        self.光伏运维成本 = [0] * 21
        self.土地租金 = [0] * 21
        self.维修费 = [0] * 21
        self.其他管理费用 = [0] * 21
        self.经营成本总和 = [0] * 21

        # 所得税
        self.利润总和 = [0] * 21
        self.EBIT = [0] * 21
        self.所得税总和 = [0] * 21

        # 折旧费
        self.工程建设其他费用待摊费用 = 0
        self.税后建筑类投资 = 0
        self.税后设备及安装类投资 = 0
        self.建筑类折旧费 = [0] * 21
        self.设备及安装类折旧费 = [0] * 21
        self.无形资产折旧费 = [0] * 21
        self.土地购置费折旧费 = [0] * 21
        self.折旧费 = dict()
        self.折旧费总和 = [0] * 21

        # 财务费用
        self.财务费用 = [0] * 21

        # 成本费用总和
        self.成本费用总和 = [0] * 21

        # 净现金流
        self.税后净现金流量 = [0] * 21
        self.累计税后净现金流量 = [0] * 21

        # ===================计算========================
        self.计算销售收入()
        self.计算销项税()

        self.计算经营成本()
        self.计算进项税()
        self.计算增值税及销售税金及附加()
        self.计算流动资金()
        self.计算折旧费()
        self.计算财务费用()
        self.计算成本费用总和()
        self.计算所得税()

        self.计算回收固定资产余值()
        self.计算回收流动资金()
        self.计算现金流入总和()
        self.计算现金流出总和()
        self.计算税后净现金流量()
        self.计算累计税后净现金流量()

        self.内部收益率 = np.irr(self.税后净现金流量)
        self.计算投资回收期()
        self.年均销售收入 = sum(self.销售收入总和) / 20
        self.年均总成本费用 = sum(self.成本费用总和) / 20
        self.年均利润总额 = sum(self.利润总和) / 20
        self.净现值 = np.npv(0.12, self.税后净现金流量)
        self.生成技经计算结果()
        self.生成技经计算明细列表()

        print('税后净现金流量', self.税后净现金流量)
        print('内部收益率', self.内部收益率)
        print('投资回收期', self.投资回收期)
        print('建设投资', self.建设投资)
        print('年均利润总额', self.年均利润总额)

        print('现金流入', self.现金流入)
        print('销售收入总和', self.销售收入总和)
        print('增值税销项税额总和', self.增值税销项税额总和)

        print('现金流出', self.现金流出)
        print('增值税进项税额总和', self.增值税进项税额总和)
        print('增值税总和', self.增值税总和)
        print('流动资金总和', self.流动资金总和)
        print('经营成本总和', self.经营成本总和)
        print('销售税金及附加总和', self.销售税金及附加总和)
        print('所得税总和', self.所得税总和)

        print('成本费用总和', self.成本费用总和)
        for key, value in self.经营成本.items():
            print(key, value)
        print('折旧费总和', self.折旧费总和)
        print('年均总成本费用', self.年均总成本费用)
        print('财务费用', self.财务费用)
        print('年均销售收入', self.年均销售收入)
        print('利润总和', self.利润总和)
        print('维修费', self.维修费)

        for key, value in self.流动资金.items():
            print(key, value)
Ejemplo n.º 29
0
            firstYearLandLeaseCosts = float(
                inputDict.get("costAcre", 0)) * landAmount
        else:
            firstYearLandLeaseCosts = 0
        for i in range(1, len(outData["allYearGenerationMWh"]) + 1):
            OMInsuranceETCDirect.append(-firstYearOPMainCosts * math.pow((1 + .01), (i - 1)) - firstYearInsuranceCosts * math.pow(
                (1 + .025), (i - 1)) - firstYearLandLeaseCosts * math.pow((1 + .01), (i - 1)))
            distAdderDirect.append(
                float(inputDict.get("distAdder", 0)) * outData["allYearGenerationMWh"][i])
            netCoopPaymentsDirect.append(
                OMInsuranceETCDirect[i - 1] + netFinancingCostsDirect)
            costToCustomerDirect.append(
                (netCoopPaymentsDirect[i - 1] - distAdderDirect[i - 1]))

        # Output - Direct Loan [F53]
        NPVLoanDirect = npv(
            float(inputDict.get("discRate", 0)) / 100, [0, 0] + costToCustomerDirect)
        NPVallYearGenerationMWh = npv(float(inputDict.get(
            "discRate", 0)) / 100, [0, 0] + outData["allYearGenerationMWh"].values())

        Rate_Levelized_Direct = -NPVLoanDirect / NPVallYearGenerationMWh

        # Master Output [Direct Loan]
        outData["levelCostDirect"] = Rate_Levelized_Direct
        outData["costPanelDirect"] = abs(NPVLoanDirect / numberPanels)
        outData["cost10WPanelDirect"] = (
            float(outData["costPanelDirect"]) / panelSize) * 10

        # NCREBs Financing
        ncrebsRate = float(inputDict.get("NCREBRate", 4.060)) / 100
        ncrebBorrowingRate = 1.1 * ncrebsRate
        ncrebPaymentPeriods = 44
Ejemplo n.º 30
0
# 率,不考虑通胀因素。
# mirr函数计算修正后内部收益率(modified internal rate of return),是内部收益率的改进
# 版本。
# nper函数计算定期付款的期数。
# rate函数计算利率(rate of interest)。
print u"终值"
#fv函数参数为利率,参数,每期支付金额,现值
print "Future value",np.fv(0.03/4, 5*4,-10,1000)
print u"现值"
#pv函数参数为利率,参数,每期支付金额,终值
print "Present value",np.pv(0.03/4,5*4,-10,1376.09633204)
#npv参数为利率和一个表示现金流的数组.
cashflows = np.random.randint(100,size=5)
cashflows = np.insert(cashflows,0,-100)
print "Cashflows",cashflows
print "Net present value",np.npv(0.03,cashflows)
print u"内部收益率"
print "Internal rate of return",np.irr([-100, 38, 48,90 ,17,36])

print u"分期付款"
#pmt输入为利率和期数,总价,输出每期钱数
print "Payment",np.pmt(0.10/12,12*30,100000)
#nper参数为贷款利率,固定的月供和贷款额,输出付款期数
print "Number of payments", np.nper(0.10/12,-100,9000)
#rate参数为付款期数,每期付款资金,现值和终值计算利率
print "Interest rate",12*np.rate(167,-100,9000,0)

print u"窗函数"
#bartlett函数可以计算巴特利特窗
window = np.bartlett(42)
print "bartlett",window
Ejemplo n.º 31
0
def workForecast(modelDir, ind):
	''' Run the model in its directory.'''
	o = {}

	# Grab data from CSV, 
	try:
		with open(pJoin(modelDir, 'hist.csv'), 'w') as f:
			f.write(ind['histCurve'].replace('\r', ''))
		df = pd.read_csv(pJoin(modelDir, 'hist.csv'), parse_dates=['dates'])
		df['month'] = df['dates'].dt.month
		df['dayOfYear'] = df['dates'].dt.dayofyear
		assert df.shape[0] >= 26280 # must be longer than 3 years
		assert df.shape[1] == 5
	except:
		raise Exception("CSV file is incorrect format.")

	# train model on previous data
	all_X = fc.makeUsefulDf(df)
	all_y = df['load']
	X_train, y_train = all_X[:-8760], all_y[:-8760]
	clf = linear_model.SGDRegressor(max_iter=10000, tol=1e-4)
	clf.fit(X_train, y_train)

	# ---------------------- MAKE PREDICTIONS ------------------------------- #
	X_test, y_test = all_X[-8760:], all_y[-8760:]
	predictions = clf.predict(X_test)
	dailyLoadPredictions = [predictions[i:i+24] for i in range(0, len(predictions), 24)]
	
	P_lower, P_upper, E_UL = vbat24hr(ind, df['tempc'][-8760:])
	dailyPl = [P_lower[i:i+24] for i in range(0, len(P_lower), 24)]
	dailyPu = [P_upper[i:i+24] for i in range(0, len(P_upper), 24)]
	dailyEu = [E_UL[i:i+24] for i in range(0, len(E_UL), 24)]
	
	vbp, vbe = [], []
	dispatched_d = [False]*365
	# Decide what days to dispatch
	zipped = zip(dailyLoadPredictions, df['month'][-8760:], dailyPl, dailyPu, dailyEu)
	for i, (load, m, pl, pu, eu) in enumerate(zipped):
		peak = max(load)
		if fc.shouldDispatchPS(peak, m, df, float(ind['confidence'])/100):
			dispatched_d[i] = True
			p, e = fc.pulp24hrVbat(ind, load, pl, pu, eu)
			vbp.extend(p)
			vbe.extend(e)
		else:
			vbp.extend([0]*24)
			vbe.extend([0]*24)

	### TESTING FOR ACCURACY ###
	assert len(dailyPl) == 365
	assert all([len(i) == 24 for i in dailyPl])

	VB_power, VB_energy = vbp, vbe

	# -------------------- MODEL ACCURACY ANALYSIS -------------------------- #

	o['predictedLoad'] = list(clf.predict(X_test))
	o['trainAccuracy'] = round(clf.score(X_train, y_train) * 100, 2)
	o['testAccuracy'] = round(clf.score(X_test, y_test) * 100, 2)

	# PRECISION AND RECALL
	maxDays = []
	for month in range(1, 13):
		test = df[df['month'] == month]
		maxDays.append(test.loc[test['load'].idxmax()]['dayOfYear'])
	
	shouldHaveDispatched = [False]*365
	for day in maxDays:
		shouldHaveDispatched[day] = True

	truePositive = len([b for b in [i and j for (i, j) in zip(dispatched_d, shouldHaveDispatched)] if b])
	falsePositive = len([b for b in [i and (not j) for (i, j) in zip(dispatched_d, shouldHaveDispatched)] if b])
	falseNegative = len([b for b in [(not i) and j for (i, j) in zip(dispatched_d, shouldHaveDispatched)] if b])
	o['confidence'] = ind['confidence']
	o['precision'] = round(truePositive / float(truePositive + falsePositive) * 100, 2)
	o['recall'] = round(truePositive / float(truePositive + falseNegative) * 100, 2)
	o['number_of_dispatches'] = len([i for i in dispatched_d if i])
	o['MAE'] = round(sum([abs(l-m)/m*100 for l, m in zip(predictions, list(y_test))])/8760., 2)

	# ---------------------- FINANCIAL ANALYSIS ----------------------------- #

	o['VBpower'], o['VBenergy'] = list(VB_power), list(VB_energy)

	# Calculate monthHours
	year = df[-8760:].copy()
	year.reset_index(inplace=True)
	year['hour'] = list(year.index)
	start = list(year.groupby('month').first()['hour'])
	finish = list(year.groupby('month').last()['hour'])
	monthHours = [(s, f+1) for (s, f) in zip(start, finish)]

	demand = list(y_test)
	peakDemand = [max(demand[s:f]) for s, f in monthHours] 
	energyMonthly = [sum(demand[s:f]) for s, f in monthHours]
	demandAdj = [d+p for d, p in zip(demand, o['VBpower'])]
	peakAdjustedDemand = [max(demandAdj[s:f]) for s, f in monthHours]
	energyAdjustedMonthly = [sum(demandAdj[s:f]) for s, f in monthHours]

	o['demand'] = demand
	o['peakDemand'] = peakDemand
	o['energyMonthly'] = energyMonthly
	o['demandAdjusted'] = demandAdj
	o['peakAdjustedDemand'] = peakAdjustedDemand
	o['energyAdjustedMonthly'] = energyAdjustedMonthly
	
	cellCost = float(ind['unitDeviceCost'])*float(ind['number_devices'])
	eCost = float(ind['electricityCost'])
	dCharge = float(ind['demandChargeCost'])

	o['VBdispatch'] = [dal-d for dal, d in zip(demandAdj, demand)]
	o['energyCost'] = [em*eCost for em in energyMonthly]
	o['energyCostAdjusted'] = [eam*eCost for eam in energyAdjustedMonthly]
	o['demandCharge'] = [peak*dCharge for peak in peakDemand]
	o['demandChargeAdjusted'] = [pad*dCharge for pad in o['peakAdjustedDemand']]
	o['totalCost'] = [ec+dcm for ec, dcm in zip(o['energyCost'], o['demandCharge'])]
	o['totalCostAdjusted'] = [eca+dca for eca, dca in zip(o['energyCostAdjusted'], o['demandChargeAdjusted'])]
	o['savings'] = [tot-tota for tot, tota in zip(o['totalCost'], o['totalCostAdjusted'])]

	annualEarnings = sum(o['savings']) - float(ind['unitUpkeepCost'])*float(ind['number_devices'])
	cashFlowList = [annualEarnings] * int(ind['projectionLength'])
	cashFlowList.insert(0, -1*cellCost)

	o['NPV'] = np.npv(float(ind['discountRate'])/100, cashFlowList)
	o['SPP'] = cellCost / annualEarnings
	o['netCashflow'] = cashFlowList
	o['cumulativeCashflow'] = [sum(cashFlowList[:i+1]) for i, d in enumerate(cashFlowList)]
	
	o['stdout'] = 'Success'
	return o
Ejemplo n.º 32
0
		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)])
Ejemplo n.º 33
0
 def value_can_afford(monthly_payment):
     # this is a 10 year average freddie mac interest rate
     ten_year_average_interest = .055
     return np.npv(ten_year_average_interest/12, [monthly_payment]*30*12)
Ejemplo n.º 34
0
def work(modelDir, ind):
	#print(ind)
	''' Run the model in its directory.'''
	# drop inverter efficiency
	# drop DoD
	(cellCapacity, dischargeRate, chargeRate, cellQuantity, cellCost) = \
		[float(ind[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate', 'cellQuantity', 'cellCost')]
	battEff	= float(ind.get("batteryEfficiency")) / 100.0
	dodFactor = float(ind.get('dodFactor')) / 100.0
	projYears = int(ind.get('projectionLength'))
	batteryCycleLife = int(ind.get('batteryCycleLife'))

	o = {}

	try:
		with open(pJoin(modelDir, 'hist.csv'), 'w') as f:
			f.write(ind['historicalData'])#.replace('\r', ''))
		df = pd.read_csv(pJoin(modelDir, 'hist.csv'), parse_dates=['dates'])
		df['month'] = df['dates'].dt.month
		df['dayOfYear'] = df['dates'].dt.dayofyear
		assert df.shape[0] >= 26280 # must be longer than 3 years
		assert df.shape[1] == 5
	except ZeroDivisionError:
		raise Exception("CSV file is incorrect format.")

	# retrieve goal
	goal = ind['goal']
	threshold = float(ind['transformerThreshold'])*1000
	confidence = float(ind['confidence'])/100

	# train model on previous data
	all_X = fc.makeUsefulDf(df)
	all_y = df['load']
	X_train, y_train = all_X[:-8760], all_y[:-8760]
	clf = linear_model.SGDRegressor(max_iter=10000, tol=1e-4)
	clf.fit(X_train, y_train)

	# ---------------------- MAKE PREDICTIONS ------------------------------- #
	X_test, y_test = all_X[-8760:], all_y[-8760:]

	# Collect data necessary for dispatch calculations
	predictions = clf.predict(X_test)
	dailyLoadPredictions = [predictions[i:i+24] for i in range(0, len(predictions), 24)]	
	weather = df['tempc'][-8760:]
	dailyWeatherPredictions = [weather[i:i+24] for i in range(0, len(weather), 24)]
	month = df['month'][-8760:]

	dispatched = [False]*365
	# decide to implement VBAT every day for a year
	VB_power, VB_energy = [], []
	for i, (load24, temp24, m) in enumerate(zip(dailyLoadPredictions, dailyWeatherPredictions, month)):
		peak = max(load24)
		if fc.shouldDispatchDeferral(peak, df, confidence, threshold):
			dispatched[i] = True
			vbp, vbe = fc.pulp24hrBattery(load24, dischargeRate*cellQuantity, 
				cellCapacity*cellQuantity, battEff)
			VB_power.extend(vbp)
			VB_energy.extend(vbe)
		else:
			VB_power.extend([0]*24)
			VB_energy.extend([0]*24)

	# -------------------- MODEL ACCURACY ANALYSIS -------------------------- #

	o['predictedLoad'] = list(clf.predict(X_test))
	o['trainAccuracy'] = round(clf.score(X_train, y_train) * 100, 2)
	o['testAccuracy'] = round(clf.score(X_test, y_test) * 100, 2)

	# PRECISION AND RECALL
	maxDays = []
	for month in range(1, 13):
		test = df[df['month'] == month]
		maxDays.append(test.loc[test['load'].idxmax()]['dayOfYear'])
	
	shouldHaveDispatched = [False]*365
	for day in maxDays:
		shouldHaveDispatched[day] = True

	truePositive = len([b for b in [i and j for (i, j) in zip(dispatched, shouldHaveDispatched)] if b])
	falsePositive = len([b for b in [i and (not j) for (i, j) in zip(dispatched, shouldHaveDispatched)] if b])
	falseNegative = len([b for b in [(not i) and j for (i, j) in zip(dispatched, shouldHaveDispatched)] if b])
	o['precision'] = round(truePositive / float(truePositive + falsePositive) * 100, 2)
	o['recall'] = round(truePositive / float(truePositive + falseNegative) * 100, 2)
	o['number_of_dispatches'] = len([i for i in dispatched if i])
	o['MAE'] = round(sum([abs(l-m)/m*100 for l, m in zip(predictions, list(y_test))])/8760., 2)

	# ---------------------- FINANCIAL ANALYSIS ----------------------------- #

	o['VBpower'], o['VBenergy'] = list(VB_power), list(VB_energy)

	# Calculate monthHours
	year = df[-8760:].copy()
	year.reset_index(inplace=True)
	year['hour'] = list(year.index)
	start = list(year.groupby('month').first()['hour'])
	finish = list(year.groupby('month').last()['hour'])
	monthHours = [(s, f+1) for (s, f) in zip(start, finish)]

	demand = list(y_test)
	peakDemand = [max(demand[s:f]) for s, f in monthHours] 
	energyMonthly = [sum(demand[s:f]) for s, f in monthHours]
	demandAdj = [d+p for d, p in zip(demand, o['VBpower'])]
	peakAdjustedDemand = [max(demandAdj[s:f]) for s, f in monthHours]
	energyAdjustedMonthly = [sum(demandAdj[s:f]) for s, f in monthHours]

	o['demand'] = demand
	o['peakDemand'] = peakDemand
	o['energyMonthly'] = energyMonthly
	o['demandAdjusted'] = demandAdj
	o['peakAdjustedDemand'] = peakAdjustedDemand
	o['energyAdjustedMonthly'] = energyAdjustedMonthly
	
	initInvestment = cellCost*cellQuantity
	eCost = float(ind['electricityCost'])
	dCharge = float(ind['demandChargeCost'])

	o['VBdispatch'] = [dal-d for dal, d in zip(demandAdj, demand)]
	o['energyCost'] = [em*eCost for em in energyMonthly]
	o['energyCostAdjusted'] = [eam*eCost for eam in energyAdjustedMonthly]
	o['demandCharge'] = [peak*dCharge for peak in peakDemand]
	o['demandChargeAdjusted'] = [pad*dCharge for pad in o['peakAdjustedDemand']]
	o['totalCost'] = [ec+dcm for ec, dcm in zip(o['energyCost'], o['demandCharge'])]
	o['totalCostAdjusted'] = [eca+dca for eca, dca in zip(o['energyCostAdjusted'], o['demandChargeAdjusted'])]
	o['savings'] = [tot-tota for tot, tota in zip(o['totalCost'], o['totalCostAdjusted'])]

	annualEarnings = sum(o['savings']) # - something!
	cashFlowList = [annualEarnings] * int(ind['projectionLength'])
	cashFlowList.insert(0, -1*initInvestment)

	o['NPV'] = np.npv(float(ind['discountRate'])/100, cashFlowList)
	o['SPP'] = initInvestment / annualEarnings
	o['netCashflow'] = cashFlowList
	o['cumulativeCashflow'] = [sum(cashFlowList[:i+1]) for i, d in enumerate(cashFlowList)]

	o['dataCheck'] = 'Threshold exceeded' if any([threshold > i for i in demandAdj]) and goal == 'deferral' else ''
	o['transformerThreshold'] = threshold if goal == 'deferral' else None

	o['stdout'] = 'Success'
	return o
Ejemplo n.º 35
0
import numpy as np

cashflows = [-45.45, 50]
npv = np.npv(0.1, cashflows)
print(round(50 / (1 + 0.1), 2))
print(round(npv, 2))
Ejemplo n.º 36
0
def work(modelDir, inputDict):
    ''' Run the model in its directory. '''
    #Set static input data
    simLength = 8760
    simStartDate = "2013-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"
    simLengthUnits = "hours"
    # Associate zipcode to climate data
    inputDict["climateName"] = omf.weather.zipCodeToClimateName(
        inputDict["zipCode"])
    inverterSizeAC = float(inputDict.get("inverterSize", 0))
    if (inputDict.get("systemSize", 0) == "-"):
        arraySizeDC = 1.3908 * inverterSizeAC
    else:
        arraySizeDC = float(inputDict.get("systemSize", 0))
    numberPanels = (arraySizeDC * 1000 / 305)
    # Set constants
    panelSize = 305
    trackingMode = 0
    rotlim = 45.0
    gamma = 0.45
    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))
    numberInverters = math.ceil(inverterSizeAC / 1000 / 0.5)
    # Copy specific climate data into model directory
    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, b'file_name',
                            bytes(modelDir + '/climate.tmy2', 'ascii'))
    ssc.ssc_data_set_number(dat, b'system_size', arraySizeDC)
    ssc.ssc_data_set_number(
        dat, b'derate',
        float(inputDict.get('inverterEfficiency', 96)) / 100 *
        float(inputDict.get('nonInverterEfficiency', 87)) / 100)
    ssc.ssc_data_set_number(dat, b'track_mode', float(trackingMode))
    ssc.ssc_data_set_number(dat, b'azimuth',
                            float(inputDict.get('azimuth', 180)))
    # Advanced inputs with defaults.
    ssc.ssc_data_set_number(dat, b'rotlim', float(rotlim))
    ssc.ssc_data_set_number(dat, b'gamma', float(-gamma / 100))
    ssc.ssc_data_set_number(dat, b'tilt', manualTilt)
    ssc.ssc_data_set_number(dat, b'tilt_eq_lat', 0.0)
    # Run PV system simulation.
    mod = ssc.ssc_module_create(b'pvwattsv1')
    ssc.ssc_module_exec(mod, dat)
    # 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(simLength)
    ]
    # Geodata output.
    outData["minLandSize"] = round(
        (arraySizeDC / 1390.8 * 5 + 1) * math.cos(math.radians(22.5)) /
        math.cos(math.radians(30.0)), 0)
    landAmount = float(inputDict.get("landAmount", 6.0))
    outData['city'] = ssc.ssc_data_get_string(dat, b'city').decode()
    outData['state'] = ssc.ssc_data_get_string(dat, b'state').decode()
    outData['lat'] = ssc.ssc_data_get_number(dat, b'lat')
    outData['lon'] = ssc.ssc_data_get_number(dat, b'lon')
    outData['elev'] = ssc.ssc_data_get_number(dat, b'elev')
    # Weather output.
    outData['climate'] = {}
    outData['climate'][
        'Global Horizontal Radiation (W/m^2)'] = ssc.ssc_data_get_array(
            dat, b'gh')
    outData['climate'][
        'Plane of Array Irradiance (W/m^2)'] = ssc.ssc_data_get_array(
            dat, b'poa')
    outData['climate']['Ambient Temperature (F)'] = ssc.ssc_data_get_array(
        dat, b'tamb')
    outData['climate']['Cell Temperature (F)'] = ssc.ssc_data_get_array(
        dat, b'tcell')
    outData['climate']['Wind Speed (m/s)'] = ssc.ssc_data_get_array(
        dat, b'wspd')
    # Power generation.
    outData['powerOutputAc'] = ssc.ssc_data_get_array(dat, b'ac')
    # Calculate clipping.
    outData['powerOutputAc'] = ssc.ssc_data_get_array(dat, b'ac')
    invSizeWatts = inverterSizeAC * 1000
    outData["powerOutputAcInvClipped"] = [
        x if x < invSizeWatts else invSizeWatts
        for x in outData["powerOutputAc"]
    ]
    try:
        outData["percentClipped"] = 100 * (
            1.0 - sum(outData["powerOutputAcInvClipped"]) /
            sum(outData["powerOutputAc"]))
    except ZeroDivisionError:
        outData["percentClipped"] = 0.0
    #One year generation
    outData["oneYearGenerationWh"] = sum(outData["powerOutputAcInvClipped"])
    #Annual generation for all years
    loanYears = 25
    outData["allYearGenerationMWh"] = {}
    outData["allYearGenerationMWh"][1] = float(
        outData["oneYearGenerationWh"]) / 1000000
    # outData["allYearGenerationMWh"][1] = float(2019.576)
    for i in range(2, loanYears + 1):
        outData["allYearGenerationMWh"][i] = float(
            outData["allYearGenerationMWh"][i - 1]) * (
                1 - float(inputDict.get("degradation", 0.8)) / 100)
    # Summary of Results.
    ######
    ### Total Costs (sum of): Hardware Costs, Design/Engineering/PM/EPC/Labor Costs, Siteprep Costs, Construction Costs, Installation Costs, Land Costs
    ######
    ### Hardware Costs
    pvModules = arraySizeDC * float(inputDict.get("moduleCost",
                                                  0)) * 1000  #off by 4000
    racking = arraySizeDC * float(inputDict.get("rackCost", 0)) * 1000
    inverters = numberInverters * float(inputDict.get("inverterCost", 0))
    inverterSize = inverterSizeAC
    if (inverterSize <= 250):
        gear = 15000
    elif (inverterSize <= 600):
        gear = 18000
    else:
        gear = inverterSize / 1000 * 22000
    balance = inverterSizeAC * 1.3908 * 134
    combiners = math.ceil(numberPanels / 19 / 24) * float(1800)  #*
    wireManagement = arraySizeDC * 1.5
    transformer = 1 * 28000
    weatherStation = 1 * 12500
    shipping = 1.02
    hardwareCosts = (pvModules + racking + inverters + gear + balance +
                     combiners + wireManagement + transformer +
                     weatherStation) * shipping
    ### Design/Engineering/PM/EPC/Labor Costs
    EPCmarkup = float(inputDict.get("EPCRate", 0)) / 100 * hardwareCosts
    #designCosts = float(inputDict.get("mechLabor",0))*160 + float(inputDict.get("elecLabor",0))*75 + float(inputDict.get("pmCost",0)) + EPCmarkup
    hoursDesign = 160 * math.sqrt(arraySizeDC / 1390)
    hoursElectrical = 80 * math.sqrt(arraySizeDC / 1391)
    designLabor = 65 * hoursDesign
    electricalLabor = 75 * hoursElectrical
    laborDesign = designLabor + electricalLabor + float(
        inputDict.get("pmCost", 0)) + EPCmarkup
    materialDesign = 0
    designCosts = materialDesign + laborDesign
    ### Siteprep Costs
    surveying = 2.25 * 4 * math.sqrt(landAmount * 43560)
    concrete = 8000 * math.ceil(numberInverters / 2)
    fencing = 6.75 * 4 * math.sqrt(landAmount * 43560)
    grading = 2.5 * 4 * math.sqrt(landAmount * 43560)
    landscaping = 750 * landAmount
    siteMaterial = 8000 + 600 + 5500 + 5000 + surveying + concrete + fencing + grading + landscaping + 5600
    blueprints = float(inputDict.get("mechLabor", 0)) * 12
    mobilization = float(inputDict.get("mechLabor", 0)) * 208
    mobilizationMaterial = float(inputDict.get("mechLabor", 0)) * 19.98
    siteLabor = blueprints + mobilization + mobilizationMaterial
    sitePrep = siteMaterial + siteLabor
    ### Construction Costs (Office Trailer, Skid Steer, Storage Containers, etc)
    constrEquip = 6000 + math.sqrt(landAmount) * 16200
    ### Installation Costs
    moduleAndRackingInstall = numberPanels * (15.00 + 12.50 + 1.50)
    pierDriving = 1 * arraySizeDC * 20
    balanceInstall = 1 * arraySizeDC * 100
    installCosts = moduleAndRackingInstall + pierDriving + balanceInstall + float(
        inputDict.get("elecLabor", 0)) * (72 + 60 + 70 + 10 + 5 + 30 + 70)
    ### Land Costs
    if (str(inputDict.get("landOwnership", 0)) == "Owned"
            or (str(inputDict.get("landOwnership", 0)) == "Leased")):
        landCosts = 0
    else:
        landCosts = float(inputDict.get("costAcre", 0)) * landAmount
    ######
    ### Total Costs
    ######
    totalCosts = hardwareCosts + designCosts + sitePrep + constrEquip + installCosts + landCosts
    totalFees = float(inputDict.get("devCost", 0)) / 100 * totalCosts
    outData["totalCost"] = totalCosts + totalFees + float(
        inputDict.get("interCost", 0))
    # Add to Pie Chart
    outData["costsPieChart"] = [
        ["Land", landCosts], ["Design/Engineering/PM/EPC", designCosts],
        ["PV Modules", pvModules * shipping], ["Racking", racking * shipping],
        ["Inverters & Switchgear", (inverters + gear) * shipping],
        [
            "BOS", hardwareCosts - pvModules * shipping - racking * shipping -
            (inverters + gear) * shipping
        ],
        [
            "Site Prep, Constr. Eq. and Installation",
            (siteMaterial + constrEquip) + (siteLabor + installCosts)
        ]
    ]
    # Cost per Wdc
    outData["costWdc"] = (totalCosts + totalFees + float(
        inputDict.get("interCost", 0))) / (arraySizeDC * 1000)
    outData["capFactor"] = float(outData["oneYearGenerationWh"]) / (
        inverterSizeAC * 1000 * 365.25 * 24) * 100
    ######
    ### Loans calculations for Direct, NCREB, Lease, Tax-equity, and PPA
    ######
    ### Full Ownership, Direct Loan
    #Output - Direct Loan [C]
    projectCostsDirect = 0
    #Output - Direct Loan [D]
    netFinancingCostsDirect = 0
    #Output - Direct Loan [E]
    OMInsuranceETCDirect = []
    #Output - Direct Loan [F]
    distAdderDirect = []
    #Output - Direct Loan [G]
    netCoopPaymentsDirect = []
    #Output - Direct Loan [H]
    costToCustomerDirect = []
    #Output - Direct Loan [F53]
    Rate_Levelized_Direct = 0
    ## Output - Direct Loan Formulas
    projectCostsDirect = 0
    #Output - Direct Loan [D]
    payment = pmt(
        float(inputDict.get("loanRate", 0)) / 100, loanYears,
        outData["totalCost"])
    interestDirectPI = outData["totalCost"] * float(
        inputDict.get("loanRate", 0)) / 100
    principleDirectPI = (-payment - interestDirectPI)
    patronageCapitalRetiredDPI = 0
    netFinancingCostsDirect = -(principleDirectPI + interestDirectPI -
                                patronageCapitalRetiredDPI)
    #Output - Direct Loan [E] [F] [G] [H]
    firstYearOPMainCosts = (1.25 * arraySizeDC * 12)
    firstYearInsuranceCosts = (0.37 * outData["totalCost"] / 100)
    if (inputDict.get("landOwnership", 0) == "Leased"):
        firstYearLandLeaseCosts = float(inputDict.get("costAcre",
                                                      0)) * landAmount
    else:
        firstYearLandLeaseCosts = 0
    for i in range(1, len(outData["allYearGenerationMWh"]) + 1):
        OMInsuranceETCDirect.append(
            -firstYearOPMainCosts * math.pow((1 + .01), (i - 1)) -
            firstYearInsuranceCosts * math.pow((1 + .025), (i - 1)) -
            firstYearLandLeaseCosts * math.pow((1 + .01), (i - 1)))
        distAdderDirect.append(
            float(inputDict.get("distAdder", 0)) *
            outData["allYearGenerationMWh"][i])
        netCoopPaymentsDirect.append(OMInsuranceETCDirect[i - 1] +
                                     netFinancingCostsDirect)
        costToCustomerDirect.append(
            (netCoopPaymentsDirect[i - 1] - distAdderDirect[i - 1]))
    #Output - Direct Loan [F53]
    NPVLoanDirect = npv(
        float(inputDict.get("discRate", 0)) / 100,
        [0, 0] + costToCustomerDirect)
    NPVallYearGenerationMWh = npv(
        float(inputDict.get("discRate", 0)) / 100,
        [0, 0] + list(outData["allYearGenerationMWh"].values()))
    Rate_Levelized_Direct = -NPVLoanDirect / NPVallYearGenerationMWh
    #Master Output [Direct Loan]
    outData["levelCostDirect"] = Rate_Levelized_Direct
    outData["costPanelDirect"] = abs(NPVLoanDirect / numberPanels)
    outData["cost10WPanelDirect"] = (float(outData["costPanelDirect"]) /
                                     panelSize) * 10
    ### NCREBs Financing
    ncrebsRate = float(inputDict.get("NCREBRate", 4.060)) / 100
    ncrebBorrowingRate = 1.1 * ncrebsRate
    ncrebPaymentPeriods = 44
    ncrebCostToCustomer = []
    # TODO ASAP: FIX ARRAY OFFSETS START 0
    for i in range(1, len(outData["allYearGenerationMWh"]) + 1):
        coopLoanPayment = 2 * pmt(
            ncrebBorrowingRate / 2.0, ncrebPaymentPeriods,
            outData["totalCost"]) if i <= ncrebPaymentPeriods / 2 else 0
        ncrebsCredit = -0.7 * (
            ipmt(ncrebsRate / 2, 2 * i -
                 1, ncrebPaymentPeriods, outData["totalCost"]) +
            ipmt(ncrebsRate / 2, 2 * i, ncrebPaymentPeriods,
                 outData["totalCost"])) if i <= ncrebPaymentPeriods / 2 else 0
        financingCost = ncrebsCredit + coopLoanPayment
        omCost = OMInsuranceETCDirect[i - 1]
        netCoopPayments = financingCost + omCost
        distrAdder = distAdderDirect[i - 1]
        costToCustomer = netCoopPayments + distrAdder
        ncrebCostToCustomer.append(costToCustomer)
    NPVLoanNCREB = npv(
        float(inputDict.get("discRate", 0)) / 100,
        [0, 0] + ncrebCostToCustomer)
    Rate_Levelized_NCREB = -NPVLoanNCREB / NPVallYearGenerationMWh
    outData["levelCostNCREB"] = Rate_Levelized_NCREB
    outData["costPanelNCREB"] = abs(NPVLoanNCREB / numberPanels)
    outData["cost10WPanelNCREB"] = (float(outData["costPanelNCREB"]) /
                                    panelSize) * 10
    ### Lease Buyback Structure
    #Output - Lease [C]
    projectCostsLease = outData["totalCost"]
    #Output - Lease [D]
    leasePaymentsLease = []
    #Output - Lease [E]
    OMInsuranceETCLease = OMInsuranceETCDirect
    #Output - Lease [F]
    distAdderLease = distAdderDirect
    #Output - Lease [G]
    netCoopPaymentsLease = []
    #Output - Lease [H]
    costToCustomerLease = []
    #Output - Lease [H44]
    NPVLease = 0
    #Output - Lease [H49]
    Rate_Levelized_Lease = 0
    ## Tax Lease Formulas
    #Output - Lease [D]
    for i in range(0, 12):
        leaseRate = float(inputDict.get("taxLeaseRate", 0)) / 100.0
        if i > 8:  # Special behavior in later years:
            leaseRate = leaseRate - 0.0261
        leasePaymentsLease.append(-1 * projectCostsLease /
                                  ((1.0 - (1.0 / (1.0 + leaseRate)**12)) /
                                   (leaseRate)))
    # Last year is different.
    leasePaymentsLease[11] += -0.2 * projectCostsLease
    for i in range(12, 25):
        leasePaymentsLease.append(0)
    #Output - Lease [G]	[H]
    for i in range(1, len(outData["allYearGenerationMWh"]) + 1):
        netCoopPaymentsLease.append(OMInsuranceETCLease[i - 1] +
                                    leasePaymentsLease[i - 1])
        costToCustomerLease.append(netCoopPaymentsLease[i - 1] -
                                   distAdderLease[i - 1])
    #Output - Lease [H44]. Note the extra year at the zero point to get the discounting right.
    NPVLease = npv(
        float(inputDict.get("discRate", 0)) / 100,
        [0, 0] + costToCustomerLease)
    #Output - Lease [H49] (Levelized Cost Three Loops)
    Rate_Levelized_Lease = -NPVLease / NPVallYearGenerationMWh
    #Master Output [Lease]
    outData["levelCostTaxLease"] = Rate_Levelized_Lease
    outData["costPanelTaxLease"] = abs(NPVLease / numberPanels)
    outData["cost10WPanelTaxLease"] = (float(outData["costPanelTaxLease"]) /
                                       float(panelSize)) * 10

    ### Tax Equity Flip Structure
    # Tax Equity Flip Function
    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

    # Function Calls Mega Sized Tax Equity Function Above
    z = 0
    PPARateSixYearsTE = z / 100
    nGoal = float(inputDict.get("taxEquityReturn", 0)) / 100
    nValue = 0
    for p in range(0, 3):
        while ((z < 50000) and (nValue < nGoal)):
            achievedReturnTE, Rate_Levelized_TaxEquity, NPVLoanTaxEquity = taxEquityFlip(
                PPARateSixYearsTE, inputDict.get("discRate", 0),
                outData["totalCost"], outData["allYearGenerationMWh"],
                distAdderDirect, loanYears, firstYearLandLeaseCosts,
                firstYearOPMainCosts, firstYearInsuranceCosts, numberPanels)
            nValue = achievedReturnTE
            z = z + math.pow(10, p)
            PPARateSixYearsTE = z / 100.0
    z = z - math.pow(10, p)
    PPARateSixYearsTE = z / 100
    #Master Output [Tax Equity]
    outData["levelCostTaxEquity"] = Rate_Levelized_TaxEquity
    outData["costPanelTaxEquity"] = abs(NPVLoanTaxEquity / numberPanels)
    outData["cost10WPanelTaxEquity"] = (float(outData["costPanelTaxEquity"]) /
                                        panelSize) * 10
    ### PPA Comparison
    #Output - PPA [F]
    distAdderPPA = distAdderDirect
    #Output - PPA [G]
    netCoopPaymentsPPA = []
    #Output - PPA [H]
    costToCustomerPPA = []
    #Output - PPA [I]
    costToCustomerPPA = []
    #Output - PPA [H40]
    NPVLoanPPA = 0
    #Output - PPA [I40]
    Rate_Levelized_PPA = 0
    ## PPA Formulas
    #Output - PPA [G] [H]
    for i in range(1, len(outData["allYearGenerationMWh"]) + 1):
        netCoopPaymentsPPA.append(
            -outData["allYearGenerationMWh"][i] *
            float(inputDict.get("firstYearEnergyCostPPA", 0)) * math.pow(
                (1 + float(inputDict.get("annualEscRatePPA", 0)) / 100),
                (i - 1)))
        costToCustomerPPA.append(netCoopPaymentsPPA[i - 1] -
                                 distAdderPPA[i - 1])
    #Output - PPA [H58]
    NPVLoanPPA = npv(
        float(inputDict.get("discRate", 0)) / 100, [0, 0] + costToCustomerPPA)
    #Output - PPA [F65]
    Rate_Levelized_PPA = -NPVLoanPPA / NPVallYearGenerationMWh
    #Master Output [PPA]
    outData["levelCostPPA"] = Rate_Levelized_PPA
    outData["firstYearCostKWhPPA"] = float(
        inputDict.get("firstYearEnergyCostPPA", 0))
    outData["yearlyEscalationPPA"] = float(inputDict.get(
        "annualEscRatePPA", 0))
    # Add all Levelized Costs to Output
    outData["LevelizedCosts"] = [["Direct Loan", Rate_Levelized_Direct],
                                 ["NCREBs Financing", Rate_Levelized_NCREB],
                                 ["Lease Buyback", Rate_Levelized_Lease],
                                 ["Tax Equity Flip", Rate_Levelized_TaxEquity]]
    outData["LevelizedCosts"].append({
        "name": "PPA Comparison",
        "y": Rate_Levelized_PPA,
        "color": "gold"
    })
    # Stdout/stderr.
    outData["stdout"] = "Success"
    outData["stderr"] = ""
    return outData
def heavyProcessing(modelDir, inputDict):
	''' Run the model in a separate process. web.py calls this to run the model.
	This function will return fast, but results take a while to hit the file system.'''
	# Delete output file every run if it exists
	try:
		# Ready to run.
		startTime = datetime.datetime.now()
		outData = {}
		# Get variables.
		cellCapacity = float(inputDict['cellCapacity'])
		(cellCapacity, dischargeRate, chargeRate, cellQuantity, demandCharge, cellCost) = \
			[float(inputDict[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate', 'cellQuantity', 'demandCharge', 'cellCost')]
		battEff	= float(inputDict.get("batteryEfficiency", 92)) / 100.0 * float(inputDict.get("inverterEfficiency", 92)) / 100.0 * float(inputDict.get("inverterEfficiency", 92)) / 100.0
		discountRate = float(inputDict.get('discountRate', 2.5)) / 100.0
		retailCost = float(inputDict.get('retailCost', 0.07))
		dodFactor = float(inputDict.get('dodFactor', 85)) / 100.0
		projYears = int(inputDict.get('projYears',10))
		startPeakHour = int(inputDict.get('startPeakHour',18))
		endPeakHour = int(inputDict.get('endPeakHour',24))
		dispatchStrategy = str(inputDict.get('dispatchStrategy'))
		batteryCycleLife = int(inputDict.get('batteryCycleLife',5000))
		# Put demand data in to a file for safe keeping.
		with open(pJoin(modelDir,"demand.csv"),"w") as demandFile:
			demandFile.write(inputDict['demandCurve'])
		# If dispatch is custom, write the strategy to a file in the model directory
		if dispatchStrategy == 'customDispatch':
			with open(pJoin(modelDir,"dispatchStrategy.csv"),"w") as customDispatchFile:
				customDispatchFile.write(inputDict['customDispatchStrategy'])
		# Start running battery simulation.
		battCapacity = cellQuantity * cellCapacity * dodFactor
		battDischarge = cellQuantity * dischargeRate
		battCharge = cellQuantity * chargeRate
		# Most of our data goes inside the dc "table"
		try:
			dc = []
			with open(pJoin(modelDir,"demand.csv")) as inFile:
				reader = csv.DictReader(inFile)
				for row in reader:
					dc.append({'datetime': parse(row['timestamp']), 'power': float(row['power'])})
				if len(dc)!=8760: raise Exception
		except:
				e = sys.exc_info()[0]
				if str(e) == "<type 'exceptions.SystemExit'>":
					pass
				else:
					errorMessage = "CSV file is incorrect format. Please see valid format definition at <a target='_blank' href = 'https://github.com/dpinney/omf/wiki/Models-~-storagePeakShave#demand-file-csv-format'>\nOMF Wiki storagePeakShave - Demand File CSV Format</a>"
					raise Exception(errorMessage)
		for row in dc:
			row['month'] = row['datetime'].month-1
			row['hour'] = row['datetime'].hour
			# row['weekday'] = row['datetime'].weekday() # TODO: figure out why we care about this.
		if dispatchStrategy == "optimal":
			outData['startDate'] = dc[0]['datetime'].isoformat()
			ps = [battDischarge for x in range(12)]
			dcGroupByMonth = [[t['power'] for t in dc if t['datetime'].month-1==x] for x in range(12)]
			monthlyPeakDemand = [max(dcGroupByMonth[x]) for x in range(12)]
			capacityLimited = True
			while capacityLimited:
				battSoC = battCapacity # Battery state of charge; begins full.
				battDoD = [battCapacity for x in range(12)]  # Depth-of-discharge every month, depends on dodFactor.
				for row in dc:
					month = int(row['datetime'].month)-1
					powerUnderPeak  = monthlyPeakDemand[month] - row['power'] - ps[month]
					isCharging = powerUnderPeak > 0
					isDischarging = powerUnderPeak <= 0
					charge = isCharging * min(
						powerUnderPeak * battEff, # Charge rate <= new monthly peak - row['power']
						battCharge, # Charge rate <= battery maximum charging rate.
						battCapacity - battSoC) # Charge rage <= capacity remaining in battery.
					discharge = isDischarging * min(
						abs(powerUnderPeak), # Discharge rate <= new monthly peak - row['power']
						abs(battDischarge), # Discharge rate <= battery maximum charging rate.
						abs(battSoC+.001)) # Discharge rate <= capacity remaining in battery.
					# (Dis)charge battery
					battSoC += charge
					battSoC -= discharge
					# Update minimum state-of-charge for this month.
					battDoD[month] = min(battSoC,battDoD[month])
					row['netpower'] = row['power'] + charge/battEff - discharge
					row['battSoC'] = battSoC
				capacityLimited = min(battDoD) < 0
				ps = [ps[month]-(battDoD[month] < 0) for month in range(12)]
			peakShaveSum = sum(ps)
		elif dispatchStrategy == "daily":
			outData['startDate'] = dc[0]['datetime'].isoformat()
			battSoC = battCapacity
			for row in dc:
				month = int(row['datetime'].month)-1
				discharge = min(battDischarge,battSoC)
				charge = min(battCharge, battCapacity-battSoC)
				#If hour is within peak hours and the battery has charge
				if row['hour'] >= startPeakHour and row['hour'] <= endPeakHour and battSoC >= 0:
					row['netpower'] = row['power'] - discharge
					battSoC -= discharge
				else:
				#If hour is outside peak hours and the battery isnt fully charged, charge it
					if battSoC < battCapacity:
						battSoC += charge
						row['netpower'] = row['power'] + charge/battEff
					else:
						row['netpower'] = row['power']
				row['battSoC'] = battSoC
			dcGroupByMonth = [[t['power'] for t in dc if t['datetime'].month-1==x] for x in range(12)]
			simpleDCGroupByMonth = [[t for t in dc if t['datetime'].month-1==x] for x in range(12)]
			#Finding rows with max power
			monthlyPeakDemand =  [max(dVals, key=lambda x: x['power']) for dVals in simpleDCGroupByMonth]
			ps = []
			#Determining monthly peak shave
			for row in monthlyPeakDemand:
				ps.append(row['power']-row['netpower'])
			peakShaveSum = sum(ps)
		else:
			try:
				with open(pJoin(modelDir,'dispatchStrategy.csv')) as strategyFile:
					reader = csv.DictReader(strategyFile)
					rowCount = 0
		 			for i, row in enumerate(reader):
		 				dc[i]['dispatch'] = int(row['dispatch'])
		 				rowCount+=1
		 			if rowCount!= 8760: raise Exception
		 	except:
				e = sys.exc_info()[0]
				if str(e) == "<type 'exceptions.SystemExit'>":
					pass
				else:
					errorMessage = "Dispatch Strategy file is in an incorrect format. Please see valid format definition at <a target = '_blank' href = 'https://github.com/dpinney/omf/wiki/Models-~-storagePeakShave#custom-dispatch-strategy-file-csv-format'>\nOMF Wiki storagePeakShave - Custom Dispatch Strategy File Format</a>"
					raise Exception(errorMessage)	 		
		 	outData['startDate'] = dc[0]['datetime'].isoformat()
			battSoC = battCapacity
			for row in dc:
				month = int(row['datetime'].month)-1
				discharge = min(battDischarge,battSoC)
				charge = min(battCharge, battCapacity-battSoC)
				#If there is a 1 in the dispatch strategy csv, the battery discharges
				if row['dispatch']==1:
					row['netpower'] = row['power'] - discharge
					battSoC -= discharge
				else:
					if battSoC < battCapacity:
						battSoC += charge
						row['netpower'] = row['power'] + charge/battEff
					else:
						row['netpower'] = row['power']
				row['battSoC'] = battSoC
			dcGroupByMonth = [[t['power'] for t in dc if t['datetime'].month-1==x] for x in range(12)]
			#Calculating how much the battery discharges each month
			dischargeGroupByMonth = [[t['netpower']-t['power'] for t in dc if t['datetime'].month-1==x] for x in range(12)]
			simpleDCGroupByMonth = [[t for t in dc if t['datetime'].month-1==x] for x in range(12)]
			monthlyPeakDemand =  [max(dVals, key=lambda x: x['power']) for dVals in simpleDCGroupByMonth]
			ps = []
			for row in monthlyPeakDemand:
				ps.append(row['power']-row['netpower'])
			peakShaveSum = sum(ps)
			chargePerMonth = []
			#Calculate how much the battery charges per year for cashFlowCurve, SPP calculation, kWhToRecharge
			for row in dischargeGroupByMonth:
				total = 0
				for num in row:
					if num > 0:
						total += num
				chargePerMonth.append(total)
			totalYearlyCharge = sum(chargePerMonth)
		#Calculations
		dcThroughTheMonth = [[t for t in iter(dc) if t['datetime'].month-1<=x] for x in range(12)]
		hoursThroughTheMonth = [len(dcThroughTheMonth[month]) for month in range(12)]
		if peakShaveSum == 0:
				peakShaveSum = -1
				#peakShave of 0 means no benefits, so make it -1
		if dispatchStrategy == 'optimal':
			cashFlowCurve = [peakShaveSum * demandCharge for year in range(projYears)]
			outData['SPP'] = (cellCost*cellQuantity)/(peakShaveSum*demandCharge)
		elif dispatchStrategy == 'daily':
			#cashFlowCurve is $ in from peak shaving minus the cost to recharge the battery every day of the year
			cashFlowCurve = [(peakShaveSum * demandCharge)-(battCapacity*365*retailCost) for year in range(projYears)]
			#simplePayback is also affected by the cost to recharge the battery every day of the year
			outData['SPP'] = (cellCost*cellQuantity)/((peakShaveSum*demandCharge)-(battCapacity*365*retailCost))
		else:
			cashFlowCurve = [(peakShaveSum * demandCharge)-(totalYearlyCharge*retailCost) for year in range(projYears)]
			outData['SPP'] = (cellCost*cellQuantity)/((peakShaveSum*demandCharge)-(totalYearlyCharge*retailCost))		
		cashFlowCurve[0]-= (cellCost * cellQuantity)
		outData['netCashflow'] = cashFlowCurve
		outData['cumulativeCashflow'] = [sum(cashFlowCurve[0:i+1]) for i,d in enumerate(cashFlowCurve)]
		outData['NPV'] = npv(discountRate, cashFlowCurve)
		outData['demand'] = [t['power']*1000.0 for t in dc]
		outData['demandAfterBattery'] = [t['netpower']*1000.0 for t in dc]
		outData['batterySoc'] = [t['battSoC']/battCapacity*100.0*dodFactor + (100-100*dodFactor) for t in dc]
		# Estimate number of cyles the battery went through.
		SoC = outData['batterySoc']
		cycleEquivalents = sum([SoC[i]-SoC[i+1] for i,x in enumerate(SoC[0:-1]) if SoC[i+1] < SoC[i]]) / 100.0
		outData['cycleEquivalents'] = cycleEquivalents
		outData['batteryLife'] = batteryCycleLife/cycleEquivalents
		# # Output some matplotlib results as well.
		# plt.plot([t['power'] for t in dc])
		# plt.plot([t['netpower'] for t in dc])
		# plt.plot([t['battSoC'] for t in dc])
		# for month in range(12):
		#   plt.axvline(hoursThroughTheMonth[month])
		# plt.savefig(pJoin(modelDir,"plot.png"))
		
		# Summary of results
		outData['months'] = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
		totMonNum = []
		monthlyDemand = []
		for x in range (0, len(dcGroupByMonth)):
			totMonNum.append(sum(dcGroupByMonth[x])/1000)
			monthlyDemand.append([outData['months'][x], totMonNum[x]])
		outData['monthlyDemand'] = totMonNum
		outData['ps'] = ps
		outData['monthlyDemandRed'] = [totMonNum - ps for totMonNum, ps in zip(totMonNum, ps)]
		outData['benefitMonthly'] = [x * demandCharge for x in outData['ps']]
		if dispatchStrategy == 'optimal':
			outData['kWhtoRecharge'] = [battCapacity - x for x in outData['ps']]
		elif dispatchStrategy == 'daily':
			#Battery is dispatched and charged everyday, ~30 days per month
			kWhtoRecharge = [battCapacity * 30 -x for x in range(12)]
			outData['kWhtoRecharge'] = kWhtoRecharge
		else:
			#
			kWhtoRecharge = []
			for num in chargePerMonth:
				kWhtoRecharge.append(num)
			outData['kWhtoRecharge'] = kWhtoRecharge
		outData['costtoRecharge'] = [retailCost * x for x in outData['kWhtoRecharge']]
		benefitMonthly = outData['benefitMonthly']
		costtoRecharge = outData['costtoRecharge']
		outData['benefitNet'] = [benefitMonthly - costtoRecharge for benefitMonthly, costtoRecharge in zip(benefitMonthly, costtoRecharge)]
		# Battery KW
		demandAfterBattery = outData['demandAfterBattery']
		demand = outData['demand']
		outData['batteryDischargekW'] = [demand - demandAfterBattery for demand, demandAfterBattery in zip(demand, demandAfterBattery)]
		outData['batteryDischargekWMax'] = max(outData['batteryDischargekW'])
		battCostPerCycle =  cellQuantity * cellCapacity * cellCost / batteryCycleLife
		lcoeTotCost = (cycleEquivalents *  cellQuantity * cellCapacity * retailCost) + (battCostPerCycle * cycleEquivalents)
		loceTotEnergy = cycleEquivalents * cellQuantity * cellCapacity
		LCOE = lcoeTotCost / loceTotEnergy
		outData['LCOE'] = LCOE
		# 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 = datetime.datetime.now()
		inputDict["runTime"] = str(datetime.timedelta(seconds=int((endTime - startTime).total_seconds())))
		with open(pJoin(modelDir,"allInputData.json"),"w") as inFile:
			json.dump(inputDict, inFile, indent=4)
		try:
			os.remove(pJoin(modelDir,"PPID.txt"))
		except:
			pass
	except:
		# If input range wasn't valid delete output, write error to disk.
		cancel(modelDir)
		thisErr = traceback.format_exc()
		print 'ERROR IN MODEL', modelDir, thisErr
		inputDict['stderr'] = thisErr
		with open(os.path.join(modelDir,'stderr.txt'),'w') as errorFile:
			errorFile.write(thisErr)
		with open(pJoin(modelDir,"allInputData.json"),"w") as inFile:
			json.dump(inputDict, inFile, indent=4)
Ejemplo n.º 38
0
		timeRemaining = int(np.floor((5*240) - (exDrillTime + prodDrillTime))) # 5 years - exploration and production drill time
		randomWalk = gmr(40.3, timeRemaining, 1) # Generate spot oil prices for time remaining days
		# Arrays to be reset each simulation
		qProd =[]
		revProd = []
		cProd = []
		netProd = []
		oilVal = []
		for x in range(timeRemaining):
			prodQ = prodQt(i+1)
			qProd.append(prodQ)
			revProd.append(randomWalk[x]*prodQ)
			cProd.append(prodQ*prodCost)
			netProd.append(revProd[x]-cProd[x])
			oilVal.append(randomWalk[x])
		npvProd.append(np.npv(dailyRate, netProd))
		NPVcProd.append(np.npv(dailyRate, cProd))
		NPVrevProd.append(np.npv(dailyRate, revProd))
		SUMqProd.append(np.sum(qProd))
		npvOilVal.append(np.npv(dailyRate, oilVal))
		finalRev.append(np.npv(dailyRate, netProd)-1000.0*(cPreDiscover[i]+cDryWell[i]+cDrill[i]+cLogging[i]+cBlowout[i]))
	else:
		finalRev.append(-1000.0*(cPreDiscover[i]+cDryWell[i]+cDrill[i]+cLogging[i]+cBlowout[i]))
		npvProd.append(0)

print("Pre Discovery")
print(descriptiveStats(cPreDiscover))
print(percentilesC(cPreDiscover))
print("Dry Well")
print(descriptiveStats(cDryWell))
print(percentilesC(cDryWell))
Ejemplo n.º 39
0
 def test_npv_decimal(self):
     assert_equal(
         np.npv(Decimal('0.05'), [-15000, 1500, 2500, 3500, 4500, 6000]),
         Decimal('122.894854950942692161628715'))
Ejemplo n.º 40
0
def heavyProcessing(modelDir, inputDict):
	''' Run the model in a separate process. web.py calls this to run the model.
	This function will return fast, but results take a while to hit the file system.'''
	# Delete output file every run if it exists
	try:
		# Ready to run.
		startTime = datetime.datetime.now()
		outData = {}
		# Get variables.
		cellCapacity = float(inputDict['cellCapacity'])
		(cellCapacity, dischargeRate, chargeRate, cellQuantity, demandCharge, cellCost) = \
			[float(inputDict[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate', 'cellQuantity', 'demandCharge', 'cellCost')]
		battEff	= float(inputDict.get("batteryEfficiency", 92)) / 100.0 * float(inputDict.get("inverterEfficiency", 92)) / 100.0 * float(inputDict.get("inverterEfficiency", 92)) / 100.0
		discountRate = float(inputDict.get('discountRate', 2.5)) / 100.0
		retailCost = float(inputDict.get('retailCost', 0.07))
		dodFactor = float(inputDict.get('dodFactor', 85)) / 100.0
		projYears = int(inputDict.get('projYears',10))
		# Put demand data in to a file for safe keeping.
		with open(pJoin(modelDir,"demand.csv"),"w") as demandFile:
			demandFile.write(inputDict['demandCurve'])
		# Start running battery simulation.
		battCapacity = cellQuantity * cellCapacity * dodFactor
		battDischarge = cellQuantity * dischargeRate
		battCharge = cellQuantity * chargeRate
		# Most of our data goes inside the dc "table"
		try:
			dc = []
			with open(pJoin(modelDir,"demand.csv")) as inFile:
				reader = csv.DictReader(inFile)
				for row in reader:
					dc.append({'datetime': parse(row['timestamp']), 'power': float(row['power'])})
				if len(dc)<8760: raise Exception
		except:
			errorMessage = "CSV file is incorrect format. Please see valid format definition at\n <a target='_blank' href = 'https://github.com/dpinney/omf/wiki/Models-~-energyStorage#demand-file-csv-format'>OMF Wiki energyStorage</a>"
			raise Exception(errorMessage)
		for row in dc:
			row['month'] = row['datetime'].month-1
			row['weekday'] = row['datetime'].weekday
		outData['startDate'] = dc[0]['datetime'].isoformat()
		ps = [battDischarge for x in range(12)]
		dcGroupByMonth = [[t['power'] for t in dc if t['datetime'].month-1==x] for x in range(12)]
		monthlyPeakDemand = [max(dcGroupByMonth[x]) for x in range(12)]
		capacityLimited = True
		while capacityLimited:
			battSoC = battCapacity # Battery state of charge; begins full.
			battDoD = [battCapacity for x in range(12)]  # Depth-of-discharge every month, depends on dodFactor.
			for row in dc:
				month = int(row['datetime'].month)-1
				powerUnderPeak  = monthlyPeakDemand[month] - row['power'] - ps[month]
				isCharging = powerUnderPeak > 0
				isDischarging = powerUnderPeak <= 0
				charge = isCharging * min(
					powerUnderPeak * battEff, # Charge rate <= new monthly peak - row['power']
					battCharge, # Charge rate <= battery maximum charging rate.
					battCapacity - battSoC) # Charge rage <= capacity remaining in battery.
				discharge = isDischarging * min(
					abs(powerUnderPeak), # Discharge rate <= new monthly peak - row['power']
					abs(battDischarge), # Discharge rate <= battery maximum charging rate.
					abs(battSoC+.001)) # Discharge rate <= capacity remaining in battery.
				# (Dis)charge battery
				battSoC += charge
				battSoC -= discharge
				# Update minimum state-of-charge for this month.
				battDoD[month] = min(battSoC,battDoD[month])
				row['netpower'] = row['power'] + charge/battEff - discharge
				row['battSoC'] = battSoC
			capacityLimited = min(battDoD) < 0
			ps = [ps[month]-(battDoD[month] < 0) for month in range(12)]
		dcThroughTheMonth = [[t for t in iter(dc) if t['datetime'].month-1<=x] for x in range(12)]
		hoursThroughTheMonth = [len(dcThroughTheMonth[month]) for month in range(12)]
		peakShaveSum = sum(ps)
		outData['SPP'] = (cellCost*cellQuantity)/(peakShaveSum*demandCharge)
		cashFlowCurve = [peakShaveSum * demandCharge for year in range(projYears)]
		cashFlowCurve[0]-= (cellCost * cellQuantity)
		outData['netCashflow'] = cashFlowCurve
		outData['cumulativeCashflow'] = [sum(cashFlowCurve[0:i+1]) for i,d in enumerate(cashFlowCurve)]
		outData['NPV'] = npv(discountRate, cashFlowCurve)
		outData['demand'] = [t['power']*1000.0 for t in dc]
		outData['demandAfterBattery'] = [t['netpower']*1000.0 for t in dc]
		outData['batterySoc'] = [t['battSoC']/battCapacity*100.0*dodFactor + (100-100*dodFactor) for t in dc]
		# Estimate number of cyles the battery went through.
		SoC = outData['batterySoc']
		outData['cycleEquivalents'] = sum([SoC[i]-SoC[i+1] for i,x in enumerate(SoC[0:-1]) if SoC[i+1] < SoC[i]]) / 100.0
		# # Output some matplotlib results as well.
		# plt.plot([t['power'] for t in dc])
		# plt.plot([t['netpower'] for t in dc])
		# plt.plot([t['battSoC'] for t in dc])
		# for month in range(12):
		#   plt.axvline(hoursThroughTheMonth[month])
		# plt.savefig(pJoin(modelDir,"plot.png"))
		# Summary of results
		outData['months'] = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
		totMonNum = []
		monthlyDemand = []
		for x in range (0, len(dcGroupByMonth)):
			totMonNum.append(sum(dcGroupByMonth[x])/1000)
			monthlyDemand.append([outData['months'][x], totMonNum[x]])
		outData['monthlyDemand'] = totMonNum
		outData['ps'] = ps
		outData['monthlyDemandRed'] = [totMonNum - ps for totMonNum, ps in zip(totMonNum, ps)]
		outData['benefitMonthly'] = [x * demandCharge for x in outData['ps']]
		outData['kWhtoRecharge'] = [battCapacity - x for x in outData['ps']]
		outData['costtoRecharge'] = [retailCost * x for x in outData['kWhtoRecharge']]
		benefitMonthly = outData['benefitMonthly']
		costtoRecharge = outData['costtoRecharge']
		outData['benefitNet'] = [benefitMonthly - costtoRecharge for benefitMonthly, costtoRecharge in zip(benefitMonthly, costtoRecharge)]
		# Battery KW
		demandAfterBattery = outData['demandAfterBattery']
		demand = outData['demand']
		outData['batteryDischargekW'] = [demand - demandAfterBattery for demand, demandAfterBattery in zip(demand, demandAfterBattery)]
		outData['batteryDischargekWMax'] = max(outData['batteryDischargekW'])
		# 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 = datetime.datetime.now()
		inputDict["runTime"] = str(datetime.timedelta(seconds=int((endTime - startTime).total_seconds())))
		with open(pJoin(modelDir,"allInputData.json"),"w") as inFile:
			json.dump(inputDict, inFile, indent=4)
		try:
			os.remove(pJoin(modelDir,"PPID.txt"))
		except:
			pass
	except:
		# If input range wasn't valid delete output, write error to disk.
		cancel(modelDir)
		thisErr = traceback.format_exc()
		print 'ERROR IN MODEL', modelDir, thisErr
		inputDict['stderr'] = thisErr
		with open(os.path.join(modelDir,'stderr.txt'),'w') as errorFile:
			errorFile.write(thisErr)
		with open(pJoin(modelDir,"allInputData.json"),"w") as inFile:
			json.dump(inputDict, inFile, indent=4)
 def test_npv(self):
     assert_almost_equal(np.npv(0.05,[-15000,1500,2500,3500,4500,6000]),
                         117.04, 2)
Ejemplo n.º 42
0
def get_roe_date(code, coefficient, required_rate_of_return, ref_year,
                 df_stock, type):
    # ref_year = datetime.date.today()       # date type
    # ref_year = ref_year.year - 1           # 현재 년도 실적 ROE는 없음으로 직전 년도를 기준으로 함.
    # required_rate_of_return는 현재 BBB- 5년를 사용하지만, 업종별, 종목별, 시장환경에 맞게 변경하여 판단이 필요함.
    try:
        year_capital = df_stock.loc['capital', ref_year]
        year_roe = df_stock.loc['roe', ref_year] / 100  # 단위 % 환산
        spread = year_roe - required_rate_of_return  # 단위 % - % 계산임으로 spread변수도 값이 %가 됨.

        # 테이블 계산을 위한 기본 setting
        index = ['coefficient', 'roe', 'net_profit', 'earing', 'capital']
        df_table = pd.DataFrame({ref_year: [1, year_roe, 0, 0, year_capital]},
                                index=index)

        # 적정가치 구하기
        roe_max_len = len(df_stock.columns)  # 년도가 있는 컬럼의 최대 길이 구함
        year_index = df_stock.columns.values.tolist()  #array자료형을 list형으로 변환
        year_index = year_index.index(ref_year)  # ref_year를 기준으로 컬럼에서 위치 찾음
        year_roe_count = roe_max_len - year_index
        year = copy(ref_year)  # ref_year를 year로 copy하여 별도 변수로 사용 a is b로 테스트
        calculated_coefficient = 0
        calculated_roe = 0
        calculated_net_profit = 0
        calculated_earing = 0
        calculated_capital = 0

        for year_count in range(1, 11):  #10년 동안 계산
            calculated_coefficient = df_table.loc[
                'coefficient', year] - coefficient  # dataframe에서 직전년도 roe와 계산
            if calculated_coefficient < 0.0:  #roe 0 이하이면 0으로 세팅
                calculated_coefficient = 0.0

        # 기준년을 참조하여 table상의 roe그대로 사용하고, roe참조가 끝나면 계산함.
            '''
            if year_roe_count >= year_count:
                calculated_roe = df_stock.loc['roe',year] / 100    # 단위 % 환산
            else:
                calculated_roe = spread * calculated_coefficient + required_rate_of_return  # spread와 required_rate_of_return는 %단위로 환산되어있음.
            '''
            calculated_roe = spread * calculated_coefficient + required_rate_of_return  # spread와 required_rate_of_return는 %단위로 환산되어있음.
            calculated_net_profit = df_table.loc['capital',
                                                 year] * calculated_roe
            calculated_earing = calculated_net_profit - df_table.loc[
                'capital', year] * required_rate_of_return  # 단위 % 환산
            calculated_capital = df_table.loc['capital',
                                              year] + calculated_net_profit

            if type == 'year':
                year = year + 1  # 1년 증가
            elif type == 'quarter':
                year_month = datetime.strptime(year, '%Y%m')
                year_month = year_month + relativedelta(months=+3)
                year = year_month.strftime('%Y%m')

            seri_table = pd.Series([
                calculated_coefficient, calculated_roe, calculated_net_profit,
                calculated_earing, calculated_capital
            ],
                                   name=year,
                                   index=index)
            df_table = pd.concat([df_table, seri_table], axis=1)

        # NPV구하기
        pv_val = df_table.loc['earing'].values.tolist()
        pv_val = pv_val[1:]

        # pv = get_npv(required_rate_of_return, pv_val) #초기 투자금액은 0,np.npv(0.281,[-0, 39, 59, 55, 20])
        pv = np.npv(required_rate_of_return, pv_val)
        rim = year_capital + pv

        # 적정주가 구하기
        '''
        stock_date = stock.loc['date',ref_year] # date type
        today = datetime.date.today()       # date type
        date_delta = stock_date - today     # timedelta type
        date_delta = date_delta.days         # int type
    
        stock_value를 구할때 할인율의 산출일 기준으로 자승으로 곱하여 남은 날짜만큼 구하고 있음.
        그러나, 이것은 과거데이타 이용 및 현재 가치 판단시에 과한것으로 판단되어 일단, 사용하지 않음
        또한, 기준날짜 - 현재날짜 일때 ...컨센서스 데이타가 없을 때는 (-)값이 나와 엉뚱하게 과하게 나옴.
        stock_value1 = rim / (1 + required_rate_of_return)**(date_delta/365)
        '''

        # RIM 값을 구한후 미래가치에 대해 spread값만큼 자승하여 현재 가치를 구함
        # calculated_rim = rim / (1 + required_rate_of_return) roe를 해당 Year것을 사용하여 할인율 미적용함.
        share_outstanding = df_stock.loc['share_outstanding',
                                         ref_year]  # ROE가 계산되는 year의 보통주식수
        value_per_share = int(
            (rim / share_outstanding) * 100000000)  # 단위:억원 환산, 정수처리
        '''
        # 자승하여 현재가지치구하지 않고 현재 year 기준으로 모든것을 구했음으로 미래가치 -> 현재가지 부분을 제외
        share_outstanding = df_stock.loc['share_outstanding',ref_year]  # ROE가 계산되는 year의 보통주식수
        value_per_share = int((rim / share_outstanding) * 100000000)    # 단위:억원 환산, 정수처리
        '''
    except:
        return (000000)  # 종목정보 오류는 000000으로 세팅
    else:
        return (value_per_share)