The script should try a range of values and get net profit for each one, then select the value with largest profit, but seems like that it changes the output only at the end of the for loop. Actually the output is just the first value tried (min value).
Any ideas to fix? (or bypass unnecessary lines in function for speeding the script)
//TEST FUNCTION
test(min, max, step) =>
max_fix = max -1
mx = min //INITIAL OUTPUT VALUE
p_values = array.new_float() //PROFITS ARRAY
for i = min to max_fix by step //TRY ALL VALUES IN RANGE
mx := mx + step //INCREMENT OUTPUT BY 1
array.push(p_values, strategy.netprofit) //PUSH NEW PROFIT VALUE INTO ARRAY
p_mx = array.max(p_values) //FIND LARGEST PROFIT VALUE
p_mx_index = array.indexof(p_values, p_mx) //FIND INDEX OF LARGEST PROFIT VALUE
mx := min + (p_mx_index * step) //GET THE OUT VALUE WITH BEST PROFIT
mx
ma = ta.sma(close, test(50, 100, 1))
plot(ma)
//
buy = close > ma
sell = close < ma
if buy
strategy.entry("Long", strategy.long)
if sell
strategy.entry("Short", strategy.short)
Related
I'd like to request help in form of pseudo-code for bouncing or "ping-ponging" a number in a range, by which I mean adding a number to another value in a range, where that number instead of exceeding the range or being clamped to it, is continuously bounced back into it.
Example
Consider the following variables:
Range: (-2, 2)
Starting value in the range: 1
Added value: 14
The number would start at 1 and go through 14 alterations, as following:
2
1
0
-1
-2
-1
0
1
2
1
0
-1
-2
-1
The code I am trying to write would only return the final number of this sequence, which is -1.
Specifications
— The code must not use a while loop.
— The code must be able to work with non-integer values.
— The code must be efficient and fail-proof.
Thank you in advance.
Just have a for loop that goes for the number of steps specified.
Inside the loop add to a running total the value of each step using a variable to hold the step value, and when you hit the limit multiply the step value by -1 to get it going in the other direction.
For the number of steps required
Add value to total
If total exceeds upper limit
Value *= -1
If value is less than lower limit
Value *= -1
Return the total when the loop ends
Edit: I'm on my phone and psedocode bit formatting got borked
First, compute cycle = 2 * (max - min) and find the largest integer n such that cycle * n is less than or equal to added value. One way to do this is to calculate full cycles = round_toward_zero(added value / cycle). We can immediately subtract from added value the value cycle * full cycles because moving by cycle returns you to where you started and headed in the same direction, so we only need to consider the portion of added value that is strictly greater than an even multiple of cycle. Let us define modified value = added value - cycle * full cycles.
Next, calculate position = starting position + modified value. Given that min <= starting position <= max, there are three cases for position:
position < min. In this case, modified value must have been negative, so we can simply "bounce right" by calculating position' = min + (min - position). There are two sub-cases now:
min <= position' <= max: simply return position' as the answer
max < position': we must "bounce back" again by calculating position'' = max - (position' - max). This time, position'' is guaranteed to be between min and max since modified value is guaranteed to to be between -2 * (max - min) and 0... so just return position''.
min <= position <= max. In this case, no additional bouncing is required, so just return position.
position > max. In this case, modified value must have been positive, so we can simply "bounce left" by calculating position' = max - (position - max). There are two sub-cases now:
position' < min: we must "bounce back" again by calculating position'' = min + (min - position'). This time, position'' is guaranteed to be between min and max since modified value is guaranteed to be between 0 and 2 * (max - min)... so just return position''.
min <= position' <= max: simply return position' as the answer
Example:
Range: (-2, 2)
Starting value in the range: 1
Added value: 14
min = -2
max = 2
starting position = 1
added value = 14
cycle = 2 * (max - min) = 2 * 4 = 8
full cycles = round_toward_zero(added value / cycle)
= round_toward_zero(14 / 8)
= round_toward_zero(1.75)
= 1
modified value = added value - cycle * full cycles
= 14 - 8 * 1
= 6
position = starting position + modified value
= 1 + 6
= 7
position = 7 > 2 = max
position' = max - (position - max)
= 2 - (7 - 2)
= 2 - 5
= -3
position' = -3 < -2 = min
position'' = min + (min - position')
= -2 + (-2 - -3)
= -2 + 1
= -1
Now, this might seem like a lot of calculations. For small numbers of steps, it might be faster just to do a loop. However, for large added values, this approach is significantly better.
I'm writing a diploma about vaccines. There is a region, its population and 12 month. There is an array of 12 values from 0 to 1 with step 0.01. It means which part of population should we vaccinate in every month.
For example if we have array = [0.1,0,0,0,0,0,0,0,0,0,0,0]. That means that we should vaccinate 0.1 of region population only in first month.
Another array = [0, 0.23,0,0,0,0,0,0, 0.02,0,0,0]. It means that we should vaccinate 0.23 of region population in second month and 0.02 of region population in 9th month.
So the question is: how to generate (using 3 loops) 12(months) * 12(times of vaccinating) * 100 (number of steps from 0 to 1) = 14_400 number of arrays that will contain every version of these combinations.
For now I have this code:
for(int month = 0;month<12;month++){
for (double step = 0;step<=1;step+=0.01){
double[] arr = new double[12];
arr[month] = step;
}
}
I need to add 3d loop that will vary number of vaccinating per year.
Have no idea how to write it.
Idk if it is understandable.
Hope u get it otherwise ask me, please.
You have 101 variants for the first month 0.00, 0.01..1.00
And 101 variants for the second month - same values.
And 101*101 possible combinations for two months.
Continuing - for all 12 months you have 101^12 variants ~ 10^24
It is not possible to generate and store so many combinations (at least in the current decade)
If step is larger than 0.01, then combination count might be reliable. General formula is P=N^M where N is number of variants per month, M is number of months
You can traverse all combinations representing all integers in range 0..P-1 in N-ric numeral system. Or make digit counter:
fill array D[12] with zeros
repeat
increment element at the last index by step value
if it reaches the limit, make it zero
and increment element at the next index
until the first element reaches the limit
It is similar to counting 08, 09, here we cannot increment 9, so make 10 and so on
s = 1
m = 3
mx = 3
l = [0]*m
i = 0
while i < m:
print([x/3 for x in l])
i = 0
l[i] += s
while (i < m) and l[i] > mx:
l[i] = 0
i += 1
if i < m:
l[i] += s
Python code prints 64 ((mx/s+1)^m=4^3) variants like [0.3333, 0.6666, 0.0]
Is it possible to limit a value in a given range, between min and max, using only arithmetic? That is, + - x / and %?
I am not able to use functions such as min, max nor IF-statements.
Let's assume I have a range of [1850, 1880], for any values < 1850, it should display 1850. For values > 1880, 1880 should be displayed. It would also be acceptable if only 1850 was displayed outside the range.
I tried:
x = (((x - xmax) % (xmax - xmin)) + (xmax - xmin)) % (xmax - xmin) + xmin
but it gives different values in the middle of the range for values lower than xmin.
If you know the size of the integer type, you can extract its sign bit (assuming two's complement) using integer division:
// Example in C
int sign_bit(int s)
{
// cast to unsigned (important)
unsigned u = (unsigned)s;
// number of bits in int
// if your integer size is fixed, this is just a constant
static const unsigned b = sizeof(int) * 8;
// pow(2, b - 1)
// again, a constant which can be pre-computed
static const unsigned p = 1 << (b - 1);
// use integer division to get top bit
return (int)(u / p);
}
This returns 1 if s < 0 and 0 otherwise; it can be used to calculate the absolute value:
int abs_arith(int v)
{
// sign bit
int b = sign_bit(v);
// actual sign (+1 / -1)
int s = 1 - 2 * b;
// sign(v) * v = abs(v)
return s * v;
}
The desired function looks like this:
It is useful to first shift the minimum to zero:
This function form can be computed as a sum of the two shifted absolute value functions below:
However the resultant function is scaled by a factor of 2; shifting to zero helps here because we only need to divide by 2, and shift back to the original minimum:
// Example in C
int clamp_minmax(int val, int min, int max)
{
// range length
int range = max - min;
// shift minimum to zero
val = val - min;
// blue function
int blue = abs_arith(val);
// green function
int green = range - abs_arith(val - range);
// add and divide by 2
val = (blue + green) / 2;
// shift to original minimum
return val + min;
}
This solution, although satisfies the requirements of the problem, is limited to signed integer types (and languages which allow integer overflow - I'm unsure of how this could be overcome in e.g. Java).
I found this while messing around in... excel. It only works for strictly positive integers. Although this is not more restrictive as the answer by meowgoesthedog because he also effectivly halves the integer space by dividing by two at the end. It doesn't use mod.
//A = 1 if x <= min
//A = 0 if x >= min
A = 1-(min-min/x)/min
//B = 0 if x <= max
//B = 1 if x > max
B = (max-max/x)/max
x = A*min + (1-A)*(1-B)*x + B*max
I found this solution in Python:
A = -1 # Minimum value
B = +1 # Maximum value
x = min(max(x, A), B)
After studying the vectorization methods used in the two links below, I've attempted to create a simple trading strategy template (code shown below) that can be vectorized in R for better speed vs a loop-based structure. I'm having difficulty vectorizing because variable state must be maintained and built upon such as:
1) The signals I'm using are not mutually exclusive for long and short (as in a simplistic MA crossover system).
2) Once triggered, the signal can wander until it gets an opposing indication (such as an RSI go short above 80, go long below 20 type system).
3) Positions are held for multiple periods so it isn't a case of enter on every signal or exit after a signal is false (I wish to be able to only enter once as in a Stop and Reverse or SAR system).
I consider this to be a simple example system but it is a bit more complex than the examples listed here:
http://blog.fosstrading.com/2011/03/how-to-backtest-strategy-in-r.html
Cumulative Return in Trading Strategy Test
System logic summary: The system starts flat then goes long (short) at the ask (bid) price when zscore is below (above) -2 (2). The system keeps track of performance statistics such as 'trades', 'wins', closed P&L (others omitted for simplicity). The system also keeps a running 'equity' for plotting after a system run.
# assume vectors bid, ask, and zscore containing those price series respectively
# pos = current position where 1 == long, -1 == short, 0 == flat
# entryP = entry price, pnl = open pnl, cpnl = closed pnl
pos = 0; entryP = 0.0; pnl = 0; cpnl = 0; trades = 0; wins = 0
ub = length(bid)
equity = rep(0, ub)
for (i in 10000:ub) {
pnl = 0
if (pos > 0) pnl = bid[i] - entryP
if (pos < 0) pnl = entryP - ask[i]
if (zscore[i] > 2.0 && pos != -1) { # go short
if (pos > 0) { # exit long and record pnl
cpnl = cpnl + pnl
if (pnl > 0) wins = wins + 1
trades = trades + 1
pnl = 0
}
pos = -1
entryP = bid[i]
} else if (zscore[i] < -2.0 && pos != 1) { # go long
if (pos < 0) { # exit short and record pnl
cpnl = cpnl + pnl
if (pnl > 0) wins = wins + 1
trades = trades + 1
pnl = 0
}
pos = 1
entryP = ask[i]
}
equity[i] = cpnl + pnl
}
# assume close-out of final position
cpnl = cpnl + pnl
if (pnl > 0) wins = wins + 1
if (pos != 0) trades = trades + 1
# plot equity chart and report performance stats
plot(equity, t='l', lwd=3)
cpnl;trades; cpnl / trades; wins/trades
Is it possible to vectorize this simple loop-based mean reversion trading system in R?
" I'm having difficulty vectorizing because variable state must be maintained "
That sums it all. You can't avoid loops if your result in any iteration depends on previous iterations.
Provided the below values
start value = 1
End Value = 20
Interval = 5
I have been provided a number 6. I have to find the range of numbers in which the number 6 falls say now the answer is 6-10.
If the given number is greater than the end value then return the same number.
Is there any formula so that i can generate the range for the number?
UPDATE
I tried the below solution, But it is not working if the range interval is changed,
$end_value = $start_value + $range_interval;
// we blindly return the last term if value is greater than max value
if ($input_num > $end_value) {
return '>' . $end_value;
}
// we also find if its a first value
if ($input_num <= $end_value && $value >= $start_value) {
return $start_value . '-' . $end_value;
}
// logic to find the range for a given integer
$dived_value = $input_num/$end_value;
// round the value to get the exact match
$rounded_value = ceil($dived_value);
$upper_bound_range = $rounded_value*$end_value;
$lower_bound_range = $upper_bound_range - $end_value;
return $lower_bound_range . '-'. $upper_bound_range;
In (c-style) pseudocode:
// Integer division assumed
rangeNumber = (yourNumber - startValue) / rangeLength;
lower_bound_range = startValue + rangeNumber*rangeLength;
upper_bound_range = lower_bound_range + rangeLength-1;
For your input:
rangeNumber = (6-1)/5 = 1
lower_bound_range = 1 + 5*1 = 6
upper_bound_range = 10
and so range is [6, 10]
The answer depends on whether you talk about integers or floats. Since all your example numbers are integers, I assume you talk about those. I further assume that all your intervals contain the same number of integers, in your example 5, namely 1...5, 6...10, 11...15, and 16...20. Note that 0 is not contained in the 1st interval (otherwise the 1st interval had 6 numbers).
In this case the answer is easy.
Let be:
s the start value that is not contained in the 1st interval,
i the interval size, i.e. the number of integers that it contains,
p the provided number to which an interval should be assigned,
b the 1st integer in this interval, and
e the last integer in this interval.
Then:
b = s + (p-s-1)\i * i + 1 (here, "\" means integer division, i.e. without remainder)
e = b + i - 1
In your example:
s = 0, i = 5, p = 6, thus
b = 0 + (6-0-1)\5 * 5 + 1 = 6
e = 6 + 5 - 1 = 10