MPAndroidChart how can I stop the line when there is no data yet? - mpandroidchart

I am using MPAndroidLineChart to display some data over the course of a week. This works fine. My problem is this
If, for example, today is Wednesday, I'd like the line chart to abruptly stop at the Wednesday point on the X axis, although the axis goes from Sunday to Saturday. I have attached an example of my current chart

don't set zero value to Thu Fri Sat...But still show X axis Thu Fri Sat

Loading entry data like this will show a continuous line
val entryList: ArrayList<Entry> = ArrayList()
entryList.add(1, 10)
entryList.add(2, 10)
entryList.add(3, 10)
entryList.add(4, 10)
Loading entry data like this will show a continuous line
val entryList: ArrayList<Entry> = ArrayList()
for (i in 0 until 5){
entryList.add(i, 10)
}
Loading data like this will show a break
val entryList: ArrayList<Entry> = ArrayList()
entryList.add(1, 10)
entryList.add(2, 10)
entryList.add(5, 10)

Related

Pine Editor V5 Plotting OHLC levels with a timeframe selector

Im trying to simplify some code for an indicator Im working one and need some help. Currently trying to setup and OHLC level that allows you to change it while selecting an option from the timeframe dropdown. I found a script on here but wasnt sure how to tie in the timeframe option. The first option is to activate the OHLC levels and the second one is to adjust the timeframe while for example staying on the 15 minute chart
ohlcscan = input(false, title='OHLC Scanner', group='OPEN HIGH LOW CLOSE')
ohlctf = input.timeframe(title="Timeframe", defval="1D", group='OPEN HIGH LOW CLOSE')
f_newLine(_color) => line.new(na, na, na, na, xloc.bar_time, extend.right, _color)
f_moveLine(_line, _x, _y) =>
line.set_xy1(_line, _x, _y)
line.set_xy2(_line, _x+1, _y)
var line line_open = f_newLine(color.yellow)
var line line_high = f_newLine(color.red)
var line line_low = f_newLine(color.green)
var line line_close = f_newLine(color.white)
[pdo,pdh,pdl,pdc,pdt] = request.security(syminfo.tickerid,"D",
[open[1],high[1],low[1],close[1],time[1]])
if barstate.islast
f_moveLine(line_open, pdt, pdo)
f_moveLine(line_high, pdt, pdh)
f_moveLine(line_low , pdt, pdl)
f_moveLine(line_close, pdt, pdc)

How to make global variable in pinescript(Tradingview)

I am working on creating a trend indicator in tradingview to track which way the trend is going. Specifically, I want a variable that will stay the same over days, but when a certain condition is met it will change. It seems like it should be simple to do, but everytime I try I get thrown into a never ending loop and I can't seem to wrap my head around it. Variable "Trend"
///Condition
pos = close > open
neg = close < open
pos_cond = pos and pos[1]
neg_cond = neg and neg[1]
///Variables to keep track of trend
Trend = iff(***pos_cond or neg_cond not met***, Trend[1], Trend + real_trend)
trend_change_neg = iff(pos_cond, 1, 0)
trend_change_pos = iff(neg_cond, -1, 0)
real_trend = trend_change_neg + trend_change_pos
Trend = iff(Trend > 2, 2, iff(Trend < -2, -2, Trend))
/////////plots
plotshape(Trend > 0, color = color.green, location = location.top, style = shape.square, title="TrendLong")
plotshape( Trend == 0, color = color.yellow, location = location.top, style = shape.square, title = "TrendNeutral")
plotshape( Trend < 0, color = color.red, location = location.top, style = shape.square, title = "TrendShort")
So basically what I want to do is keep a running total for Trend where each time there are 2 consecutive candles against the trend it will switch to neutral, but as the trend continues to move in 1 direction it can build back up to +-2 (This was we are never more than 2 "pullbacks" away from neutral. I've racked my brain over this for days now, but if anyone has any ideas any help would be appreciated.
You need to use var.
Example:
var a = 0
a:=close>open?1:0
https://www.tradingview.com/pine-script-docs/en/v4/language/Expressions_declarations_and_statements.html

Add a column of minutes to a datetime in pandas

I have a dataframe with a start time and the length of operation. I'm trying to figure out out to add the length (in minutes) to the start time in order to figure out the end time of the session. I've run a few different variations of the same general idea and keep getting the same error, "unsupported type for timedelta minutes component: Series". The code extract is below:
data= {'Name': ['John', 'Peter'],
'Start' : [2, 2],
'Length': [120, 90],
}
df = pd.DataFrame.from_records(data)
df['Start'] = pd.to_datetime(df['Start'])
df['Length'] = pd.to_datetime(df['Length'])
df["tdiffinmin"] = df['Start'].apply(lambda x: x + pd.DateOffset(minutes = df["Length"]))
Ive also tried the follow as other methods of doing this math and keep getting similar errors.
df["tdiffinmin"] = df['Start'].apply(lambda x: x -pd.DateOffset(minutes = df["Length"]))
df["tdiffinmin"] = (df['Start']. + timedelta(minutes = df["Length"])).dt.total_seconds() / 60
df['tdiffinmin'] = df['Start'] - pd.DateOffset(minutes = df["Length"])
The full code reads from a data set (excel sheet or CSV), populates a Dataframe, and this is some of the math I am doing. Originally it was done with Start and Stop times, so I know something similar is possible. In the dataset, Length is in minutes and Start is a date and time, so datetime is necessary.
You should convert Length into timedelta, not datetime:
df['Start'] = pd.to_datetime(df['Start'])
df['Length'] = pd.to_timedelta(df['Length'], unit='min')
df['tdiffinmin'] = df['Start'] + df['Length']
Output:
Length Name Start tdiffinmin
0 02:00:00 John 1970-01-01 00:00:00.000000002 1970-01-01 02:00:00.000000002
1 01:30:00 Peter 1970-01-01 00:00:00.000000002 1970-01-01 01:30:00.000000002

Moving average line is only shown till last ticker.id close

I am working on a moving average indicator which shows the MA line of a given time frame.
For some reason is the MA line only displaced till the last ticker.id period close. So when for example I have set the indicator to show a daily MA the line is only updated when the day closes.
(Link to image https://i.stack.imgur.com/QjkvO.jpg)
Does anyone know how my indicator will be able include data between daily closes, so the line is being updated continuously?
I think this line not being updated continuously also causes the label which is supposed to be plotted right at the MA line being plotted at the 1 point / dollar height on the chart.
I have only recently started writing code, so excuse me if this is a dumb question. I have written this code looking at other indicators and trying to fit parts into my own
This is the code of the entire indicator.
//#version=4
study(title="Custom Timeframe SMA", shorttitle="Custom TF MA", overlay=true)
res = input(title="MA Timeframe", type=input.resolution, defval="D",options=["60", "240", "D", "W"])
length1 = input(title="SMA Length", type=input.integer, defval=50)
Label=input(title="show Labels",defval=true)
sma1 = sma(close, length1)
sourceEmaSmooth1 = security(syminfo.tickerid, res, sma1, barmerge.gaps_on, barmerge.lookahead_on)
plot(sourceEmaSmooth1, style=plot.style_line, linewidth=2, title="25 period", color=#a21e7b)
plotchar((sourceEmaSmooth1 ? Label : barstate.islast and not barstate.isconfirmed) ? sourceEmaSmooth1 : na, location=location.absolute, text=" 50 SMA", textcolor=#a21e7b, offset=10, editable=false)
Using barmerge.gaps_on with security() creates holes which appear as na values at the chart's resolution, which is why your ma wasn't always showing. It wasn't apparent on historical bars because the plot() function fills the space from non-gap to non-gap (you could see it if you plotted circles instead of a line).
Using barmerge.lookahead_on with security() produces lookahead bias on historical bars. Very nasty if you don't index the value you're fetching, as is explained in this publication on how to use security() correctly: How to avoid repainting when using security().
I added show_last = 1 to you label-plotting call and fixed the conditional. Because it now only plots the last occurrence of the label, we no longer need to worry about barstates:
//#version=4
study(title="Custom Timeframe SMA", shorttitle="Custom TF MA", overlay=true)
res = input(title="MA Timeframe", type=input.resolution, defval="D",options=["60", "240", "D", "W"])
length1 = input(title="SMA Length", type=input.integer, defval=50)
Label=input(title="show Labels",defval=true)
sma1 = sma(close, length1)
sourceEmaSmooth1 = security(syminfo.tickerid, res, sma1)
plot(sourceEmaSmooth1, linewidth=2, title="25 period", color=#a21e7b)
plotchar(Label ? sourceEmaSmooth1 : na, location=location.absolute, text=" 50 SMA", textcolor=#a21e7b, offset=10, show_last = 1, editable=false)

matplotlib x-axis ticks dates formatting and locations

I've tried to duplicate plotted graphs originally created with flotr2 for pdf output with matplotlib. I must say that flotr is way easyer to use... but that aside - im currently stuck at trying to format the dates /times on x-axis to desired format, which is hours:minutes with interval of every 2 hours, if period on x-axis is less than one day and year-month-day format if period is longer than 1 day with interval of one day.
I've read through numerous examples and tried to copy them, but outcome remains the same which is hours:minutes:seconds with 1 to 3 hour interval based on how long is the period.
My code:
colorMap = {
'speed': '#3388ff',
'fuel': '#ffaa33',
'din1': '#3bb200',
'din2': '#ff3333',
'satellites': '#bfbfff'
}
otherColors = ['#00A8F0','#C0D800','#CB4B4B','#4DA74D','#9440ED','#800080','#737CA1','#E4317F','#7D0541','#4EE2EC','#6698FF','#437C17','#7FE817','#FBB117']
plotMap = {}
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.dates as dates
fig = plt.figure(figsize=(22, 5), dpi = 300, edgecolor='k')
ax1 = fig.add_subplot(111)
realdata = data['data']
keys = realdata.keys()
if 'speed' in keys:
speed_index = keys.index('speed')
keys.pop(speed_index)
keys.insert(0, 'speed')
i = 0
for key in keys:
if key not in colorMap.keys():
color = otherColors[i]
otherColors.pop(i)
colorMap[key] = color
i += 1
label = u'%s' % realdata[keys[0]]['name']
ax1.set_ylabel(label)
plotMap[keys[0]] = {}
plotMap[keys[0]]['label'] = label
first_dates = [ r[0] for r in realdata[keys[0]]['data']]
date_range = first_dates[-1] - first_dates[0]
ax1.xaxis.reset_ticks()
if date_range > datetime.timedelta(days = 1):
ax1.xaxis.set_major_locator(dates.WeekdayLocator(byweekday = 1, interval=1))
ax1.xaxis.set_major_formatter(dates.DateFormatter('%Y-%m-%d'))
else:
ax1.xaxis.set_major_locator(dates.HourLocator(byhour=range(24), interval=2))
ax1.xaxis.set_major_formatter(dates.DateFormatter('%H:%M'))
ax1.xaxis.grid(True)
plotMap[keys[0]]['plot'] = ax1.plot_date(
dates.date2num(first_dates),
[r[1] for r in realdata[keys[0]]['data']], colorMap[keys[0]], xdate=True)
if len(keys) > 1:
first = True
for key in keys[1:]:
if first:
ax2 = ax1.twinx()
ax2.set_ylabel(u'%s' % realdata[key]['name'])
first = False
plotMap[key] = {}
plotMap[key]['label'] = u'%s' % realdata[key]['name']
plotMap[key]['plot'] = ax2.plot_date(
dates.date2num([ r[0] for r in realdata[key]['data']]),
[r[1] for r in realdata[key]['data']], colorMap[key], xdate=True)
plt.legend([value['plot'] for key, value in plotMap.iteritems()], [value['label'] for key, value in plotMap.iteritems()], loc = 2)
plt.savefig(path +"node.png", dpi = 300, bbox_inches='tight')
could someone point out why im not getting desired results, please?
Edit1:
I moved the formatting block after the plotting and seem to be getting better results now. They are still now desired results though. If period is less than day then i get ticks after every 2 hours (interval=2), but i wish i could get those ticks at even hours not uneven hours. Is that possible?
if date_range > datetime.timedelta(days = 1):
xax.set_major_locator(dates.DayLocator(bymonthday=range(1,32), interval=1))
xax.set_major_formatter(dates.DateFormatter('%Y-%m-%d'))
else:
xax.set_major_locator(dates.HourLocator(byhour=range(24), interval=2))
xax.set_major_formatter(dates.DateFormatter('%H:%M'))
Edit2:
This seemed to give me what i wanted:
if date_range > datetime.timedelta(days = 1):
xax.set_major_locator(dates.DayLocator(bymonthday=range(1,32), interval=1))
xax.set_major_formatter(dates.DateFormatter('%Y-%m-%d'))
else:
xax.set_major_locator(dates.HourLocator(byhour=range(0,24,2)))
xax.set_major_formatter(dates.DateFormatter('%H:%M'))
Alan
You are making this way harder on your self than you need to. matplotlib can directly plot against datetime objects. I suspect your problem is you are setting up the locators, then plotting, and the plotting is replacing your locators/formatters with the default auto versions. Try moving that block of logic about the locators to below the plotting loop.
I think that this could replace a fair chunk of your code:
d = datetime.timedelta(minutes=2)
now = datetime.datetime.now()
times = [now + d * j for j in range(500)]
ax = plt.gca() # get the current axes
ax.plot(times, range(500))
xax = ax.get_xaxis() # get the x-axis
adf = xax.get_major_formatter() # the the auto-formatter
adf.scaled[1./24] = '%H:%M' # set the < 1d scale to H:M
adf.scaled[1.0] = '%Y-%m-%d' # set the > 1d < 1m scale to Y-m-d
adf.scaled[30.] = '%Y-%m' # set the > 1m < 1Y scale to Y-m
adf.scaled[365.] = '%Y' # set the > 1y scale to Y
plt.draw()
doc for AutoDateFormatter
I achieved what i wanted by doing this:
if date_range > datetime.timedelta(days = 1):
xax.set_major_locator(dates.DayLocator(bymonthday=range(1,32), interval=1))
xax.set_major_formatter(dates.DateFormatter('%Y-%m-%d'))
else:
xax.set_major_locator(dates.HourLocator(byhour=range(0,24,2)))
xax.set_major_formatter(dates.DateFormatter('%H:%M'))