PresentValue <- function(interest.rate, number.periods, frequency) {
if (interest.rate > 1) {interest.rate = interest.rate/100} else {"input interest.rate as a whole number"}
if (frequency < 1 || frequency > 12 ) {"frequency must be between 1 and 12"} else {interest.rate = interest.rate/frequency}
(1+interest.rate)^number.periods
}
The code above is simple but I need to catch user input error. I looked at tryCatch but it made no sense to me. Plus I think that it is not what I need at this point.
Basically, I need to do the following things
First, make sure the user has input the interest rate as a whole number (i.e. 5% not .05)
Second I need "ask" user how the rate is paid (frequency) monthly, annually, etc. Then divide the interest rate by the frequency.
What is strange is that the first condition only checks when the other if statements are remarked out.
This function will be an object in a larger set of functions so I think I need to consider these as warnings that will ultimately work with try catch. Finally, it would be nice if on the interest rate error the function did not terminate but simply asked for the user to correctly input the interest rate.
In apologize for the simplicity in advance but just could not find what I was looking for.
EDIT add some conetxt
Below is the bigger function. This shows the table output for convexity I need to incorporate duration and then a yield and price table and output to a page using swerve. This is going into a text book on structured finance. So it needs to work well for students
Bond.Cash.Flow <-function(issue.date, start.date, end.date, coupon, principal,
frequency, price){
library(lubridate)
issue.date <- as.Date(c(issue.date), "%m-%d-%Y")
start.date <- as.Date(c(start.date), "%m-%d-%Y")
end.date <- as.Date(c(end.date), "%m-%d-%Y")
price = price/100
# 30/360 day count calculation
d1 = day(issue.date)
m1 = month(issue.date)
y1 = year(issue.date)
d2 = day(end.date)
m2 = month(end.date)
y2 = year(end.date)
diff = (max(0, 30 - d1) + min(30, d2) + 360*(y2-y1) + 30*(m2-m1-1))/360
ncashflows = diff * frequency
cf.period = seq(1:ncashflows)
pmtdate = seq(start.date, end.date, by = "6 months")
time.period = (cf.period * 6)/12
couponincome = rep(coupon/frequency * principal, ncashflows)
principalincome = rep(0,ncashflows)
principalincome[ncashflows] = principal
cashflow = couponincome + principalincome
# Yield to maturity
irr <- function(rate, time.period, cashflow, principal, price){
pv = cashflow * 1/(1+rate)^time.period
proceeds = principal * price
sum(pv) - proceeds
}
ytm = uniroot(irr, interval = c(lower = -.20, upper = .20), tol =.000000001,
time.period = time.period, cashflow = cashflow, principal = principal, price = price)$root
ytm.vec = c(rep(ytm,ncashflows))
pv.factor = 1/(1+ytm.vec)^time.period
pv.cashflow = cashflow*pv.factor
pv.price = pv.cashflow /(principal * (price/100))
pv.period = pv.price * time.period
cvx.time = time.period*(time.period + 1)
cf.cvx = (cashflow/(1+ytm)^(time.period + 2))/(principal * (price/100))
cf.cvx.period = cf.cvx * cvx.time
cashflow.table <- data.frame(Period = cf.period, Time = time.period,
Cashflow = cashflow, PVFactor = pv.factor,PV = pv.cashflow, PV.Price = pv.price,
pv.period = pv.period, cvx.time = cvx.time, cf.cvx = cf.cvx,
cf.cvx.period = cf.cvx.period)
cashflow.table
(sum(pv.period) / (price * 100))/( 1+ (ytm/frequency))
.5 * ((sum(cf.cvx.period)/(price * 100)))
print(xtable(cashflow.table, digits = 4))
}
Bond.Cash.Flow <-function(issue.date, start.date, end.date, coupon, principal,
frequency, price){
library(lubridate)
issue.date <- as.Date(c(issue.date), "%m-%d-%Y")
start.date <- as.Date(c(start.date), "%m-%d-%Y")
end.date <- as.Date(c(end.date), "%m-%d-%Y")
price = price/100
# 30/360 day count calculation
d1 = day(issue.date)
m1 = month(issue.date)
y1 = year(issue.date)
d2 = day(end.date)
m2 = month(end.date)
y2 = year(end.date)
diff = (max(0, 30 - d1) + min(30, d2) + 360*(y2-y1) + 30*(m2-m1-1))/360
ncashflows = diff * frequency
cf.period = seq(1:ncashflows)
pmtdate = seq(start.date, end.date, by = "6 months")
time.period = (cf.period * 6)/12
couponincome = rep(coupon/frequency * principal, ncashflows)
principalincome = rep(0,ncashflows)
principalincome[ncashflows] = principal
cashflow = couponincome + principalincome
# Yield to maturity
irr <- function(rate, time.period, cashflow, principal, price){
pv = cashflow * 1/(1+rate)^time.period
proceeds = principal * price
sum(pv) - proceeds
}
ytm = uniroot(irr, interval = c(lower = -.20, upper = .20), tol =.000000001,
time.period = time.period, cashflow = cashflow, principal = principal, price = price)$root
ytm.vec = c(rep(ytm,ncashflows))
pv.factor = 1/(1+ytm.vec)^time.period
pv.cashflow = cashflow*pv.factor
pv.price = pv.cashflow /(principal * (price/100))
pv.period = pv.price * time.period
cvx.time = time.period*(time.period + 1)
cf.cvx = (cashflow/(1+ytm)^(time.period + 2))/(principal * (price/100))
cf.cvx.period = cf.cvx * cvx.time
cashflow.table <- data.frame(Period = cf.period, Time = time.period,
Cashflow = cashflow, PVFactor = pv.factor,PV = pv.cashflow, PV.Price = pv.price,
pv.period = pv.period, cvx.time = cvx.time, cf.cvx = cf.cvx,
cf.cvx.period = cf.cvx.period)
cashflow.table
(sum(pv.period) / (price * 100))/( 1+ (ytm/frequency))
.5 * ((sum(cf.cvx.period)/(price * 100)))
print(xtable(cashflow.table, digits = 4))
}
It is not clear what do you want to do since you don't give a precise context of the call of your function. So my answer will be partial.
Please assign default values to your arguments, especially one you have more than one argument to validate. Default arguments uses lazy evaluation in R and are really a powerful feature of the language.
Use stop and/or warning to throw an error/warning and catch it in its final call context to give the user a human message.
take a look at match.call(difficult for a beginner) to get the effective call of your function.
here an example using stop:
PresentValue <- function(interest.rate, number.periods=1, frequency=1) {
if (missing(interest.rate))
stop("Need to specify interest.rate as number between 0 and 1 for calculations.")
if (!is.numeric(interest.rate) )
stop("No numeric interest.rate specified.")
if (interest.rate <0 | interest.rate > 1)
stop("No valid interest.rate specified.")
## you do the same thing for other arguments
}
some tests:
PresentValue()
Error in PresentValue() :
Need to specify interest.rate as number between 0 and 1 for calculations.
> PresentValue("a")
Error in PresentValue("a") : No numeric interest.rate specified.
> PresentValue(5)
Error in PresentValue(5) : No valid interest.rate specified.
> PresentValue(0.9) ## normal use
Related
i am trying to use a code in a paper but the code for gurobi seems changed these days, it showed some error and i want to put the gurobi environment setting below into my optimization.
the gurobi environment setting is below :
function setup_gurobi_env(; quiet_mode = true, method_type = :barrier, use_time_limit = true, time_limit = 60.0)
env = Gurobi.Env()
if quiet_mode
setparams!(env; OutputFlag = 0)
end
if method_type == :barrier
setparams!(env; Method = 2)
elseif method_type == :method3
setparams!(env; Method = 3)
elseif method_type != :default
error("Enter a valid method type for Gurobi.")
end
if use_time_limit
setparams!(env; TimeLimit = time_limit)
end
return env
end
the author of the paper use the method below to use this setting:
function portfolio_simplex_jump_setup(Sigma::Matrix{Float64}, gamma::Float64; gurobiEnv = setup_gurobi_env(method_type = :default, use_time_limit = false))
(d, d2) = size(Sigma)
if d != d2
error("Sigma dimensions don't match")
end
mod = Model(with_optimizer(Gurobi.Optimizer, gurobiEnv))
#variable(mod, w[1:d] >= 0)
#constraint(mod, sum(w[i] for i = 1:d) <= 1)
#constraint(mod, w'*Sigma*w <= gamma)
function local_portfolio_oracle(c::Vector{Float64})
#objective(mod, Min, dot(c, w))
optimize!(mod)
z_ast = objective_value(mod)
w_ast = value.(w)
return (z_ast, w_ast)
end
return c -> local_portfolio_oracle(c)
end
i changed the function into this but it still showed error for not be able to use gurobi since my coding is too old.
function portfolio_simplex_jump_setup(; gurobiEnv = setup_gurobi_env(method_type = :default, use_time_limit = false))
mod = Model(Gurobi.Optimizer)
#variable(mod, 0 <=w[1:d] <= 1)
#constraint(mod, sum(w[i] for i = 1:d) <= 3)
function local_portfolio_oracle(c::Vector{Float64})
#objective(mod, Min, dot(c, w))
optimize!(mod)
z_ast = objective_value(mod)
w_ast = value.(w)
return (z_ast, w_ast)
end
return c -> local_portfolio_oracle(c)
end
i think the problem is in here
mod = Model(with_optimizer(Gurobi.Optimizer, gurobiEnv))
maybe gurobi just upload the new coding method?
Thank you to everyone who replied to me~
This is the current pattern to use Gurobi (taken from one of my academic codes):
const GRB_ENV = Gurobi.Env()
m = Model(()->Gurobi.Optimizer(GRB_ENV))
set_optimizer_attribute(m, "OutputFlag", 0)
set_optimizer_attribute(m, "TimeLimit", 100)
set_optimizer_attribute(m, "MIPGap", 0.001)
set_optimizer_attribute(m, "Threads", min(length(Sys.cpu_info()),16))
I think i did not write this code properly since it does not find the proper code inside the function :
comp_spread_CDS = function(loss, vec_ZC_prem, vec_ZC_def, vec_prob_suv_prem, vec_prob_surv_def)
{
nb_payment = lenght(vec__VC_prem)
nb_step = lengh(vec_ZC_def)
vec_prob_surv_prem_eff = vec_prob_surv_prem + c(1, vec_prob_surv_prem[1 :(nb_payment - 1)])
vec_tenor = rep(tenor, nb_payment)
vec_prob_def = c(1, vec_prob_surv_def[1:(nb_step-1)]) - vec_prob_surv_def
annuity = 0.5 * sum(vec_ZC_prem * vec_prob_surv_prem_eff * vec_tenor)
leg_def = los * sum( vec_ZC_def * vec_prob_def)
spread_CDS = leg_def / annuity
return(spread_CDS)
}
base = 10000
notional = 100
maturity = 5
recovery = 40/100
loss = 1 - recovery
int_rate = 3/100
intensity = 180/base
tenor = 3/12
time_step = 1/360
nb_payment = maturity/ tenor
nb_payment
nb_step = maturity/time_step
nb_step
c(1, vec_prob_surv_prem[1: nb_payment-1])
vec_prob_surv_prem_eff
As a result it is telling me that the object is not find by R.
vec_prob_surv_prem_eff
Erreur : objet 'vec_prob_surv_prem_eff' introuvable
thank you for your help
sincerely,
How do you guys handle console input validation? In C++, case/switch is my goto...
I was trying a recursive function but was getting locked in lower levels. Plus that might be overdoing it. I did manage a while loop with an "exclusive or" but, that is not really scalable.
function prob6()
println("Pick a number; any number:")
x = readline(stdin)
y = parse(Int64, x)
z = 0
println("Select 1 or 2")
p1 = readline(stdin)
p2 = parse(Int64, p1)
select = p2
while xor((p2 == 1), (p2 == 2)) == false
println("Select 1 or 2")
p1 = readline(stdin)
p2 = parse(Int64, p1)
select = p2
end
if select == 1
for i in 1:y
print("$i ")
z = z + i
end
else
z = 1
for i in 1:y
print("$i ")
z = z * i
end
end
println(z)
end
Any alternatives?
There are many ways. I usually create a validation loop to check the type of the input item, and will use tryparse instead of parse, since it will not throw an error if input is malformed:
function queryprompt(query, typ)
while true
print(query, ": ")
choice = uppercase(strip(readline(stdin)))
if (ret = tryparse(typ, choice)) != nothing
return ret
end
println()
end
end
n = queryprompt("Integer please", Int64)
println(n)
x = queryprompt("Float please", Float64)
println(x)
I'm trying to use a bit of code that I found in an academic journal (). I'm new-ish to R. I keep getting an error when I reach the code calling up the function "binHist" that says "could not find the function "binhist". I can't figure out if it's in a library/ package I need to install or if there's another problem with the code. Any help would be much appreciated. Here's the code I extracted from the article:
whichData = yourData
baseH = data.frame()
RunningSum = 0
for (i in 2:16) {
tempBin = NULL
tempBin = binhist(i, whichData$rt)
theMean = sum(tempBin)/(i)
Divisor = sum(tempBin)
new = data.frame()
for (j in 1:ncol(tempBin)) {
grabVal = (tempBin[j] - theMean)^2
names(grabVal) <- NULL
new = c(new,grabVal)
}
extra = i - ncol(tempBin)
NewSum = Reduce("+",new) + extra*((0 - theMean)^2)
StdDev = sqrt(NewSum /(i-1))
RowVal = StdDev /Divisor
RunningSum = RunningSum + RowVal
baseH = c(baseH, list(tempBin))
}
paste("Number of Trials:",Divisor)
paste("Modulo-Binning Score (MBS): ",RunningSum)
library(plyr)
baseNow = do.call(rbind.fill,baseH)
Im using chainer and im try to do topic modeling. The code for the training phase contains the following:
optimizer = O.Adam()
optimizer.setup(self.train_model)
clip = chainer.optimizer.GradientClipping(5.0)
optimizer.add_hook(clip)
j = 0
msgs = defaultdict(list)
for epoch in range(epochs):
print "epoch : ",epoch
data = prepare_topics(cuda.to_cpu(self.train_model.mixture.weights.W.data).copy(),
cuda.to_cpu(self.train_model.mixture.factors.W.data).copy(),
cuda.to_cpu(self.train_model.sampler.W.data).copy(),
self.words)
top_words = print_top_words_per_topic(data)
if j % 100 == 0 and j > 100:
coherence = topic_coherence(top_words)
for j in range(self.n_topics):
print j, coherence[(j, 'cv')]
kw = dict(top_words=top_words, coherence=coherence, epoch=epoch)
data['doc_lengths'] = self.doc_lengths
data['term_frequency'] = self.term_frequency
for d, f in utils.chunks(self.batchsize, self.doc_ids, self.flattened):
t0 = time.time()
self.train_model.cleargrads()
l = self.train_model.fit_partial(d.copy(), f.copy(), update_words = update_words, update_topics = update_topics)
prior = self.train_model.prior()
loss = prior * self.fraction
loss.backward()
optimizer.update()
msg = ("J:{j:05d} E:{epoch:05d} L:{loss:1.3e} "
"P:{prior:1.3e} R:{rate:1.3e}")
prior.to_cpu()
loss.to_cpu()
t1 = time.time()
dt = t1 - t0
rate = self.batchsize / dt
msgs["E"].append(epoch)
msgs["L"].append(float(l))
j += 1
logs = dict(loss=float(l), epoch=epoch, j=j, prior=float(prior.data), rate=rate)
print msg.format(**logs)
print "\n ================================= \n"
#serializers.save_hdf5("lda2vec.hdf5", self.model)
msgs["loss_per_epoch"].append(float(l))
whn i execute the code i get for example:
J:00200 E:00380 L:0.000e+00 P:-2.997e+04 R:2.421e+04
only the L(loss) dont change, can someone please help to know why this value remain zero?