DAX - Running Percentage Over Time? - charts

I'm working on plotting a Percentage Over Time. I have my measures configured and working properly on a daily basis but what I would like is for a running percentage / rolling average.
I've attached the Table, Rate Formula, Percentage Formula and Graph. The Graph lets me know that it is doing the calculation on a daily basis instead of a rolling basis by the huge difference of today's date.
Rolled Rate =
VAR STARTDATE = FIRSTDATE('Date'[Date])
VAR Result =
CALCULATE(
'RAW - ALL'[RR Division],
'RAW - ALL'[LCRBA Approved TimeStamp] >= STARTDATE,
ALL('RAW - ALL')
)
RETURN
Result
RTN =
VAR STARTDATE = FIRSTDATE('Date'[Date])
VAR RESULT =
CALCULATE(DISTINCTCOUNT('RAW - ALL'[TicketNumber]),
FILTER('RAW - ALL', 'RAW - ALL'[Final Status] = "LCRB Approved"),
FILTER('RAW - ALL', NOT 'RAW - ALL'[Discussion Thread Topic] = "N/A"),
FILTER ('RAW - ALL', 'RAW - ALL'[LCRBA Approved TimeStamp] >= STARTDATE))
RETURN
Result
RR Division =
calculate (DIVIDE([RTN],'RAW - ALL'[ATD],0))
I can't post pictures, reputation isn't high enough.

Related

Power BI - Date calculations for a non standard month

Power BI Desktop
Version: 2.73.5586.984 64-bit (September 2019)
I am creating a calculated column to determine if a ticket has been completed in a "Current" or "Backlog" state. Our reporting period month goes from the 26th of the month to the 25th. If a ticket was completed in the reporting period m/26 - m/25 it would be considered "Current." If the ticket was completed outside of that time frame then it would be "Backlog." Also, if the current ticket has not been completed but still has the possibility of being completed in the same reporting period then that would be listed as "Current", but if it goes on to the next reporting month then it would be "Backlog."
Example:
Created 1/1/2021 & Completed 1/10/2021 = Current
Created 1/1/2021 & Completed 3/18/2021 = Backlog
Created 1/25/2021 & Completed 1/26/2021 = Backlog
Created 4/20/2021 & Not Completed & Today [4/30/2021] = Backlog
Created 4/29/2021 & Not Completed & Today [4/30/2021] = Current
I have written the following DAX to handle this but I seem to run into issues after the end/at the start of the reporting period, where the calculations don't work properly and everything lists as either current or backlog.
I also have a helper column in my Date Table that determines what the current reporting period is based on the current day, but I am not using it in this formula, but can if it would make it more efficient.
What is a better/proper way to do this?
Current/Backlog Caluclated Column:
Current_Backlog =
VAR CreatedDay = Day(IR_SR[Created_Date])
VAR CompletedDay = Day(IR_SR[Completed_Date])
VAR CreatedMonth = Month(IR_SR[Created_Date])
VAR CompletedMonth = Month(IR_SR[Completed_Date])
VAR CreatedMonthAdd = Month(IR_SR[Created_Date])+1
VAR CompletedMonthAdd = Month(IR_SR[Completed_Date])+1
VAR CurrentMonth = Month(TODAY())
VAR CurrentMonthAdd = Month(TODAY())+1
VAR CurrentDay = Day(TODAY())
RETURN
//If the date the ticket was completed is before the 26th and the created and completed month match, mark as current
IF(CompletedDay < 26 && CreatedMonth = CompletedMonth, "Current",
//If the completed date is after or equal to the 26th see if the created month plus one and completed month plus one match, mark as current
IF(CreatedDay >= 26 && CompletedDay >= 26 && CreatedMonthAdd = CompletedMonthAdd, "Current",
//If the completed date is after or equal to the 26th and the created date is after or equal to the 26th see if the created and completed month plus one match, mark as current
IF(CreatedDay >= 26 && CreatedMonthAdd = CompletedMonth, "Current",
//If the ticket is not completed and the created date is less then the 26th and the created month and current month match, mark as current
IF(IR_SR[Open/Closed] = "Open" && CurrentDay < 26 && CreatedDay < 26 && CreatedMonth = CurrentMonth, "Current",
//If the ticket is not completed and the created date is greater then the 26th and the created month and current month match plus one, mark as current
IF(IR_SR[Open/Closed] = "Open" && CurrentDay >= 26 && CurrentDay < 1 && CreatedDay >= 26 && CreatedMonthAdd = CurrentMonthAdd, "Current",
IF(IR_SR[Open/Closed] = "Open" && CurrentDay < 26 && CurrentDay >= 1 && CreatedDay >= 26 && CreatedMonthAdd = CurrentMonth, "Current",
"Backlog"))))))
Current Reporting Month:
= Table.AddColumn(#"Inserted Day Name", "Reporting_Period", each if Date.Day([Date]) >= 26
then Date.StartOfMonth(Date.AddMonths([Date], 1))
else Date.StartOfMonth([Date]))
an advice in this case. Compare both DAX formula in the performance analyizer inside Power BI and check how much time spent the calculation.
I guess all your data are imported, in this case data are cached, so first problem about performance is solved.
Anyway, paste second part of your DAX code and I'll check it.
Thanks

how to create time period from-to based on current time in flutter/dart

I have list of delivery time options:
11am - 2pm
3pm - 6pm
6pm - 9pm
9pm - 11pm
i want to create list of delivery time and excluding the the option that contains the current time.
For example if the current time is 5pm the list should be like this:
[6pm - 9pm , 9pm - 11pm]
How i can achieve this using Flutter/Dart ?
Just filter the list of delivery time with function map and keyTime is the mark time for the start of delivery time:
var listPeriod = ["11am - 2pm", "3pm - 6pm", "6pm - 9pm", "9pm - 11pm"];
var keyTime = [11, 15, 18, 21];
var currentTime = DateTime.now().hour;
var listFilteredPeriod = listPeriod.map((period) {
var index = listPeriod.indexOf(period);
if (currentTime < keyTime[index]) {
return period;
}
}).toList();

PowerBI end of month

I'm using monthly data and trying to display YoY% calculations.
However, my code is not robust for different end-of-month dates caused by leap years, I think.
Value YoY% 2 =
VAR START_DATE = DATEADD('DATA'[Date], -12, MONTH)
RETURN
DIVIDE(SUM(DATA[Value]), CALCULATE(SUM(DATA[Value]),START_DATE))-1
I'm very much a power BI novice. Thank you for your help.
Try the following:
Value YoY% 2 =
VAR Curr_Year = YEAR(SELECTEDVALUE(DATA[Date]))
VAR Last_Year = Curr_Year - 1
RETURN
DIVIDE(
CALCULATE(SUM(DATA[Value]), FILTER(DATA, YEAR(DATA[Date]) = Curr_Year)),
CALCULATE(SUM(DATA[Value]), FILTER(DATA, YEAR(DATA[Date]) = Last_Year))
)

Relative Strength Index in Swift

I am trying to code an RSI (which has been a good way for me to learn API data fetching and algorithms already).
The API I am fetching data from comes from a reputable exchange so I know the values my algorithm is analyzing are correct, that's a good start.
The issue I'm having is that the result of my calculations are completely off from what I can read on that particular exchange and which also provides an RSI indicator (I assume they analyze their own data, so the same data as I have).
I used the exact same API to translate the Ichimoku indicator into code and this time everything is correct! I believe my RSI calculations might be wrong somehow but I've checked and re-checked many times.
I also have a "literal" version of the code where every step is calculated like an excel sheet. It's pretty stupid in code but it validates the logic of the calculation and the results are the same as the following code.
Here is my code to calculate the RSI :
let period = 14
// Upward Movements and Downward Movements
var upwardMovements : [Double] = []
var downwardMovements : [Double] = []
for idx in 0..<15 {
let diff = items[idx + 1].close - items[idx].close
upwardMovements.append(max(diff, 0))
downwardMovements.append(max(-diff, 0))
}
// Average Upward Movements and Average Downward Movements
let averageUpwardMovement1 = upwardMovements[0..<period].reduce(0, +) / Double(period)
let averageDownwardMovement1 = downwardMovements[0..<period].reduce(0, +) / Double(period)
let averageUpwardMovement2 = (averageUpwardMovement1 * Double(period - 1) + upwardMovements[period]) / Double(period)
let averageDownwardMovement2 = (averageDownwardMovement1 * Double(period - 1) + downwardMovements[period]) / Double(period)
// Relative Strength
let relativeStrength1 = averageUpwardMovement1 / averageDownwardMovement1
let relativeStrength2 = averageUpwardMovement2 / averageDownwardMovement2
// Relative Strength Index
let rSI1 = 100 - (100 / (relativeStrength1 + 1))
let rSI2 = 100 - (100 / (relativeStrength2 + 1))
// Relative Strength Index Average
let relativeStrengthAverage = (rSI1 + rSI2) / 2
BitcoinRelativeStrengthIndex.bitcoinRSI = relativeStrengthAverage
Readings at 3:23pm this afternoon give 73.93 for my algorithm and 18.74 on the exchange. As the markets are crashing right now and I have access to different RSIs on different exchanges, they all display an RSI below 20 so my calculations are off.
Do you guys have any idea?
I am answering this 2 years later, but hopefully it helps someone.
RSI gets more precise the more data points you feed into it. For a default RSI period of 14, you should have at least 200 previous data points. The more, the better!
Let's suppose you have an array of close candle prices for a given market. The following function will return RSI values for each candle. You should always ignore the first data points, since they are not precise enough or the number of candles is not the 14 (or whatever your periods number is).
func computeRSI(on prices: [Double], periods: Int = 14, minimumPoints: Int = 200) -> [Double] {
precondition(periods > 1 && minimumPoints > periods && prices.count >= minimumPoints)
return Array(unsafeUninitializedCapacity: prices.count) { (buffer, count) in
buffer.initialize(repeating: 50)
var (previousPrice, gain, loss) = (prices[0], 0.0, 0.0)
for p in stride(from: 1, through: periods, by: 1) {
let price = prices[p]
let value = price - previousPrice
if value > 0 {
gain += value
} else {
loss -= value
}
previousPrice = price
}
let (numPeriods, numPeriodsMinusOne) = (Double(periods), Double(periods &- 1))
var avg = (gain: gain / numPeriods, loss: loss /numPeriods)
buffer[periods] = (avg.loss > .zero) ? 100 - 100 / (1 + avg.gain/avg.loss) : 100
for p in stride(from: periods &+ 1, to: prices.count, by: 1) {
let price = prices[p]
avg.gain *= numPeriodsMinusOne
avg.loss *= numPeriodsMinusOne
let value = price - previousPrice
if value > 0 {
avg.gain += value
} else {
avg.loss -= value
}
avg.gain /= numPeriods
avg.loss /= numPeriods
if avgLoss > .zero {
buffer[p] = 100 - 100 / (1 + avg.gain/avg.loss)
} else {
buffer[p] = 100
}
previousPrice = price
}
count = prices.count
}
}
Please note that the code is very imperative to reduce the amount of operations/loops and get the maximum compiler optimizations. You might be able to squeeze more performance using the Accelerate framework, though. We are also handling the edge case where you might get all gains or losses in a periods range.
If you want to have a running RSI calculation. Just store the last RSI value and perform the RSI equation for the new price.

Speed upgrade for loop

I am analysing intra-day volume profiles on stocks. I have built a (rough) piece of code that does 2 things well, but slowly. One stock can have north of 200k trades over a given period and I want to analyse around 200 stocks.
My code looks over 3 months' worth of trade data, binning the data into 10 minute buckets for each day. I do this to make sure a stock trades at least x value per bucket. I then aggregate the intra day buckets to just time buckets to get a sense of the average volume distribution.
Code sample below just shows how I bin data and then aggregate by bin:
% Totals by time bucket
for i = 1:size(VALUE,1)
MyDay = day(datenum(sprintf('%d',VALUE(i,1)),'yyyymmdd'));
MyMonth = month(datenum(sprintf('%d',VALUE(i,1)),'yyyymmdd'));
MyYear = year(datenum(sprintf('%d',VALUE(i,1)),'yyyymmdd'));
StartHour = hour(VALUE(i,2));
StartMinute = minute(VALUE(i,2));
EndHour = hour(VALUE(i,3));
EndMinute = minute(VALUE(i,3));
if StartMinute ~= 50
t = (day(MyTrades(:,1)) == MyDay & month(MyTrades(:,1)) == MyMonth & year(MyTrades(:,1)) == MyYear & hour(MyTrades(:,1)) == StartHour & minute(MyTrades(:,1)) >= StartMinute & minute(MyTrades(:,1)) <= EndMinute);
else
t = (day(MyTrades(:,1)) == MyDay & month(MyTrades(:,1)) == MyMonth & year(MyTrades(:,1)) == MyYear & hour(MyTrades(:,1)) == StartHour & hour(MyTrades(:,1)) < EndHour & minute(MyTrades(:,1)) >= StartMinute);
end
tt = MyTrades(t,:);
MyVALUE(i,1) = sum(tt(:,5));
end
% Aggregate totals
for ii = 1:50
VWAP(ii,1) = datenum(0,0,0,9,0,0)+datenum(0,0,0,0,10,0)*ii-datenum(0,0,0,0,10,0) ;
VWAP(ii,2) = datenum(0,0,0,9,0,0)+datenum(0,0,0,0,10,0)*ii;
StartTime = VWAP(ii,1);
temp = (VALUE(:,2) == StartTime);
temp2 = VALUE(temp,:);
VWAP(ii,3) = sum(temp2(:,4))/100;
end
Is there a more elegant and (more importantly) faster way of calculating these types of "brute force" analyses?
instead of using a complex data like DateNumber, use the timestamp and make the dateenum only one time for value.
you'll have to rewrite completly your code, but thinking with timestamp is more computing (and DB) friendly
Here some help to convert from timestamp in DateNumber: http://www.mathworks.it/matlabcentral/newsreader/view_thread/119237