how to calculate the fixed monthly payment of credit card - python

How do I continue the following loop until I find mmp = 310? So far, with my code the furthest I can go is mmp = 240. Do you think I should have one more if statement?
balance = 4213
annualInterestRate = 0.2
mir = annualInterestRate/12
monthlyPaymentRate = 0.04
rb = balance
mmp = 0
Month = 1
while Month <= 12:
print('Month:' + str(Month))
mmp = mmp + 10
print('Minimum monthly payment:' + str(mmp))
ub = rb - mmp
rb = round(ub + (annualInterestRate/12 * ub), 2)
Month = Month + 1
print('Remaining balance:' + str(rb))
if rb > 0:
rb = balance
Month = 1
while Month <= 12:
print('Month:' + str(Month))
mmp = mmp + 10
print('Minimum monthly payment:' + str(mmp))
ub = rb - mmp
rb = round(ub + (annualInterestRate/12 * ub), 2)
Month = Month + 1
print('Remaining balance:' + str(rb))
else:
print('Lowest Payment:' + str(mmp)

Instead of while Month <= 12:, you could use while mmp < 310: if you just want to reach that number. Or while rb > 0: if you want to continue looping until everything is paid.
If looping over the months is a requirement (btw, it's generally appreciated here if you mention that your question is homework), you could add an outer loop for years:
year = 1
while rb > 0:
month = 1
while month <= 12:
# do stuff
month = month + 1
year = year + 1

Related

Years and months output not formatting properly

When I try to implement this function of no_payment() in my python script:
import math
import argparse
parse = argparse.ArgumentParser(usage='Differential calculator that calculates the per month payment on a decreasing'
'principal amount')
parse.add_argument('--type', '-t', type=str, required=True, help='diff = differential, annuity = standard, fixed payments') #error code
# cant compute with diff argument selected, as payment each month is different
parse.add_argument('--payment', '-p', type=float, required=False, help='monthly payment amount')
parse.add_argument('--principal', '-P', type=float, required=False, help='principal amount of the loan')
parse.add_argument('--periods', '-m', type=int, required=False, help='number of payments required to pay the loan')
parse.add_argument('--interest', '-i', type=float, required=True, help='interest rate (as integer, not converted)') #error code
args = parse.parse_args()
def no_payments():
i = args.interest / (12 * 100)
month_no = math.log(args.payment / (args.payment - i * args.principal), 1 + i)
overpayment = args.principal * args.interest
year_count = math.ceil(month_no // 12)
month_count = math.ceil(month_no % 12)
if 1 < month_no <= 12:
print(f'It will take {month_count} months to repay this loan!')
elif month_no == 1:
print(f'It will take 1 month to repay this loan!')
elif month_no == 12:
print(f'It will take 1 year to repay this loan!')
elif 12 < month_no < 24 and month_count == 1:
print(f'It will take {year_count} year and 1 month to repay this loan!')
elif 12 < month_no < 24 and month_count > 1:
print(f'It will take {year_count} year and {month_count} months to repay this loan!')
elif month_no >= 24 and month_count == 1:
print(f'It will take {year_count} years and {month_count} month to repay this loan!')
elif month_no >= 24 and month_count > 1:
print(f'It will take {year_count} years and {month_count} months to repay this loan!')
print(f'Overpayment = {overpayment}')
# error codes thrown if interest and type are not inputted
if args.interest is None:
print('Incorrect Parameters')
elif args.type is None:
print('Incorrect Parameters')
if args.type == 'annuity' and args.payment is None:
ann_calc()
elif args.type == 'diff' and args.payment is None:
diff_calc()
elif args.type == 'annuity' and args.principal is None:
princ()
elif args.type == 'annuity' and args.periods is None:
no_payments()
With a given argument of --type=annuity --principal=500000 --payment=23000 --interest=7.8.
The output should be 2 years but it comes out to be 1 year and 12 months. What do I have to change to make the output as 2 years?
on line 8m, your configuration states:
month_no = math.log(args.payment / (args.payment - i * args.principal), 1 + I)
using the arguments you stated in your question, this results in a value of 23.513122662562726
This is the reason why you are receiving 1 year and 12 months in your response, because technically it's 23 months, then converted to 24 months when rounded.
you have two options:
round up to 24 months, if the business logic states
remove the math.ceil, and allow the number of months to be shown as fractions.
This answers your immediate question.
For the long term solution, I would recommend a reducing classification method with your date calculations. For example:
month_no = 24 (for your example)
years = math.floor(month_no / 12). -> 2
months = (month_no - (years * 12)) -> 24 - (2 * 12) -> 0
another example:
month_no = 26 (for your example)
years = math.floor(month_no / 12). -> 2
months = (month_no - (years * 12)) -> 26 - (2 * 12) -> 2
from there you can use string injection to push your print statement
yr = '{} years'.format(years) if years > 1 else '1 year' if years = 1 else ''
mo = 'and {} months'.format(months) if months > 1 else 'and 1 month' if months = 1 else ''
print('It will take {years}{months} to repay this loan!'.format(years,months))
here's my example:
import math
import argparse
#--type=annuity --principal=500000 --payment=23000 --interest=7.8
def no_payments(args):
i = args['interest'] / (12 * 100)
month_no = round(math.log(args['payment'] / (args['payment'] - i * args['principal']), 1 + i))
overpayment = args['principal'] * args['interest']
year_count = math.ceil(month_no // 12)
month_count = math.ceil(month_no % 12)
print("month no")
print(month_no, month_count, math.ceil(24 % 12))
years = math.floor(month_no / 12) #-> 2
months = (month_no - (years * 12)) # -> 26 - (2 * 12) #-> 2
yr = '{} years'.format(years) if years > 1 else '1 year' if years == 1 else ''
mo = 'and {} months'.format(months) if months > 1 else 'and 1 month' if months == 1 else ''
print('It will take {}{} to repay this loan!'.format(yr,mo))
args = {
'type': 'annuity',
'principal': 500000,
'payment': 23000,
'interest': 7.8
}
no_payments(args)

Stop loss and Take profit question in Quantopian

I need to set a stop loss and take profit to every trade I make in Quantopian. This is the code I have at the moment but it's not working as intended.
The order logic (to enter a short or long trade) is scheduled only once per day while the take profit or stop loss should be checked every minute.
import talib as ta
import pandas
risk_per_trade = 500
factor_tp = 2
factor_sl = 2
Bars_count = 60
def initialize(context):
context.stocks = [sid(4265), sid(5061)]
schedule_function(orderlogic,date_rules.every_day(), time_rules.market_open(hours=0, minutes=10))
def orderlogic(context, data):
hist = data.history(context.stocks,['price','high','low','close','open'], bar_count=Bars_count, frequency='1d')
for stock in context.stocks:
atr = ta.ATR(hist['high'][stock],hist['low'][stock],hist['close'][stock],timeperiod=14)
sma_20 = ta.SMA(hist['close'][stock], timeperiod=20)
stop_size = factor_sl * atr[-1]
amount_shares = round(risk_per_trade / stop_size)
open_orders = get_open_orders()
LongCondition = hist['price'][stock][-1] < sma_20[-1]
SellCondition = hist['price'][stock][-1] > sma_20[-1]
if LongCondition and stock not in open_orders and context.portfolio.positions[stock].amount ==0:
order(stock, amount_shares)
elif SellCondition and stock not in open_orders and context.portfolio.positions[stock].amount ==0:
order(stock, -1 * amount_shares)
def handle_data(context,data):
# record(leverage=context.account.leverage)
for axion in context.stocks:
current_price = data.current(axion, 'price')
position = context.portfolio.positions[axion].amount
price_position = context.portfolio.positions[axion].cost_basis
pnl = ( current_price - price_position ) * position
if position > 0 and current_price > price_position:
if pnl >= factor_tp * risk_per_trade:
order_target_percent(axion, 0)
log.info("Buy with Take Profit hit " + str(axion.symbol))
if position > 0 and current_price < price_position:
if pnl <= -risk_per_trade:
order_target_percent(axion, 0)
log.info("Buy with Stop Loss hit " + str(axion.symbol))
if position < 0 and current_price < price_position:
if -pnl >= factor_tp * risk_per_trade:
order_target_percent(axion, 0)
log.info("Sell with Take Profit hit " + str(axion.symbol))
if position < 0 and current_price > price_position:
if pnl >= risk_per_trade:
order_target_percent(axion, 0)
log.info("Sell with Stop Loss hit " + str(axion.symbol))

Binary/Bisection Search to Determine Minimum Monthly Credit Card Payment Over A Year

I am trying to solve an online question using binary search (bisection search?) and I am uncertain where my code is wrong, my answers vary from the expected answer by a bit more than comfortable for me. I would really appreciate to know where I am off-course, as well as pointers for the future.
I am given an annual interest rate and an initial balance. I am also expected to select a small enough step so I can increment to the cent.
My code is like this:
startbalance = input('Balance: ')
annualInterestRate = input('annualInterestRate: ')
monthlyInterestRate = annualInterestRate / 12.0
balance = startbalance
step = 0.01
lowbound = balance / 12.0
highbound = (balance * (1 + monthlyInterestRate)**12) / 12.0
monthlyPayment = (lowbound + highbound) / 2.0
while (monthlyPayment - balance) >= step:
for month in range(0, 12):
balance -= monthlyPayment
balance = balance + ((1 + monthlyInterestRate) * balance)
if balance < 0:
highbound = monthlyPayment
balance = startbalance
elif balance > 0:
lowbound = monthlyPayment
balance = startbalance
print 'Lowest Payment: ', round(monthlyPayment, 2)
Testing my code with the values provided in cases, I have the following:
With an annual interest rate of 0.2
and a balance of 320000,
My result: 29591.88 (incorrect, the answer should be 29157.09)
With an annual interest rate of 0.18
and a balance of 999999,
My result: 91484.0 (incorrect, the answer should be 90325.03)
I think I am just a little bit off and I would really appreciate some setting-straight.
Thanks!
Fixed it (thanks, z0k!):
startbalance = input('Balance: ')
annualInterestRate = input('annualInterestRate: ')
monthlyInterestRate = annualInterestRate / 12.0
monthlyInterestRate = annualInterestRate / 12.0
startbalance = balance
step = 0.01
lowbound = startbalance / 12.0
highbound = (startbalance * (1 + monthlyInterestRate)**12) / 12.0
monthlyPayment = (lowbound + highbound) / 2.0
while (abs(startbalance)) >= step:
startbalance = balance
for month in range(0, 12):
startbalance -= monthlyPayment
startbalance = startbalance + ((monthlyInterestRate) * startbalance)
if startbalance < 0:
highbound = monthlyPayment
if startbalance > 0:
lowbound = monthlyPayment
monthlyPayment = (lowbound + highbound) / 2.0
print 'Lowest Payment: ', round(monthlyPayment, 2)

python TypeError: 'float' object is not iterable in a program for monthly payment

month = 1
while month < 13:
monthly_interest_rate = annualInterestRate/12.0
min_monthlypayment = monthlyPaymentRate * balance
monthlyUnpaidBalance = balance - min_monthlypayment
updated_balance = monthlyUnpaidBalance + (monthly_interest_rate * monthlyUnpaidBalance)
print "Month: " + str(month)
print "Minimum monthly payment : " + str(round(min_monthlypayment, 2))
print "Remaining balance: " + str(round(updated_balance, 2))
balance = updated_balance
month = month + 1
print "Total paid : " + round(sum(min_monthlypayment), 2)
print "Remaining balance: " + round(updated_balance, 2)
I don't know why I'm getting this error if not using any iteration.
You are iterating when you are trying to take the sum. My suggestion would be to keep your code and store the variable in an array and then take the sum at the end so:
import numpy as np
sum_arr = np.zeros(12)
a = 0
under min_monthlypayment put: sum_arr[a] = min_monthlypayment
under month = month + 1 put: a = a+1
then to get the sum use np.sum(sum_arr)

Bisect search using varying hi lo

I am trying to figure out how to use a bisect search to find:
Monthly payment made to clear loan amount
Monthly interest rate = (Annual interest rate) / 12
Monthly payment lower bound = Balance / 12
Monthly payment upper bound = (Balance x (1 + Monthly interest rate)12) / 12
At the moment I have:
balance = 6758
annualInterestRate = 0.20
monthlyRate = annualInterestRate/12
numGuesses = 0
lo = balance/12
hi = (balance)*((1+monthlyRate)**12)/12
monthPay = (hi + lo)/2.0
NuBalance = balance
while abs((NuBalance)*(1+monthlyRate))-(monthPay) >= 0.01:
print('low = ' + str(lo) + ' high = ' + str(hi) + ' MonthPay = ' + str(monthPay))
numGuesses += 1
if ((NuBalance)*(1+monthlyRate))-(monthPay) <= 0.01:
print('Month Pay LO = ' + str(monthPay))
lo = monthPay
else:
print('Month Pay HI = ' + str(monthPay))
hi = monthPay
monthPay = (hi + lo)/2.0
print('numGuesses = ' + str(numGuesses))
print('Month Pay = ' + str(monthPay))
Any help to where I'm going wrong would be appreciated.
It should be:
while abs((NuBalance)*(1+monthlyRate)-(monthPay)) >= 0.01:
^ ^
and always exists
(hi + lo)/2.0 < (NuBalance)*(1+monthlyRate)
is True because hi and lo both smaller than (NuBalance)*(1+monthlyRate)
In [9]: print 'lo:', lo
lo: 563
In [10]: print 'hi:', hi
hi: 686.720412649
In [11]: print 'monthPay:', monthPay
monthPay: 624.860206325
In [12]: print '(NuBalance)*(1+monthlyRate):', (NuBalance)*(1+monthlyRate)
(NuBalance)*(1+monthlyRate): 6870.63333333

Categories

Resources