Excluding Outliers from Avg Calculations at the dimension level in Qlik - average

All,
I need to plot monthly average trend. Each month behaves differently hence the need to exclude outliers at the month level. This calculation needs to be dynamic if I need to look at the trend by a certain category (the outliers need to be recalculated at the category level by each month)
here is what I tried:
I created a variable
vOutlier = Fractile(count , 0.75 ) + 1.5 *(Fractile(count , 0.75 ) - Fractile(count , 0.25 ))
then I used it in the set analysis
avg({$<Values = {"<=Fractile(Values , 0.75 ) + 1.5 *(Fractile(Values , 0.75 ) - Fractile(Values , 0.25 ))"}>} Values)
and avg({$<Values = {"<=$(=$(vOutliers))"}>} Values)
If you need a sample QVF, please find it here on the Qlik forum.

Related

Charting OHLC candle with SMA 200 using mplfinance plot function

I'm using mplfinance plot function to draw OHLC candlestick chart of a symbol. OHLC data is of 2 min timeframe. Also, I'm plotting sma 20 period and sma 200 period on the same chart. Because of sma200, the number of candles which are displayed on chart is quite huge (almost two days of 2min candle)
Since moving average is calculated internally by plot function so I've to pass the two days of 2 min candle to plot function so that I could get some data points of sma200. Candlestick chart is saved as png file. Now because of around 300 candles displayed on chart (sma20 and sma200 line also displayed), candles are not very clearly displayed.
Is there a way to restrict number of candles which get displayed on chart. If I slice my dataframe to lets say 30 candle, then sma200 will not be calculated in that case due to insufficient number of candles. What I need is sma200 with complete dataset but only fixed number of candle or for a fixed duration chart get displayed like last one hour candle data only.
mpf.plot(df, type='candle', style='charles',
title=title,
ylabel='Price',
ylabel_lower='Shares \nTraded',
mav=(20,200),
savefig=file)
I would suggest that you calculate your own moving average, and plot it using mpf.make_addplot(). This will allow you to calculate a moving average based on one-minute or two-minute candles, while plotting five-minute or ten-minute candles. For example:
# calculate mav values
mav20 = twominute_df['Close'].rolling( 20).mean()
mav200 = twominute_df['Close'].rolling(200).mean()
# resample:
resample_ohlcmap = {'Open' :'first',
'High' :'max',
'Low' :'min',
'Close' :'last',
'Volume':'sum'
}
tenminute_df = twominute_df.resample('10T').agg(resample_ohlcmap)
# plot ten-minute candles with two-minute mavs:
apmavs = [ mpf.make_addplot(mav20),
mpf.make_addplot(mav200) ]
mpf.plot(tenminute_df, type='candle', style='charles',
title=title, ylabel='Price', ylabel_lower='Shares \nTraded',
addplot=apmavs, savefig=file)
References:
resampling
moving average calculation
Thanks Daniel for your help. I'm now able to plot a chart for 60 candles with sma 20 and 200.
Well I don't need resampling as my chart timeframe and moving average time frame both are same.
Please find my code snippet.
# get list of close prices from symbol_docs. symbol_docs contain 2 min OHLC.
close_list = list(map(lambda a: a['close'], symbol_docs))
# sma20 and 200 calculated using ta-lib
sma20 = sma(close_list, 20)
sma200 = sma(close_list, 200)
# call to plot_chart function
plot_chart('TCS', symbol_docs, sma20, sma200)
def plot_chart(symbol, docs, sma20, sma200):
df = pd.DataFrame(docs)
df = df.set_index(['time'])
df.rename(columns={'open': 'Open', 'close': 'Close', 'high': 'High', 'low': 'Low'},
inplace=True)
title = symbol.upper() + ' - 2min'
file = saved_chart_image_abs_path + symbol + '.png'
df['sma20'] = sma20
df['sma200'] = sma200
df_sliced = df[-60:]
apmavs = [mpf.make_addplot(df_sliced['sma20']), mpf.make_addplot(df_sliced['sma200'])]
mpf.plot(df_sliced, type='candle', style='charles',
title=title,
ylabel='Price',
ylabel_lower='Shares \nTraded',
addplot=apmavs,
savefig=file)
telegram_message_sender.send_document(file)
os.remove(file)
Below chart is sent as a document on my telegram group :)

Can't compute an aggregation of an aggregation in Tableau

I'm trying to compute the standard deviation of a nested calculated measure.
In this example, different countries produce a number of items every month, each with a specific colour. I'm trying to sort countries by the standard deviation of the monthly ratio between warm and cold colours for every country.
The underlying data is as follows (each row is an item produced at a certain date by a certain country):
date country colour
-------------------------------
2020-03-01 France Blue
2020-03-01 UK Red
2020-03-02 USA Green
2020-03-03 Belgium Red
2020-03-04 UK Green
The first calculated measures identifies all the items which are either warm or cold colours:
WARM_COLOUR:
{INCLUDE [Colour]: SUM(If [Colour] = 'Red' or [Colour] = 'Orange' or [Colour] = 'Yellow' THEN 1 ELSE 0 END)}
COLD_COLOUR:
{INCLUDE [Colour]: SUM(If [Colour] = 'Blue' or [Colour] = 'Green' THEN 1 ELSE 0 END)}
Then, I compute the ratio between warm and cold colours:
WARM_COLD_RATIO
sum([WARM_COLOR]) / (sum([WARM_COLOUR]) + SUM([COLD_COLOUR]))
Finally, I want to compute, for every country, the standard deviation of this ratio, but this produces an error:
{INCLUDE [Country]: STDEV([WARM_COLD_RATIO])}
^^^^^ Error: argument to STDEV is already an aggregation and can't be aggregated further
The final desired result is that I want to sort countries by descending order of standard deviation of the warm/cold colours ratio, per time period (e.g. month). Specifically, a country for which the warm/cold ratio would vary a lot every month, would come on top, whereas a country which gets the same warm/cold ratio every month would come last.
Table calculations can't be inside LOD calculations.
Any reason it really needs to be a LOD? Are there good table calculation alternative formulas, such as WINDOW_STDEV?
WINDOW_STDEV([WARM_COLD_RATIO])

Swift - How to set x-Axis to show hourly intervals using iOS Charts

I have the following data:
2019-08-14T13:00:00.000Z, 0.0015378000
2019-08-14T12:30:00.000Z, 0.0015172000
2019-08-14T12:00:00.000Z, 0.0014922000
2019-08-14T11:30:00.000Z, 0.0014706000
2019-08-14T11:00:00.000Z, 0.0014229000
2019-08-14T10:30:00.000Z, 0.0000989000
2019-08-14T10:00:00.000Z, 0.0000736000
2019-08-14T09:30:00.000Z, 0.0000508000
2019-08-14T09:00:00.000Z, 0.0000214000
2019-08-13T17:30:00.000Z, 0.0012805000
And have plotted this data into a Line Chart using the Charts library as shown below:
The data appears correct in the graph, however I've noticed that the x Axis is showing a scale that is not hourly, which I would ideally like to show.
The following code was applied to generate the above graph in an attempt to set an hourly scale on the x-Axis:
xAxis.drawAxisLineEnabled = true
xAxis.drawGridLinesEnabled = true
xAxis.granularityEnabled = true
xAxis.granularity = 1.0 / 24.0
When applying a granularity of 1.0 / 2.4 however, I was able to show a 10 hour interval on the graph as shown below:
It seems that the granularity does not line up to the hourly rate for the given graph, which may be associated with the fact that it contains a minimum interval between axis-values (In my case the maximum duration can be up to 2 days).
Is there a way to lock/snap the x-Axis grid to an hourly scale?
While I believe this is a workaround, I was able to snap the grid to an hourly basis for up to 5 x-axis labels using the following code (where diff is the date range in days presented on the graph:
// Determine a reasonable scale that complies to an hourly grid (Assume no more than 5 labels on grid)
let hourRange = diff * 24.0
let interval = Int(hourRange.rounded(FloatingPointRoundingRule.up)) / 5
if (interval <= 0)
{
xAxis.granularity = 1.0 / 24.0
} else {
xAxis.granularity = 1.0 / 24.0 * Double(interval)
}

What level of decimal precision do QBO Invoice Items support?

We have a one-way sync which transfers our internal invoices to QBO. The problem seems to be that once transferred to QBO the line items are rounded to the nearest cent and then summed, not summed and then rounded.
For example:
Line item 1 = 0.75 x $0.50 = $0.375 (it will display as $0.38)
Line item 2 = 0.75 x $0.50 = $0.375 (it will display as $0.38)
Total = $0.375 + $0.375 = $0.75
If I try to do this in QBO, I will get:
Line item 1 = 0.75 x $0.50 = $0.38
Line item 2 = 0.75 x $0.50 = $0.38
Total = $0.38 + $0.38 = $0.76
So the customer would have paid $0.75, but QBO thinks that the invoice is for $0.76 ultimately also resulting in the invoice appearing to be overdue.
I've tried entering items into QBO with greater precision, and it always rounds to the whole cent.
Is what we are doing not supported by QBO?

How to round off x-ticklabels to the nearest 50

I need to round off the X-ticklabels in an excel chart to the nearest 50. The charts are created in VBA, the data series is in a worksheet so I would be happy to use a solution in either. I have written the following function that rounds to the nearest 50:
Function RoundTo50(number As Double) As Double
RoundTo50 = WorksheetFunction.Round(number * 2, -2) / 2
End Function
I have applied it to the min and max x limits of the chart and it works for them, but I can't work out how to apply this to all the ticklabels in between. I thought of applying it to all the data before plotting but that would alter the plot which I don't want to do. I would prefer for the ticklabels to be slightly misaligned due the rounding.
Can you do this with a formatting string? Or any other way?
Thanks
So the answer is as follows (thanks to Sam Ward for the comment that pushed me in the right direction):
Use my RoundTo50() function to round of the min and max limits to the nearest 50. Calculate what the interval should be for a reasonable amount of grid lines, in my case 12. Round this interval to the nearest 50.
Function RoundTo50(number As Double) As Double
RoundTo50 = WorksheetFunction.Round(number * 2, -2) / 2
End Function
and
With Sheets("Report").ChartObjects.Add(...)
.Chart.Axes(xlCategory).MinimumScale = RoundTo50(Sheets(sheetName).Range("M4"))
.Chart.Axes(xlCategory).MaximumScale = RoundTo50(Sheets(sheetName).Range("M124"))
.Chart.Axes(xlCategory).MajorUnit = RoundTo50((.Chart.Axes(xlCategory).MaximumScale - .Chart.Axes(xlCategory).MinimumScale) / 12)
.Chart.Axes(xlCategory).MinorUnit = .Chart.Axes(xlCategory).MajorUnit / 3
I would still be very much interested in being able to do this with a formatting string though as I have a secondary axis in percent and the grid lines from rounding to 50 are slightly offset with the tick marks of the secondary axis. With a formatting string they would be perfectly aligned (because they would be slightly in the wrong place but I would prefer that).