I am struggling to get the .update to work on my line objects. I am pretty sure I have the correct format for the pd.Series and have followed the docs to the best of my ability.
terminal output states:
Received avg_series_high: 2024-03-05 3693.797625 dtype: float64
I then receive the following error:
Error occurred in update_chart_lines: Can only use .str accessor with string values!
I have never seen this error before whilst use pd and all examples of this error i have found online seem to indicate that the name of the series may not automatically be being treated as a string?
Any help or pointers would be greatly appreciated.
Code example
async def update_chart_lines(self, avg_line_high, avg_line_low, avg_line_high2, avg_line_low2, queue):
print("Starting update_chart_lines function")
avg_data = None
while True:
try:
avg_data = await queue.get()
if avg_data is not None and 'date' in avg_data:
avg_data['date'] = pd.to_datetime(avg_data['date'], unit='ms')
# Create a pandas Series for each line
avg_series_high_data = pd.Series([avg_data['avg_last_candles_high']], index=[avg_data['date']])
avg_series_low_data = pd.Series([avg_data['avg_last_candles_low']], index=[avg_data['date']])
avg_series_high2_data = pd.Series([avg_data['avg_last_candles_high2']], index=[avg_data['date']])
avg_series_low2_data = pd.Series([avg_data['avg_last_candles_low2']], index=[avg_data['date']])
print(f"Received avg_series_high: {avg_series_high_data}")
# Update each line with the corresponding pandas Series
avg_line_high.update(avg_series_high_data)
avg_line_low.update(avg_series_low_data)
avg_line_high2.update(avg_series_high2_data)
avg_line_low2.update(avg_series_low2_data)
else:
print("No avg candle ticks to process.")
continue
except Exception as e:
print(f"Error occurred in update_chart_lines: {e}")
This generates a dataframe continuously and sends it to update_chart_lines:
async def last_candles_cont(df, n, timeframe, queue):
timeframe = timeframe
""" print(f"Calculating average of last {n} candles for {timeframe} timeframe") """
multipliers = {
'1d': 1.025,
'4h': 1.015,
'1h': 1.01,
'15m': 1.005,
'5m': 1.001,
'1m': 1.00
}
while True:
try:
avg_data = None
tick= await queue.get()
print(f"Received tick: {tick}")
tick_df = pd.DataFrame(tick, index=[0])
df = pd.concat([df, tick_df], ignore_index=True)
""" df['diff'] = df['close'] - df['close'].shift(1)
print (df['diff'])
# Calculate the rate of change as a percentage
df['roc'] = df['diff'] / df['close'].shift(1) * 100
print (df['roc']) """
multiplier = multipliers[timeframe]
df['avg_last_candles_high'] = (df['high']*multiplier).shift(1).rolling(n).mean()
df['avg_last_candles_low'] = (df['low']/multiplier).shift(1).rolling(n).mean()
df['avg_last_candles_high2'] = (df['high']*multiplier).rolling(n).mean()
df['avg_last_candles_low2'] = (df['low']/multiplier).rolling(n).mean()
avg_data = pd.DataFrame({
'date': (df['date']),
'avg_last_candles_high': df['avg_last_candles_high'],
'avg_last_candles_low': df['avg_last_candles_low'],
'avg_last_candles_high2': df['avg_last_candles_high2'],
'avg_last_candles_low2': df['avg_last_candles_low2'],
}).dropna()
current_candle = avg_data.tail(1).squeeze()
print(f"Current candle: {current_candle}")
# Put the current candle into the queue
await queue.put(current_candle)
await asyncio.sleep(1)
""" return avg_data """
except Exception as e:
print(f"Error in avg candle function: {e}")
return pd.DataFrame() # Return an empty DataFrame in case of error
I don't have experience with lightweight-charts
, but your problem seems related to the data you're passing to .update
.
You're creating pandas series like this:
avg_series_high_data = pd.Series([avg_data['avg_last_candles_high']], index=[avg_data['date']])
Which effectively creates a series with dates as index and corresponding values for each date. Something similar to this:
2024-03-11 1
2024-03-12 2
2024-03-13 3
2024-03-14 4
The issue is lightweight-charts
is expecting pandas series in a different format, i.e., a series for each row of the dataframe you're plotting, with values for an index 'date', another index 'some_value'... and so on. So something more along the lines of:
date 2016-12-28 00:00:00
open 14.6667
high 14.92
low 14.48
close 14.616
volume 48715005.0
The error you're seeing happens because lightweight-charts
is expecting date
or time
to be in the series index. If it isn't, it assumes these words may be in uppercase and calls .str.lower()
on it.
In the series you're passing it, the index values are of type datetime
, so it raises the error:
Error occurred in update_chart_lines: Can only use .str accessor with string values!
You need to create pandas series in the format suggested above. I don't have access to your data, so it's hard to recommend anything more concrete. Since it's a line, I assume each series would look something like this:
date 2016-12-28 00:00:00
open 14.6667