Moving everage - how to calculate? - trading

Please explain how to calculate the EMA indicator on trading candles?
I found the formula here:https://www.investopedia.com/ask/answers/122314/what-exponential-moving-average-ema-formula-and-how-ema-calculated.asp
But there is some strange, incomprehensible explanation, I would even say stupid.
It says there:
The formula for calculating the EMA is a matter of using a multiplier
and starting with the SMA:
Compute the SMA Calculate the multiplier for weighting the EMA
Calculate the current EMA
The calculation for the SMA is the same as computing an average or
mean. That is, the SMA for any given number of time periods is simply
the sum of closing prices for that number of time periods, divided by
that same number
Okay, so far everything is clear.
The following is written next:
So when it comes to calculating the EMA of a stock:
EMA=Price(t)×k+EMA(y)×(1−k)
where: t=today y=yesterday N=number of days in EMA k=2÷(N+1)
And from that moment begins, some kind of trash.
where in the EMA formula - SMA indicator?
WHY did they write about the calculation of SMA - if it is not used in any way in the ETA formula?
How can I calculate the EMA indicator - if there is an ETA indicator for yesterday inside the formula??
I got completely lost at the end.

I presume EMA is Exponential Moving Average. This is what the formula shown by the OP calculates. This is not really an average at all, since it doesn't give equal weight to all values. Instead it gives exponentially decaying weight to past values. The most recent value has weight k, the nth past value has weight (1-k) to the nth power.
The starting value of the EMA always has some influence: its weight is again (1-k) to the nth power where n is now one less than the total number of values processed, so its effect decays exponentially with time.
If you want a moving average of the last m values,
you have to keep an array of them and just sum the array and divide m. Each time you get a new value, you remove the oldest one from the array, shift everything along, insert the new one, and sum the array and divide m again. There is a slightly faster algorithm which avoids summing the array every time.
#define N 100 /* the number of items to average over */
double array[N]; /* the last N items, each divided by N */
double average;
double step(double x /* new item */) /* insert new item and recompute */ {
int i; /* indexing */
average -= array[0]; /* subtract oldest item from average */
for (i = 0; i < N - 1; ++i) {
array[i] = array[i+1]; /* shift old items down array */
}
x = x/N; /* apply weight 1/N to new item */
array[N-1] = x; /* add new item to array */
average += x; /* add new item to average */
return average;
}

Related

Random select in with a bias towards certain outcomes (ie 60/40)

Lets say I have 2 lists and I would like to randomly select a winner between the lists but I would like to select the winner from list A 60% of the time and from list B 40% of the time, how can that be done in Google Sheets?
You can randomly select names from a list using this formula
INDEX(A2:A, RANDBETWEEN(1, COUNTA(A2:A)))
Without knowing some more information on your setup here is a general formula that does what you're describing:
=IF(RAND()<=0.6,INDEX(A2:A, RANDBETWEEN(1, COUNTA(A2:A))),INDEX(B2:B, RANDBETWEEN(1, COUNTA(B2:B))))
Essentially it is rolling a random number between 0 and 1. If it is equal to or less than .6 (simulating 60%, since there is a 60% chance it will be less than or equal to .6) it then selects a random name from Column A, otherwise (bottom 40%) it selects from column B.
You can also replace the "0.6" with A1 in my example to have the weight be a dynamic number. Changing A1 to 75% for example will then compare the random value against less than or equal to .75.
EDIT: Image shows the wrong condition, I was corrected in the sense you want less than or equal to .6 and not greater than, I had the weights flipped.

How do I create an arrayformula to calculate the median of three different values from one row?

How do you create an arrayformula to calculate the median of three different values from one row in google sheet?
For example, I want to do ARRAYFORMULA for MEDIAN formula.
=ARRAYFORMULA(MEDIAN(A2:A,$B$2,$C$2))
where
A2: start date - 2020-07-22 10:00
B2: start hour - 8:00
C2: end hour - 17:30
And the result of MEDIAN(A2:A,B2,C2) is 10:00, but ARRAYFORMULA does not work. (the result is 00:00:00)
is it possible to make an Array for MEDIAN? Or is there any option to do that in other way?
Mean and median are not the same. Mean is essentially AVERAGE, while MEDIAN is the "middle-most" value in a set:
=AVERAGE(2,1,9) returns 4 [i.e., (1+2+9)/4 ]
=MEDIAN(2,1,9) returns 2 (i.e., the value in the middle if all the numbers were lined up from lowest to highest)
If you only have to compare three columns, you could get by with a sort of "brute force" value-to-value comparison array. For instance, in D2:
=ArrayFormula(IF(((A2:A-INT(A2:A)<B2:B)*(A2:A-INT(A2:A)>C2:C))+((A2:A-INT(A2:A)>B2:B)*(A2:A-INT(A2:A)<C2:C)),A2:A-INT(A2:A),IF((B2:B<(A2:A-INT(A2:A))*(B2:B>C2:C))+(B2:B>(A2:A-INT(A2:A))*(B2:B<C2:C)),B2:B,C2:C)))
In English, this says:
"If the first value is lower than the second AND higher than the third, OR if the first value is higher than the second AND lower than the third, it is the median. Return the first value.
If neither of those is true, check to see if the second value is lower than the first AND higher than the third, OR if the second value is higher than the first AND lower than the third. If so, it is the median. Return the second value.
If nothing has been true so far, then the third value must be the median. Return the third value."
The one additional thing is you'll notice I have E2:E-INT(E2:E). This gets rid of the date portion and leaves only the time, since in Google Sheets, dates are whole numbers while times are decimal portions less than 1. So removing the INTeger (i.e., whole) part of the cell value leaves only the decimal portion, which is the time. This is necessary so that the comparisons can be of-a-kind.
arrayformula for average:
=ARRAYFORMULA(TEXT(QUERY(TRANSPOSE(QUERY(TRANSPOSE(N(A2:C*1)),
"select "&TEXTJOIN(",", 1, IF(A2:A="",,
"avg(Col"&ROW(A2:A)-ROW(A2)+1&")"))&"")),
"select Col2"), "hh:mm"))
arrayformula for MEDIAN now possible:
=IFERROR(BYROW(A2:C10, LAMBDA(xx, TEXT(MEDIAN(xx), "hh:mm"))))

ArrayFormula Google Sheets - remove high and low from average

I'm trying to use an arrayformula to calculate the average across 7 columns while removing the max and min number from those columns. The tricky part is there is no preset limit on how may cell will be filled, each time its different.
I have the formula to calculate the average complete:
=ARRAYFORMULA(IF(ISBLANK($A$2:$A),"",IF($J$2:$J="Granted",($AO$2:$AO+$AP$2:$AP+$AQ$2:$AQ+$AR$2:$AR+$AS$2:$AS+AT2:AT)/6,0)))
I've tried using the Trimmean function but it isn't working with the array formula, =Trimmean(AO2:AU2,0.33) any suggestions on how to get it to work?
Assuming the values in the cells that you want to ignore are empty, you want :
Average of all cells that are filled and not maximum or minimum
Which is
Sum of all cells that are filled and not maximum or minimum / (number of filled cells - 2)
Thus
=(sum(YourRange)-max(YourRange)-min(YourRange))/(count(YourRange)-2)
should give you what you want

How to generate a certain amount of numbers and spread them randomly across a grid?

I want to generate the number 2 5 times and the number 1 10 times. I'm trying to spread these across a String Grid in Delphi randomly. I also want to fill the rest of the grid that isn't 1 or 2, with 0's. I have no idea how to even start here.
It would look something like this (P stands for player and there would only be 5 2's and 10 1's): https://gyazo.com/aeef05c3a92ce7847c0f42ad40faa733
Given a grid with dimensions m×n, create an array of length m * n. Put five 2's and 10 1's in the array, and fill the remainder with 0's. (We'll assume the product of m and n is at least 15.) Shuffle the array. Copy each element of the shuffled array into successive cells in the grid.
While the approach represented in Robs answer will do the job I personally think it is way to complicated for it's purpose.
So what would be more simpler approach?
Well your goal is to place these numbers at random positions in grid.
How do you determine position of some object in a grid? You do it by its X (Column) and Y (Row) coordinates.
So how do you get random position in a grid? Simple chose two random values for X and Y coordinates.
As for placing certain numbers of number 1 and number 2 use two simple loops.

2D array - checking for column with most "on" values

So I have a 2D array of "1" and "0" values, a value is either on or off, this can generate shapes and I want to check for vertical lines, for example:
[0,0,1,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,1,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[1,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
that has a vertical line in column 5 so we will return those ones and strip all other results (change the 1's that aren't part of that line to 0's...)
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
[0,0,0,0,1,0,0,0]
My 2 dimensional array is much more complex, it is about a 300x600 2D array. In-order to visually see the values I generated UIViews with red background and stuck them on the screen in a view the size of my array. This is what the returned image was (the blue arrow was later photoshopped in to indicate the longest vertical line (the values we want to keep)
So what's a good method to find the longest vertical line (of "1" values) in a 2 dimensional array and change all other values to zero. (So that if I render the array in a visual graph format again only this is displayed (other red dots are fading out because they have been changed from "1" values to "0" values.)
I was thinking maybe something along the lines of generating a for-loop that would keep track of all of the "1" values in each column and a set of maybe any given 6 columns that are consecutively next to each other that have the largest amount of "1" values is the area (6 columns wide) where the longest vertical line is most likely located, but I can see a few issues with this, also I don't know how to get the rows that are part of that line after I have the columns.... hmmmm
*Note: I am making my "2 dimensional array" by just have a variable for the fixed number of columns and then I have an array that just has all of the values for all column/row combinations. For example a 3x3 board would be [0,0,0,0,1,0,0,0,0] which I can then understand means this:
[0,0,0]
[0,1,0]
[0,0,0]
Because I know there is always 3 columns per row.
[row1column1,row1column2,row1column3,row2column1,row2column2,row2column3,row3column1,row3column2,row3column3]
Here's some sample code (you'll need to take care of the allocations and some semantics - e.g: assigning one array to another)
int array2d[]; // which is 1d from what I understood - this holds your initial values
int columnCount; // you already have the number of columns, this is the var that's holding it
int maxColumn[], column[]; // these will hold the values of the maximum column and the current looped column
int maxIndex = 0, max=0; // used to determine which of the columns is the longest
int rowCount = array2d.count/columnCount; // find out how many rows there are
// first loop through the entire array, set everything to '0', while storing the values of the longest column (so far) in a different array
for(int i=0; i<columnCount; i++){
int columnSum = 0;
int index = i;
// go through every row of the column i
for(int j=0; j<rowCount; j++, index+=rowCount){
columnSum=columnSum+array2d[index];
column[j]=array2d[index];
array2d[index]=0;
}
if(columnSum>max){
max = columnSum;
maxIndex = i; // the column index
maxColumn = column;
}
}
// we found the longest column (maxIndex), now we need to set its values back to what they were previously
int index = maxIndex;
for(int j=0; j<rowCount; j++, index+=rowCount){
array2d[index]=maxColumn[j];
}
Since you want to find the longest of 6 consecutive columns, I believe that setting columnCount/=6; should work (it'll also make the rowCount=rowCount*6)
Your requirements aren't very precise, which makes me think you need to think harder about what you want, or state it more clearly. Take a look at the attached figure:
It's six pixels wide, so I image you could get this sort of a chain in your image. There's no connected sequence of 1's longer than 4 in any of the columns, yet the chain itself is 18 pixels long. Would you need to deal with a situation like this? If yes, then just summing over individual columns isn't enough; you need a more sophisticated method, like finding "connected components".

Resources