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

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)
}

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 :)

unequal intervals on gauge Highcharts (or other libraries)

I need to setup a Gauge chart, with very customized and unequal intervals
Unequal in values and in space they take in the chart, for example: from 0 to 5 are classified as stable, and its area on the gauge chart is bigger than 5% (we do it to visualize better its value on the chart)
All example have seen till now equally divide the area..
I think is more understandable with an image, here below.
I have the idea of how to create this chart by using two pie series and gauge. Gauge y axis has set min set to 0 and max to 10 for a function which calculates the values for the indicator.
Here is a function to calculate the values for gauge for each period:
function parseData(value) {
if (value <= 10) {
return value * 0.8 - 1
} else if (10 < value && value <= 20) {
return ((value - 10) / 2.5) + 7
} else {
return ((value - 20) / 10) + 11.5
}
}
Rest of the code you can find here - demo
API: https://api.highcharts.com/highcharts/series.pie.dataLabels.formatter
Let me know if something is unclear.
Kind regards!

offset in atr in tradingview - pine script

Need to have offset in ATR function in pine script
Background: The indicator script below is based on the hypothesis that this period's range will be mostly within [last period high + atr(14)] and [last period low - atr(14)]. I want to sell the high call option and low put option and enjoy the premium at the end of the period (week, month).
I have created a pine script that will calculate this period range based on [last period high + atr(14)] and [last period low - atr(14)].
However, because atr(14) applies to current period as well, it plots the dots that change with the current price.
I need to have an atr(14) days till the last period and not considering this current period. Could you please advise how to achieve that.
//#version=3
study(title="High and Low Levels", shorttitle="HL Levels", overlay = true)
Width = input(2, minval=1)
SelectPeriod = input("W", defval="W", type=string)
LookBack = input(1, minval=1)
xHigh = high[LookBack]
xHigh := xHigh + (atr(14))
xLow = low[LookBack] - atr(14)
vS1 = xHigh
vR1 = xLow
plot(vS1, color=#ff0000, title="S1", style = circles, linewidth = Width)
plot(vR1, color=#009600, title="R1", style = circles, linewidth = Width)
Expected: the dots plotted should be plotted based on last period high + last period atr(14) and last period low - last period atr(14)
Actual: the dots plotted based on last week high + atr(14) till the current period and last week low - atr(14) till the current period. This is changing the dots based on the current price movement.
Maybe, I got it wrong, but I think what you want is to take the previous value of atr(14). So it looks like that:
xLow = low[LookBack] - atr(14)[1]
I think, you've got my idea.
This should help....
plot(vS1[1], color=#ff0000, title="S1", style = circles, linewidth = Width)
plot(vR1[1], color=#009600, title="R1", style = circles, linewidth = Width)

Excluding Outliers from Avg Calculations at the dimension level in Qlik

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.

How to setup up iOS charts y-axis with min, max value and a fixed step between the grid lines?

I'm just in the learning phase of using ios-charts. I like to change the x-axis grid to fixed values.
My plotted y-values are just int numbers like 1, 2, 3,..., 10. Nevertheless, the left y-axis shows values like 6.3, 9.1, etc., depending on my zoom level.
The second question is, how to set up the x-axis in order to show the labels 1,5,10,15,....40?
Is there any way to influence the step size like e.g. in Excel?
// zoom y-axis to min/max value
lineChart.leftAxis.customAxisMin = max(0.0, lineChart.data!.yMin - 1.0)
lineChart.leftAxis.customAxisMax = min(10.0, lineChart.data!.yMax + 1.0)
lineChart.leftAxis.startAtZeroEnabled = false
Chart (min = 6.0 and max = 10.0): The grid start at 6.3 instead of 6.0.
Chart (min = 7.0 and max = 10.0): The grid starts as expected with 7.0.
What's going wrong here?
I solved the issue just by setting the correct labelCount.
// zoom y-axis to min/max value
lineChart.leftAxis.customAxisMin = max(0.0, lineChart.data!.yMin - 1.0)
lineChart.leftAxis.customAxisMax = min(10.0, lineChart.data!.yMax + 1.0)
lineChart.leftAxis.labelCount = Int(lineChart.leftAxis.customAxisMax lineChart.leftAxis.customAxisMin)
lineChart.leftAxis.startAtZeroEnabled = false
Swift 4.2 and above:
startAtZeroEnabled - This property is deprecated - Use axisMinimum instead.
open var axisMinValue: Double
{
get { return axisMinimum }
set { axisMinimum = newValue }
}
lineChartView.leftAxis.axisMinimum = 0
lineChartView.leftAxis.axisMaximum = 10.0