def main():
    print(
        '\n====================================Part 2 (Same as Part 1)====================================\n'
    )
    print('Creating a LoanPool object with the csv file of loan data ... \n')
    myLoanPool = LoanPool()
    with open('Loans.csv', 'r') as f:
        f.readline()
        cnt = 0
        while 1:
            line = f.readline()
            if line == '':
                break
            elif cnt == 1500:  # cnt id for debug perpose
                break
            else:
                lst = line.split(',')
                loan = AutoLoan(Civic(initValue=float(lst[6])),
                                face=float(lst[2]),
                                rate=float(lst[3]),
                                term=float(lst[4]))
                myLoanPool.loans.append(loan)
                cnt += 1

    print('Instantiate my StructuredSecurity object ... \n')
    myStructuredSecurity = StructuredSecurity(myLoanPool.ttlPrincipal(),
                                              'Sequencial')
    tranchesChar = [(0.8, 0.05, 'A'), (0.2, 0.08, 'B')]
    for percent, rate, subordination in tranchesChar:
        myStructuredSecurity.addTranche(percent, rate, subordination)
    logging.debug('The first tranche is {}'.format(
        myStructuredSecurity.tranches[0].rate * 12.0))

    print('Running my doWaterfall function ... \n')
    logging.info(
        'Attention: when running doWaterfall(), I will run checkDefaults(). Or you can go to file StructuredSecurity.py->doWaterfall() to disable it. \n'
    )
    res = doWaterfall(myLoanPool, myStructuredSecurity)
    raw_input('Program pause. Press enter to continue.\n')
    '''===================================================================================================
	Implementation and demo for Part2
	==================================================================================================='''
    print(
        '\n====================================Part 2 (Different from Part 1)=====================================\n'
    )
    print(
        'Printing IRR, DIRR, WAL and letter rating for Tranche A and Tranche B to the screen ... \n'
    )
    IRR = output.get('IRR tranches')
    DIRR = output.get('DIRR tranches')
    WAL = output.get('WAL tranches')
    letter = [toLetterRating(dirr) for dirr in DIRR]
    logging.info('For trenche A, the IRR is {0}, the DIRR is {1}, the AL is {2}, the letter rating is {3}.'.\
     format(IRR[0], DIRR[0], WAL[0], letter[0]))
    logging.info('For trenche B, the IRR is {0}, the DIRR is {1}, the AL is {2}, the letter rating is {3}.'.\
     format(IRR[1], DIRR[1], WAL[1], letter[1]))
    print('')
    raw_input('Part 2 demo finished successfully. Press any key to exit.\n')
def main():
	print('\n====================================Part 3 (Same as Part 1)=====================================\n');
	print('Creating a LoanPool object with the csv file of loan data ... \n');
	myLoanPool=LoanPool()
	with open('Loans.csv', 'r') as f:
		f.readline();cnt=0;
		while 1:
			line=f.readline();
			if line=='':
				break
			elif cnt==1500: # cnt id for debug perpose
				break
			else :
				lst=line.split(',');
				loan=AutoLoan(Civic(initValue=float(lst[6])), face=float(lst[2]), rate=float(lst[3]), term=float(lst[4]))
				myLoanPool.loans.append(loan);
				cnt+=1;

	print('Instantiate my StructuredSecurity object ... \n');
	myStructuredSecurity=StructuredSecurity(myLoanPool.ttlPrincipal(), 'Sequencial');
	tranchesChar=[(0.8, 0.05, 'A'), (0.2, 0.08, 'B')]
	for percent, rate, subordination in tranchesChar:
		myStructuredSecurity.addTranche(percent, rate, subordination);
	logging.debug('The first tranche is {}'.format(myStructuredSecurity.tranches[0].subordination))
	raw_input('Program pause. Press enter to continue.\n');

	'''===================================================================================================
	Implementation and demo for Part3
	==================================================================================================='''
	print('\n====================================Part 3 (Different from Part 1)=====================================\n');
	print('Seeking optimal numProcess for multiProcessing ... \n');
	ans=raw_input('Sir, do you want to explore the optimal numProcess ? [y/n] \n');
	try :
		if ans.lower()=='y':
			numProcess_list=[2+2*i for i in range(8)]; numProcess_list.insert(0, 1)
			minimum=original=float("inf"); optimal_processes=None;
			for numProcess in numProcess_list:
				s=time.time(); 
				res=simulateWaterfallParallel(myLoanPool, myStructuredSecurity, NSIM=2000, numProcess=numProcess);
				e=time.time();
				if e-s<minimum and res.get('DIRR tranches')!=[]:
					optimal_processes=numProcess; minimum=e-s;
				if numProcess==1:
					original=e-s
				logging.info('Using {} processes, it takes time {}'.format(numProcess, e-s))
			logging.info('Original it takes {} secs without multiprocessing; with multiprocessing method, it takes {} secs with optimal_processes {}.'\
				.format(original, minimum, optimal_processes))
			raw_input('Program pause. Press enter to continue.\n');
		else :
			optimal_processes=4;
	except Exception as e:
		logging.exception('Error Message: {}'.format(e));
		logging.info('The optimal_processes will be set to 4.')


	print('Running my runMonte function ... \n');
	# res=runMonte(myLoanPool, myStructuredSecurity, NSIM=2000, tol=0.005);
	res=runMonte(myLoanPool, myStructuredSecurity, NSIM=2000, tol=0.005, numProcess=optimal_processes);
	rate=res.get('rate');
	logging.info('The result optimal rates are {}'.format(rate))
	resStructuredSecurity=StructuredSecurity(myLoanPool.ttlPrincipal(), 'Sequencial');
	tranchesChar=[(0.8, 0.05, 'A'), (0.2, 0.08, 'B')]
	tranchesChar=[(percent, rate[idx], subordination) for idx, percent, _, subordination in enumerate(tranchesChar)]
	for percent, rate, subordination in tranchesChar:
		resStructuredSecurity.addTranche(percent, rate, subordination);
	output=doWaterfall(myLoanPool, resStructuredSecurity);

	print('Printing IRR, DIRR, WAL and letter rating for Tranche A and Tranche B to the screen ... \n');
	IRR=output.get('IRR tranches'); DIRR=output.get('DIRR tranches'); WAL=output.get('WAL tranches');
	letter=[toLetterRating(dirr) for dirr in DIRR]; 
	for idx, _, rate, subordination in enumerate(tranchesChar):
		logging.info('{0} trenche: class {1}, the rate is {2}, the IRR is {3}, the DIRR is {4}, the AL is {5}, the letter rating is {6}.'.\
			format(idx, subordination, rate, IRR[0], DIRR[0], WAL[0], letter[0]))
	raw_input('Part 3 demo finished successfully. Press any key to exit.\n');
def main():
    print(
        '\n====================================Part 3 (Same as Part 1)=====================================\n'
    )
    print('Creating a LoanPool object with the csv file of loan data ... \n')
    myLoanPool = LoanPool()
    with open('Loans.csv', 'r') as f:
        f.readline()
        cnt = 0
        while 1:
            line = f.readline()
            if line == '':
                break
            elif cnt == 1500:  # cnt id for debug perpose
                break
            else:
                lst = line.split(',')
                loan = AutoLoan(Civic(initValue=float(lst[6])),
                                face=float(lst[2]),
                                rate=float(lst[3]),
                                term=float(lst[4]))
                myLoanPool.loans.append(loan)
                cnt += 1

    print('Instantiate my StructuredSecurity object ... \n')
    myStructuredSecurity = StructuredSecurity(myLoanPool.ttlPrincipal(),
                                              'Sequencial')
    myStructuredSecurity.addTranche(0.8, 0.05, 'A')
    myStructuredSecurity.addTranche(0.2, 0.08, 'B')
    logging.debug('The first tranche is {}'.format(
        myStructuredSecurity.tranches[0].subordination))
    raw_input('Program pause. Press enter to continue.\n')
    '''===================================================================================================
	Implementation and demo for Part3
	==================================================================================================='''
    print(
        '\n====================================Part 3 (Different from Part 1)=====================================\n'
    )
    print('Seeking optimal numProcess for multiProcessing ... \n')
    ans = raw_input(
        'Sir, do you want to explore the optimal numProcess ? [y/n] \n')
    try:
        if ans.lower() == 'y':
            numProcess_list = [2 + 2 * i for i in range(6)]
            numProcess_list.insert(0, 1)
            minimum = original = float("inf")
            optimal_processes = 1
            for numProcess in numProcess_list:
                s = time.time()
                _, ls = simulateWaterfallParallel(myLoanPool,
                                                  myStructuredSecurity,
                                                  NSIM=200,
                                                  numProcess=numProcess)
                e = time.time()
                if e - s < minimum and ls != []:
                    optimal_processes = numProcess
                    minimum = e - s
                if numProcess == 1:
                    original = e - s
                logging.info('Using {} processes, it takes time {}'.format(
                    numProcess, e - s))
            logging.info('Original it takes {} secs without multiprocessing; with multiprocessing method, it takes {} secs with optimal_processes {}.'\
             .format(original, minimum, optimal_processes))
            raw_input('Program pause. Press enter to continue.\n')
        else:
            optimal_processes = 8
    except Exception as e:
        logging.exception('Error Message: {}'.format(e))
        logging.info('The optimal_processes will be set to 4.')
    raw_input('Program pause. Press enter to continue.\n')

    print('Running my runMonte function ... \n')
    rate = runMonte(myLoanPool, myStructuredSecurity, NSIM=5, tol=0.005)
    #rate=runMonte(myLoanPool, myStructuredSecurity, NSIM=2000, tol=0.005, numProcess=optimal_processes);
    myStructuredSecurity = StructuredSecurity(myLoanPool.ttlPrincipal(),
                                              'Sequencial')
    myStructuredSecurity.addTranche(0.8, rate[0], 'A')
    myStructuredSecurity.addTranche(0.2, rate[1], 'B')
    waterfall_s, waterfall_l, reserve_account, IRR_s, DIRR_s, AL_s = doWaterfall(
        myLoanPool, myStructuredSecurity)

    print(
        'Printing IRR, DIRR, AL and letter rating for Tranche A and Tranche B to the screen ... \n'
    )
    letter_s = [toLetterRating(DIRR) for DIRR in DIRR_s]
    rate_s = [t.rate * 12.0 for t in myStructuredSecurity.tranches]
    logging.info('For trenche A, the rate is {0}, the IRR is {1}, the DIRR is {2}, the AL is {3}, the letter rating is {4}.'.\
     format(rate_s[0], IRR_s[0], DIRR_s[0], AL_s[0], letter_s[0]))
    logging.info('For trenche B, the rate is {0}, the IRR is {1}, the DIRR is {2}, the AL is {3}, the letter rating is {4}.'.\
     format(rate_s[1], IRR_s[0], DIRR_s[1], AL_s[1], letter_s[1]))
    raw_input('Part 3 demo finished successfully. Press any key to exit.\n')
def main():
    '''===================================================================================================
	Implementation for Part1.1
	==================================================================================================='''
    # Create a LoanPool object that consists of 1,500 loans. Use the provided CSV file of loan data
    # to create these Loan objects.
    print(
        '\n====================================Part 1.1=====================================\n'
    )
    print('Creating a LoanPool object with the csv file of loan data ... \n')
    myLoanPool = LoanPool()
    with open('Loans.csv', 'r') as f:
        f.readline()
        cnt = 0
        while 1:
            line = f.readline()
            if line == '':
                break
            elif cnt == 1500:  # cnt id for debug perpose
                break
            else:
                lst = line.split(',')
                # logging.debug(lst);
                loan = AutoLoan(Civic(initValue=float(lst[6])),
                                face=float(lst[2]),
                                rate=float(lst[3]),
                                term=float(lst[4]))
                myLoanPool.loans.append(loan)
                cnt += 1

    logging.debug('The first loan is {}'.format(myLoanPool.loans[0].face))
    raw_input('Program pause. Press enter to continue.\n')
    '''===================================================================================================
	Implementation for Part1.2
	==================================================================================================='''
    # Instantiate your StructuredSecurities object, specify the total notional (from the LoanPool), add
    # two standard tranches (class A and class B in terms of subordination), and specify sequential or
    # pro-rata mode
    # The rates for each tranche can be arbitrary (for now). Note that subordinated tranches should always
    # have a higher rate, as they have increased risk
    print(
        '\n====================================Part 1.2=====================================\n'
    )
    print('Instantiate my StructuredSecurity object ... \n')
    myStructuredSecurity = StructuredSecurity(myLoanPool.ttlPrincipal(),
                                              'Sequencial')
    tranchesChar = [(0.8, 0.05, 'A'), (0.2, 0.08, 'B')]
    for percent, rate, subordination in tranchesChar:
        myStructuredSecurity.addTranche(percent, rate, subordination)
    logging.debug('The first tranche is {}'.format(
        myStructuredSecurity.tranches[0].rate * 12.0))
    raw_input('Program pause. Press enter to continue.\n')
    '''===================================================================================================
	Implementation for Part1.3
	==================================================================================================='''
    # Call doWaterfall and save the results into two CSV files (one for the asset side and one for the
    # liabilities side). All the tranches’ data for a given time period should be a single row in the CSV
    # The reserve account balance should also be in liabilities CSV, for each time period. Each time period
    # gets its own row. Note that you may need to do some clever list comprehensions and string parsing to
    # get this to output correctly
    print(
        '\n====================================Part 1.3=====================================\n'
    )
    print('Running my doWaterfall function and saving to a csv file ... \n')
    logging.info(
        'Attention: when running doWaterfall(), I will run checkDefaults(). Or you can go to file StructuredSecurity.py->doWaterfall() to disable it. \n'
    )
    res = doWaterfall(myLoanPool, myStructuredSecurity)
    waterfall_liabilities = []
    for period, tranches in enumerate(waterfall_s):
        ls = [period + 1]
        for t in tranches:
            ls += [t[0], t[1], t[2], t[3], t[4]]
        waterfall_liabilities.append(ls)
    logging.debug('Waterfall for L is {}'.format(waterfall_liabilities))
    timestr = datetime.datetime.now().strftime('%H%M%S')
    with open('liabilities_{}.csv'.format(timestr), 'w') as f:
        header = ['Period']
        for idx, _, rate, subordination in enumerate(tranchesChar):
            name = '{} {} {}'.format(idx, rate, subordination)
            header += [
                '{} interestDue', '{} interestPaid', '{} interetShort',
                '{} principalPaid',
                '{} balance'.format(name, name, name, name, name)
            ]
        f.write(','.join(header))
        f.write('\n')
        for row in waterfall_liabilities:
            row = [str(round(entry, 2)) for entry in row]
            f.write(','.join(row))
            f.write('\n')
    logging.info('file liabilities.csv is generated successfully.')

    waterfall_asset = []
    for period, item in enumerate(waterfall_l):
        ls = [period + 1]
        ls += [item[0], item[1], item[2], item[3], item[4]]
        waterfall_asset.append(ls)
    logging.debug('Waterfall for A is {}'.format(waterfall_asset))
    with open('asset_{}.csv'.format(timestr), 'w') as f:
        header = [
            'Period', 'Principal', 'Interest', 'Recoveries', 'Total', 'Balance'
        ]
        f.write(','.join(header))
        f.write('\n')
        for row in waterfall_asset:
            row = [str(round(entry, 2)) for entry in row]
            f.write(','.join(row))
            f.write('\n')
    logging.info('file asset.csv is generated successfully.')

    raw_input('Part 1 demo finished successfully. Press any key to exit.\n')