For loop in R with many values - r

I have equations which I would like to test with many different values and find the one solution for those equations. So the idea is to find T_out, and all the other values are known. For this I want to test values from 45 to 30 in 0.001 steps.
T_out =326.5
for (i in seq(45, 30, by = -0.001)){
T_out=T_out-i;
Q_in=0.16*0.8*(316-300.4-T_out-300.4) / (log(316-300.4 / T_out-300.4));
Q_out=0.00762*1512*(316-T_out);
if (Q_in-Q_out==0){
break
end}
T_out_new=T_out-i;
}
But nothing happens. Do you know what is the mistake?

These are vectorised function and you should need for loop for this.
T_out = 326.5
vals = seq(45, 30, by = -0.001)
T_val = T_out - vals
Q_in = 0.16*0.8*(316-300.4-T_val-300.4) / (log(316-300.4 / T_val-300.4))
Q_out = 0.00762*1512*(316-T_val)
vals[which((Q_in - Q_out) == 0)]
However, none of the numbers satisfy the condition and it returns numeric(0). Maybe you need to adjust some values ?

Related

Calculate RSI indicator according to tradingview?

I would like to calculate RSI 14 in line with the tradingview chart.
According to there wiki this should be the solution:
https://www.tradingview.com/wiki/Talk:Relative_Strength_Index_(RSI)
I implemented this is in a object called RSI:
Calling within object RSI:
self.df['rsi1'] = self.calculate_RSI_method_1(self.df, period=self.period)
Implementation of the code the calculation:
def calculate_RSI_method_1(self, ohlc: pd.DataFrame, period: int = 14) -> pd.Series:
delta = ohlc["close"].diff()
ohlc['up'] = delta.copy()
ohlc['down'] = delta.copy()
ohlc['up'] = pd.to_numeric(ohlc['up'])
ohlc['down'] = pd.to_numeric(ohlc['down'])
ohlc['up'][ohlc['up'] < 0] = 0
ohlc['down'][ohlc['down'] > 0] = 0
# This one below is not correct, but why?
ohlc['_gain'] = ohlc['up'].ewm(com=(period - 1), min_periods=period).mean()
ohlc['_loss'] = ohlc['down'].abs().ewm(com=(period - 1), min_periods=period).mean()
ohlc['RS`'] = ohlc['_gain']/ohlc['_loss']
ohlc['rsi'] = pd.Series(100 - (100 / (1 + ohlc['RS`'])))
self.currentvalue = round(self.df['rsi'].iloc[-1], 8)
print (self.currentvalue)
self.exportspreadsheetfordebugging(ohlc, 'calculate_RSI_method_1', self.symbol)
I tested several other solution like e.g but non return a good value:
https://github.com/peerchemist/finta
https://gist.github.com/jmoz/1f93b264650376131ed65875782df386
Therefore I created a unittest based on :
https://school.stockcharts.com/doku.php?id=technical_indicators:relative_strength_index_rsi
I created an input file: (See excel image below)
and a output file: (See excel image below)
Running the unittest (unittest code not included here) should result in but is only checking the last value.
if result == 37.77295211:
log.info("Unit test 001 - PASSED")
return True
else:
log.error("Unit test 001 - NOT PASSED")
return False
But again I cannot pass the test.
I checked all values by help with excel.
So now i'm a little bit lost.
If I'm following this question:
Calculate RSI indicator from pandas DataFrame?
But this will not give any value in the gain.
a) How should the calculation be in order to align the unittest?
b) How should the calculation be in order to align with tradingview?
Here is a Python implementation of the current RSI indicator version in TradingView:
https://github.com/lukaszbinden/rsi_tradingview/blob/main/rsi.py
I had same issue in calculating RSI and the result was different from TradingView,
I have found RSI Step 2 formula described in InvestoPedia and I changed the code as below:
N = 14
close_price0 = float(klines[0][4])
gain_avg0 = loss_avg0 = close_price0
for kline in klines[1:]:
close_price = float(kline[4])
if close_price > close_price0:
gain = close_price - close_price0
loss = 0
else:
gain = 0
loss = close_price0 - close_price
close_price0 = close_price
gain_avg = (gain_avg0 * (N - 1) + gain) / N
loss_avg = (loss_avg0 * (N - 1) + loss) / N
rsi = 100 - 100 / (1 + gain_avg / loss_avg)
gain_avg0 = gain_avg
loss_avg0 = loss_avg
N is the number of period for calculating RSI (by default = 14)
the code is put in a loop to calculate all RSI values for a series.
For those who are experience the same.
My raw data contained ticks where the volume is zero. Filtering this OLHCV rows will directly give the good results.

For-loop where index does not start at 1 or 0 and is incremented by 30 instead of 1

I have the following:
include("as_mod.jl")
solvetimes = 50:200
timevector = Array{Float64}(undef,length(solvetimes))
for i in solvetimes
global T
T = i
include("as_dat_large.jl")
m, x, z = build_model(true,true)
setsolver(m, GurobiSolver(MIPGap = 2e-2, TimeLimit = 3600))
solve(m)
timevector[i-49] = getsolvetime(m)
end
plot(solvetimes,log.(timevector),
title = "solvetimes vs T", xlabel = "T", ylabel = "log(t)")
And this works great as long as my solvetimes vector is incremented by only 1. However, I'm interested in an 30-increment and it obviously does not work then since my timevector then goes out of bounds. Is there any way of solving this issue? I read about and attempted to use the push! function but to no avail.
I apologize if my question is not good but I don't see how to improve it. The question is essentially about for loops where the index does NOT start at 1 and is only incremented with 1 up to an upper bound, but rather a non-one increment and a start different from 0 or one, if that makes sense.
The : syntax in 50:200 or 50:30:200 creates a range object in Julia. These range objects are not only iterable but also implement the method getindex which means that you can simply access the steps in the range with a[index] syntax as if it is an array.
julia> solvetimes = 50:30:200 # 50, 80, 110, 140, ...
50:30:200
julia> solvetimes[3]
110
You can solve your problem in several ways.
First, you can introduce an itercount variable to count the number of iterations and know at which index of timevector you will put the solve-time.
solvetimes = 50:30:200 # increment by 30
timevector = Vector{Float64}(undef,length(solvetimes))
itercount = 1
for i in solvetimes
...
timevector[itercount] = getsolvetime(m)
global itercount
itercount += 1
end
Other way would be to create an empty timevector and push!.
solvetimes = 50:30:200 # increment by 30
timevector = Float64[] # an empty Float64 vector
for i in solvetimes
...
push!(timevector, getsolvetime(m)) # push the value `getsolvetime(m)` into `timevector`
end
push! operation may require julia to allocate memory and copy data to compensate increasing array size, hence might not be very efficient, although it does not really matter in your problem.
Another way would be to iterate from 1 to length of solvetimes. Your loop control variable is still incremented one-by-one but now it represents the index in solvetimes rather than the time point.
solvetimes = 50:30:200 # increment by 30
len = length(solvetimes)
timevector = Vector{Float64}(undef, len)
for i in 1:len
global T
T = solvetimes[i]
...
timevector[i] = getsolvetime(m)
end
With these modifications, kth value in timevector, timevector[k] stands for the solve-time for solvetime[k].
You might also find other ways to solve the issue, like using Dicts etc.

decimal increments in loop for R

I would like to find the value of "p" below (which is between 0 and 1), knowing the following equations:
RI_26 = min(IR,na.rm=FALSE)
RI_min = 100-(sse*SUM/((1+p)*Dotation2017*100))^(1/p)
where RI_26 is the minimum of resources index of my 26 area. It is a constant in my case. In RI_min, sse and Dotations2017 are 2 constants and p is a unknown. I know that RI_26 should be equal to RI_min.
It would be easy to solve it, but SUM (which is present in RI_min) is as well unknown as it is a function of p as following:
`sum.function = function(p){
SUM <- c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
for(i in 1:length(Canton))
if(IR[i] < 100) {
SUM[i] <- (100-IR[i])^(1+p)*Pop[i]
SUM[27] <- SUM[27]+SUM[i]
}
SUM <- round(SUM,0)
return(SUM[27])
}
SUM = sum.function(p)
SUM returns a number (or vector 1X1). To deal with it, I would like to find the value of p that satisfied:
RI_26/RI_min = 1
To do so, I would like to do a loop, beginning with p = 0 and then increasing the value of p by 0.01 until it reaches 1. The loop should return the value of p_star when the constraint is True (RI_26/RI_min = 1.00).
I don't have any idea how to do this but it could look like the following code:
p.function = function(){
for(...)
if(RI_26/RI_min = 1.000000) {
p_star <- p
}
return(p_star)
}
So the function will return the value of p_star when RI_26/RI_min = 1.000000. What am I suppose to write in my function: p.function to increment "p" and have the result that I want? Any idea?
for (i in seq(0, 1, by = 0.1)) {
"Your code here"
}

R - Arrays with variable dimension

I have a weird question..
Essentially, I have a function which takes a data frame of dimension Nx(2k) and transforms it into an array of dimension Nx2xk. I then further use that array in various locations in the function.
My issue is this, when k == 2, I'm left with a matrix of degree Nx2, and even worse, if N = 1, I'm stuck with a matrix of degree 1x2.
I would like to write myArray[thisRow,,] to select that slice of the array, but this falls short for the N = 1, k = 2 case. I tried myArray[thisRow,,,drop = FALSE] but that gives an 'incorrect number of dimensions' error. This same issue arrises for the Nx2 case.
Is there a work around for this issue, or do I need to break my code into cases?
Sample Code Shown Below:
thisFunction <- function(myDF)
{
nGroups = NCOL(myDF)/2
afMyArray = myDF
if(nGroups > 1)
{
afMyArray = abind(lapply(1:nGroups, function(g){myDF[,2*(g-1) + 1:2]}),
along = 3)
}
sapply(1:NROW(myDF),
function(r)
{
thisSlice = afMyArray[r,,]
*some operation on thisSlice*
})
}
Thanks,
James

Cheapest way of doing max() on absolute values, but have max() preserve sign?

I have a 3-vector, let's say
v = vec3(-4, 2, 3)
I would like to do a max on the absolute values of the components, so the equivalent of:
max(abs(v[0]), max(abs(v[1]), abs(v[2]))) == 4
However, I have a requirement that I need to preserve the sign. So for example:
magic_max(v[0], magic_max(v[1], v[2])) == -4.
It's a trivial problem if I use conditional branching, but I'm trying to do this in as few operations as possible, and avoid branching. Any ideas on where to look? Maybe there's some bit-shifting magic that can be done?
I would determ the max AND the min of all values, and then decide what is abs larger
ma = max(v[0], max(v[1], v[2]));
mi = min(v[0], min(v[1], v[2]));
res = abs(mi) > ma ? mi : ma;
If you want to get the sign, replace the last line with an if
if (abs(mi) > ma) {
sign = -1;
res = mi;
} else {
sign = +1;
res = ma;
}
However, what should happen on (0, 0, 0)? no sign?

Resources