#python #dataframe #matplotlib
#python #фрейм данных #matplotlib
Вопрос:
Я в значительной степени новичок во всем, что касается python, и, к моему большому огорчению, я пытался создать довольно простой график OHLC. Приведенный ниже код с примерами фреймов данных. Я пытаюсь построить и сохранить график OHLC для одной акции за один торговый день в 1 млн тиков. Ось yaxis, похоже, работает нормально, однако график, когда он показан, пуст. Xaxis показывает время начала 09:30, но без других 1-миллиметровых тиков. Перемещение графика по пустой фигуре показывает значения для осей yax, но x = nada. Пример
Чего я надеюсь в конечном итоге достичь, так это метки xaxis для отображения времени в минутах, не требуется dae, поворот на 90 градусов, скажем, с интервалом 15 минут. Я бы предпочел график OHLC, чем свечу, но я также хочу, чтобы его можно было расшифровать, поскольку я видел много версий, которые представляют собой просто размытие крошечных вертикальных линий, которые никому не нужны. Если размер необходимо растянуть по горизонтали, чтобы вместить около 376 1-миллиметровых записей в dataframe, пусть будет так. Если он слишком загроможден, я хотел бы иметь возможность распределять интервал между тиками, возможно, каждые 2 или 5 минут. Однако xaxis xticks все равно должны оставаться с интервалом в 15 минут. Затем я хотел бы сохранить результат в формате jpg.
Я перепробовал так много вариантов mplfinace, что теперь больше не знаю, какой самый последний из допустимых модулей. Я пробовал как «котировки», так и значения в инструкции candlestick_ohlc, кажется, нет видимой разницы. Я читал и перечитывал и перепробовал так много примеров, но, похоже, все они терпят неудачу при переводе времени во всех вещах, связанных с xaxis, и это очень сбивает меня с толку и расстраивает .. хех.
Если бы кто-нибудь мог любезно указать мне правильное направление здесь, я был бы очень благодарен за любую помощь.
Большое спасибо, Tim.D
import pandas as pd
import numpy as np
from datetime import datetime, date, timedelta
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from mplfinance.original_flavor import candlestick_ohlc
sym = sys.argv[1] #symbol in all caps
run_dt = sys.argv[2] #run date of the required process requires the date to be surrounded by 'quotes'
run_int = sys.argv[2].replace('/', '-')
run_int = run_int.replace("'", "")
import pyodbc #database connectivity
cnxn = pyodbc.connect(dsn='abc', user='abc', password='abc', autocommit=False)
df = pd.read_sql_query("
SELECT TIMESTAMP(ACT_DATE||' '||TIME(TICK)) AS TIME, OPEN, HIGH, LOW, CLOSE
FROM INTRADAY_IDX
WHERE ACT_DATE = " run_dt "
AND SYMBOL = '" sym "'
ORDER BY 1",cnxn, )
print(df)
Это создает фрейм данных следующим образом:
ВРЕМЯ ОТКРЫТИЯ, МАКСИМУМ, МИНИМУМ, ЗАКРЫТИЕ
0 2021-02-12 09:30:00 314.27 314.50 314.22 314.49
1 2021-02-12 09:31:00 314.51 314.73 314.44 314.63
2 2021-02-12 09:32:00 314.63 314.79 314.54 314.73
.. … … … … …
375 2021-02-12 15:59:00 315.01 315.14 314.85 315.00
376 2021-02-12 16:00:00 315.00 315.18 314.97 315.18
df.TIME = mdates.date2num(df.TIME.dt.to_pydatetime())
print(df.head(5))
ВРЕМЯ ОТКРЫТИЯ, МАКСИМУМ, МИНИМУМ, ЗАКРЫТИЕ
0 737833.395833 314.27 314.50 314.22 314.49
1 737833.396528 314.51 314.73 314.44 314.63
2 737833.397222 314.63 314.79 314.54 314.73
3 737833.397917 314.83 314.89 314.76 314.85
…
#quotes = [tuple(x) for x in df[['TIME', 'OPEN', 'HIGH', 'LOW', 'CLOSE']].to_records(index=False)]
#print(quotes)
fig, ax = plt.subplots(figsize=(12,7))
plt.yscale('linear') #default scaling of the y axis
ax.set_xlim('09:30', '16:00') #sets the start and end values for the xaxis charting
start, end = ax.get_xlim() #initializes the start and end variables
ax.xaxis.set_ticks(np.arange(start, end, 1800)) #sets the tick values for charting
plt.xticks(rotation=90, fontsize=12) #sets the rotation value of the x axis ticks
plt.yticks(fontsize=12)
ax.set_title(sym ' OHLC Intraday Chart', fontsize=14, fontweight = 'bold')
ax.set_ylabel('Price', fontsize=12, fontweight = 'bold')
ax.set_xlabel('Time', fontsize=12, fontweight = 'bold')
plt.tight_layout() #reduces the space padding surrounding the graph
ax.grid(True)
candlestick_ohlc(ax, df.values, width = 1/(24*60*2.5), alpha = 1.0, colorup = 'g', colordown ='r')
#candlestick_ohlc(ax, quotes, width = 1/(24*60*2.5), alpha = 1.0, colorup = 'g', colordown ='r')
bbox_inches='tight') #saves the data to to jpg file
#plt.savefig('c:\temp\charts\' sym '_OHLC_' run_int '.jpg', format='jpg', quality=95, #plt.close()
plt.show()
Ответ №1:
и большое спасибо за ответ. Используя ваш код, мне удалось заставить его работать сейчас, также добавив дополнительный график. Код ниже:
import sys, os, time, warnings #csv
import pandas as pd
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
#import numpy as np
#from datetime import datetime, date, timedelta
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
#from matplotlib import dates, ticker
from mplfinance.original_flavor import candlestick_ohlc
sym = sys.argv[1] #symbol in all caps
run_dt = sys.argv[2] #run date of the required process requires the date to be surrounded by 'quotes'
run_int = sys.argv[2].replace('/', '-') #reformat the date
run_int = run_int.replace("'", "") #reformat the date
import pyodbc #database connectivity
cnxn = pyodbc.connect(dsn='abc', user='abc', password='abc', autocommit=False)
db = pd.read_sql_query("
SELECT timestamp(ACT_DATE||' '||TIME(TICK)) AS TIME, OPEN, HIGH, LOW, CLOSE
FROM SQ4_INTRADAY_IDX
WHERE ACT_DATE = " run_dt "
AND SYMBOL = '" sym "'
ORDER BY 1",cnxn, )
print(db)
db['TIME']= pd.to_datetime(db['TIME'])
db.set_index('TIME', inplace=True) #this resets the dataframe index to the time values
#db.info() #shows column data types
#setup an array for the candlestick chart
dd = db.copy() #create a copy of the dataframe
dd.index = mdates.date2num(dd.index) #set the datetime to numeric for the chart to work
dd_data = dd.reset_index().values #set the index
#print(dd_data)
clse = db["CLOSE"] #setup the data for plotting an additional subplot line
fig, ax = plt.subplots(figsize=(12,7))
ax.set_title(sym ' OHLC Intraday Chart', fontsize=14, fontweight='bold')
ax.set_ylabel('Price', fontsize=12, fontweight='bold')
ax.set_xlabel('Time', fontsize=12, fontweight='bold')
candlestick_ohlc(ax, dd_data, width=.0003, alpha=.8, colorup='g', colordown='r')
ax.plot(clse, color = 'k', linestyle='--', linewidth = .5, label='Close')
plt.xticks(rotation=90, fontsize=12) #sets the rotation value of the x axis ticks
plt.yticks(fontsize=12) #sets the rotation value of the x axis ticks
ax.xaxis.set_major_locator(mdates.MinuteLocator(interval=30))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
plt.tight_layout() #reduces the space padding surrounding the graph
plt.savefig('c:\temp\' sym '_OHLC Intrday Chart for ' run_int '.jpg', format='jpg', quality=95, bbox_inches='tight') #saves the data to to jpg file
plt.show()
При этом создается прикрепленный график.
Моя проблема в том, что я пытаюсь удалить заполненный пробел между левым и правым масштабами оси y. Другими словами, я бы хотел, чтобы метка 9:30 отображалась непосредственно под левым и 16:00 под правым полями. В основном, я думаю, я пытаюсь растянуть график, чтобы заполнить все поле диаграммы.
Также есть ли возможность добавить значения левой шкалы цен как с левой, так и с правой стороны?
Спасибо за помощь, очень признателен. С уважением, Tim.D
Комментарии:
1. Пожалуйста, обратитесь к моему ответу за кодом, который реализует требования, добавленные в самоответ.
Ответ №2:
Аргументом этой функции должен быть массив. Кроме того, формат даты и времени должен быть преобразован в mdates2num()
. В остальное время дата и время контролируются с помощью локатора и средства форматирования. Я думаю ax.set_xlim('09:30', '16:00')
, что причиной ошибки является связанный с вашим кодом. Сбор данных осуществляется Yahoo Finance.
import pandas as pd
import numpy as np
from datetime import datetime, date, timedelta
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from mplfinance.original_flavor import candlestick_ohlc
import yfinance as yf
dia = yf.download("DIA", period='1d', interval='1m', start="2021-02-11", end='2021-02-12')
df = dia.copy()
df.index = mdates.date2num(df.index)
data = df.reset_index().values
fig, ax = plt.subplots(figsize=(12,7))
sym = 'DIA'
candlestick_ohlc(ax, data, width=1/(24*60*2.5), alpha=1.0, colorup='g', colordown='r')
ax.set_title(sym ' OHLC Intraday Chart', fontsize=14, fontweight='bold')
ax.set_ylabel('Price', fontsize=12, fontweight='bold')
ax.set_xlabel('Time', fontsize=12, fontweight='bold')
# update start
ax.set_xlim(data[0][0], data[382][0])
ax1 = ax.twinx()
ax1.set_yticks(ax.get_yticks())
ax1.set_ybound(ax.get_ybound())
ax1.set_yticklabels([str(x) for x in ax.get_yticks()])
# update end
ax.grid()
locator = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))
plt.show()