دریافت داده های بورس تهران در پایتون — راهنمای گام به گام
پیشتر در آموزش «کار با داده های مالی در پایتون — راهنمای مقدماتی» به موضوعاتی همچون دریافت و پردازش دادههای مربوط به بورس خارج از کشور، رمزارزها و قیمت جهانی فلزات گرانبها پرداختیم. در این مطلب قصد داریم تا داده های بورس تهران را دریافت و آنها را پردازش کنیم. بدین منظور از ماژول (Module) Finpy-TSE استفاده خواهیم کرد که برای این کار توسعه داده شده است و امکانات خوبی فراهم آورده است. برای آشنایی بیشتر با این کتابخانه، میتوانید به صفحه PyPi مربوط به آن (+) مراجعه کنید.
فراخوانی کتابخانهها
برای شروع کار دریافت داده های بورس تهران در بورس، پس از نصب کتابخانه مورد نظر، وارد محیط برنامهنویسی پایتون شده و کتابخانههای مورد نیاز را فراخوانی میکنیم:
1import numpy as np
2import pandas as pd
3import finpy_tse as tse
4import mplfinance as mplf
5import scipy.stats as stt
6import matplotlib.pyplot as plt
این کتابخانهها به ترتیب برای موارد زیر استفاده خواهند شد:
- محاسبات برداری
- کار با دیتافریمها
- دریافت داده از API مربوط به بورس تهران
- رسم نمودارهای تکنیکال
- محاسبه ضریب همبستگی پیرسون (Pearson Correlation Coefficient)
- رسم نمودار
حال تنظیمات نمودارها را به شکل زیر تعیین میکنیم:
1plt.style.use('ggplot')
دریافت فهرست تمامی سهامها
حال میتوانیم در اولین قدم، فهرست تمامی سهمها را دریافت کنیم:
1DF1 = tse.Build_Market_StockList(bourse=True,
2 farabourse=True,
3 payeh=True,
4 detailed_list=False,
5 show_progress=True,
6 save_excel=False,
7 save_csv=False)
ورودیهای تعریف شده برای این تابع، به ترتیب برای این موارد کاربرد دارند:
- دریافت سهام مربوط به بازار بورس
- دریافت سهام مربوط به بازار فرابورس
- دریافت سهام مربوط به بازار پایه
- اضافه کردن اطلاعات سربرگ سهام به دیتافریم خروجی
- نمایش روند دریافت داده
- ذخیره دیتافریم در فایل اکسل (Excel)
- ذخیره دیتافریم در فایل CSV
حال ۵ سطر ابتدایی دیتافریم دریافتشده را نشان میدهیم:
1print(DF1.head())
که خواهیم داشت:
Market | Name | Ticker |
بورس | تولید نیروی برق آبادان | آبادا |
بورس | آسان پرداخت پرشین | آپ |
بورس | بیمه آسیا | آسیا |
بورس | کنتورسازی ایران | آکنتور |
بورس | فرآورده معدنی اپال کانی پارس | اپال |
توجه داشته باشید که میتوان با تغییر detailed_list به True میتوان فهرستی با جزئیات بیشتر دریافت کرد.
حال میتوانیم برای دریافت فهرستی از تمامی نمادها، به شکل زیر نوشت:
1Tickers = DF1.index.to_list()
به این ترتیب، فهرستی به طول ۷۰۵ ایجاد میشود که شامل کل نمادهای بورس، فرابورس و بازار پایه است.
برای یادگیری برنامهنویسی با زبان پایتون، پیشنهاد میکنیم به مجموعه آموزشهای مقدماتی تا پیشرفته پایتون فرادرس مراجعه کنید که لینک آن در ادامه آورده شده است.
دریافت تاریخچه شاخص کل
در اغلب بازارها، یک شاخص کل وجود دارد که برگرفته از کل بازار است و بر رفتار اغلب نمادها اثرگذار است. برای دریافت تاریخچه شاخص کل، میتوان به شکل زیر عمل کرد:
1DF2 = tse.Get_CWI_History(start_date='1396-01-01',
2 end_date='1399-01-01',
3 ignore_date=False,
4 just_adj_close=False,
5 show_weekday=True,
6 double_date=True)
برای این تابع، ورودیهای تعریفشده اعمال زیر را تنظیم میکنند:
- تاریخ اولین داده
- تاریخ آخرین داده
- این ورودی در صورت True بودن، کل تاریخچه را برمیگرداند و دو ورودی قبلی را Ignore میکند.
- این ورودی در صورت True بودن، تنها مقدار تعدیل شده Close را برمیگرداند.
- اضافه کردن روز هفته به دیتافریم خروجی
- اضافه کردن تاریخ میلادی به دیتافریم خروجی
پس از اجرای کد فوق، دیتافریم به شکل زیر دریافت میشود:
Date Weekday Open High Low Close Adj Close Volume J-Date 1396-01-05 2017-03-25 Saturday 77239.0 77494.0 77239.0 77486.0 77485.8 282764388 1396-01-06 2017-03-26 Sunday 77505.0 77542.0 77493.0 77503.0 77502.9 362972179 1396-01-07 2017-03-27 Monday 77519.0 77529.0 77481.0 77523.0 77523.3 356510812 1396-01-08 2017-03-28 Tuesday 77533.0 77577.0 77533.0 77548.0 77548.5 466165632 1396-01-09 2017-03-29 Wednesday 77575.0 77607.0 77565.0 77584.0 77584.4 547432473
به این ترتیب، مشاهده میکنیم که مجموعه داده به صورت تعیینشده دریافت میشود.
حال میتوانیم یک نمودار شمعی (Candle Stick Plot) برای قیمت رسم کنیم. برای این کار ابتدا Index دیتافریم را به تاریخ میلادی تغییر میدهیم:
1DF2.index = DF2['Date']
سپس برای رسم نمودار مینویسیم:
1mplf.plot(DF2[-200:], type='candle', mav=(13, 55))
2plt.show()
که نمودار زیر حاصل میشود.
به این ترتیب، نمودار مورد نظر رسم میشود.
میتوان نمودار OHLC را نیز به شکل زیر رسم کرد:
1mplf.plot(DF2[-200:], type='ohlc', mav=(13, 55))
2plt.show()
که در این صورت، شکل زیر را خواهیم داشت.
به این ترتیب، نمودار OHLC نیز رسم میشود. علاوه بر این دو نمودار، نمودارهای Line و Renko و PNF نیز قابل رسم هستند.
به جز شاخص کل، میتوان از توابع زیر استفاده کرد:
- Get_EWI_History: این تابع برای دریافت تاریخچه شاخص کل هم وزن کاربرد دارد.
- Get_INDI_History: این تابع برای دریافت تاریخچه شاخص صنعت کاربرد دارد.
- Get_ACT50_History: این تابع برای دریافت تاریخچه ۵۰ شرکت فعالتر کاربرد دارد.
- Get_LCI30_History: این تابع برای دریافت تاریخچه ۳۰ شرکت بزرگ کاربرد دارد.
علاوه بر موارد گفتهشده، توابع دیگری نیز وجود دارد.
برای مقایسه، میتوان اطلاعات دو شاخص کل و شاخص کل هموزن را در DF2 و DF3 دریافت کرد:
1DF2 = tse.Get_CWI_History(start_date='1396-01-01',
2 end_date='1399-01-01',
3 ignore_date=False,
4 just_adj_close=False,
5 show_weekday=True,
6 double_date=True)
7
8DF3 = tse.Get_EWI_History(start_date='1396-01-01',
9 end_date='1399-01-01',
10 ignore_date=False,
11 just_adj_close=False,
12 show_weekday=True,
13 double_date=True)
حال میتوانیم ستون Close را در کنار هم رسم کنیم:
1CWI = DF2['Adj Close'].to_numpy()
2EWI = DF3['Adj Close'].to_numpy()
3
4plt.subplot(1, 2, 1)
5plt.plot(CWI, ls='-', lw=1, c='crimson')
6plt.title('Tehran Stock Exchange CWI')
7plt.xlabel('Time')
8plt.ylabel('Value')
9plt.yscale('log')
10
11plt.subplot(1, 2, 2)
12plt.plot(EWI, ls='-', lw=1, c='crimson')
13plt.title('Tehran Stock Exchange EWI')
14plt.xlabel('Time')
15plt.ylabel('Value')
16plt.yscale('log')
17
18plt.show()
که شکل زیر را خواهیم داشت.
همچنین، میتوانیم همبستگی بین این دو شاخص را نیز به شکل زیر در قالب یک نمودار نشان دهیم:
1PCC = 100 * stt.pearsonr(CWI, EWI)[0]
2
3plt.scatter(CWI, EWI, s=10, color='crimson')
4plt.title(f'Tehran Stock Exchange CWI & EWI Correlation (PCC: {round(PCC, 2)} %)')
5plt.xlabel('CWI')
6plt.ylabel('EWI')
7plt.show()
که نتیجه آن، شکل زیر است.
به این ترتیب، مشاهده میکنیم که شاخص کل با شاخص کل هموزن ٪۹۸ همبستگی دارد که عدد بزرگی است. از طرفی، در بخش ابتدایی نمودار مشاهده میکنیم که این رابطه در مقدارهای کمتر از ۱۰۰٬۰۰۰ شاخص کل، ضعیفتر است.
علاوه بر قیمت، میتوان نمودار بالا را برای لگاریتم قیمت نیز رسم کرد:
1logCWI = np.log(CWI)
2logEWI = np.log(EWI)
3
4PCC = 100 * stt.pearsonr(logCWI, logEWI)[0]
5
6plt.scatter(logCWI, logEWI, s=10, color='crimson')
7plt.title(f'Tehran Stock Exchange log(CWI) & log(EWI) Correlation (PCC: {round(PCC, 2)} %)')
8plt.xlabel('log(CWI)')
9plt.ylabel('log(EWI)')
10plt.show()
که در این صورت، نمودار زیر حاصل میشود.
به این ترتیب، مشاهده میکنیم که در حالت لگاریتمی، جزئیات بهتر دیده میشوند، از طرفی نیز مقدار ضریب همبستگی پیرسون به عدد ٪۹۷ کاهش مییابد. با توجه به رفتار نمایی بازار، همبستگی بین لگاریتم قیمتها، قابلاستنادتر است.
همین نمودار را میتوانیم برای تغییرات لگاریتم قیمت رسم کنیم:
1difflogCWI = logCWI[1:] - logCWI[:-1]
2difflogEWI = logEWI[1:] - logEWI[:-1]
3
4PCC = 100 * stt.pearsonr(difflogCWI, difflogEWI)[0]
5
6plt.scatter(difflogCWI, difflogEWI, s=10, color='crimson')
7plt.title(f'Tehran Stock Exchange diff(log(CWI)) & diff(log(EWI)) Correlation (PCC: {round(PCC, 2)} %)')
8plt.xlabel('diff(log(CWI))')
9plt.ylabel('diff(log(EWI))')
10plt.show()
که در این صورت، شکل زیر را خواهیم داشت.
به این ترتیب، مشاهده میکنیم که همبستگی ٪۹۷ که برای لگاریتم قیمت مشاهده شده بود، در تغییرات لگاریتم قیمت به ٪۸۰ کاهش یافته است. دلیل این اتفاق در انباشت تغییرات نهفته است. اگر یک بازه ۳۰ روز را در نظر بگیریم، اگر تغییرات هر دو شاخص با یکدیگر ٪۸۰ همبستگی داشته باشند، به دلیل انباشت این تغییرات روی هم، مقدار قیمت در طول این بازه همبستگی بیشتری از خود نشان خواهد داد.
به همین دلیل، معیار مهمتر و قابل اعتمادتر، همبستگی بین تغییرات لگاریتم قیمت است. میتوان تغییرات نسبی را نیز به جای این معیار استفاده کرد.
دریافت تاریخچه قیمت سهام
برای دریافت تاریخچه قیمت سهام، از تابع Get_Price_History به شکل زیر استفاده میکنیم:
1DF4 = tse.Get_Price_History(stock='شپنا',
2 start_date='1397-01-01',
3 end_date='1399-01-01',
4 ignore_date=False,
5 adjust_price=True,
6 show_weekday=True,
7 double_date=True)
در این تابع ۲ ورودی جدید وجود دارد که اولی Stock بوده و نماد مورد بررسی را نشان میدهد. دومین مورد نیز مربوط به Adjust Price است که تعیین میکند قیمتهای تعدیلشده نیز در دیتافریم نهایی افزوده شوند یا خیر.
پس از اجرا، یک دیتا فریم با ۱۸ ستون ایجاد خواهد شد. میتوانیم دیتافریم را به شکل زیر تمیز و اصلاح کنیم:
1DropList = ['Open', 'High', 'Low', 'Close', 'Final',
2 'No', 'Ticker', 'Name', 'Part']
3
4DF4.drop(columns=DropList, axis=1, inplace=True)
5
6RenameDict = {'Adj Open': 'Open',
7 'Adj High': 'High',
8 'Adj Low': 'Low',
9 'Adj Close': 'Close',
10 'Adj Final': 'Final'}
11
12DF4.rename(columns=RenameDict, inplace=True)
به این ترتیب، دیتافریم تمیزتر شده و به شکل زیر در میآید:
Date Weekday Volume Value Open High Low Close Final J-Date 1397-01-05 2018-03-25 Sunday 2105211 9110653660 485 488 480 480 483 1397-01-06 2018-03-26 Monday 2920816 12508686541 484 485 475 475 479 1397-01-07 2018-03-27 Tuesday 2509378 10627250267 476 476 471 473 474 1397-01-08 2018-03-28 Wednesday 4395699 18484907932 479 479 467 468 470 1397-01-14 2018-04-03 Tuesday 4699234 19610457457 474 474 465 465 467
دریافت اطلاعات لحظهای بازار
علاوه بر تاریخچه شاخص و سهام، اطلاعات لحظهای نمادها نیز میتواند سودمند باشد که آنها را نیز میتوان به شکل زیر دریافت کرد:
1DF5 = tse.Get_MarketWatch(save_excel=False)
در این دیتافریم، ستونهای متعددی از جمله قیمتها، درصد تغییرات، حد بالا و پایین قیمت مجاز روزانه، ارزش معاملات و صفها، میانگین ارزش سرانه صفها، حجم خرید حقیقی و حقوقی و... وجود دارد. برای آشنایی بیشتر با این تابع، میتوان دیتافریم حاصل را بررسی کرد و از اطلاعات موجود در آن، برای استخراج شرایط خاص استفاده کرد. یکی از کاربردهای این دیتافریم، فیلترنویسی است و به این طریق میتوان سهامی که از شرایط خاصی برخوردار هستند را شناسایی کرد.
در کتابخانه Finpy-TSE، علاوه به موارد ذکرشده، توابع و امکانات دیگری نیز برای دانلود دسته جمعی دیتا، ساخت پنل قیمت، دریافت ارزش صفها، دریافت دیتای عمق بازار، دریافت سابقه حقیقی-حقوقی وجود دارد که هرکدام بسته به نیاز میتوانند مورد استفاده قرار گیرند.
جمعبندی دریافت داده های بورس تهران
در این مطلب، دریافت داده های بورس تهران در بورس و پردازش آنها را بررسی و برخی از امکانات کتابخانه Finpy-TSE را معرفی کردیم.
برای مطالعه بیشتر این کتابخانه میتوانید Documentation آن را مطالعه کنید.
سلام. متاسفانه نمیتونم اسم نماد رو خارج از متد تعریف و بهش پاس بدم. حتما باید داخل متد نوشته بشه.
ممنون میشم راهنمایی بفرمایید.
چطور از متد دریافت سابقه، درون لوپی از نماد ها استفاده کنم؟
باعرض سلام این کد با نصب کتابخانه بر ای من کار نکرد
و پیغام پایتون نمیتونه کار کند را می دهد
با سلام و احترام؛
کدها تست شدند و ظاهراً مشکلی وجود ندارد.
با تشکر از همراهی شما با مجله فرادرس
سلام وقت بخیر. آیا امکانش هست به جای تایم فریم روزانه، اطلاعات هفتگی رو گرفت؟ اگر بله چطور؟
سلام، برای دریافت سابقه قیمت، کد مورد نظر زمان طولانی ای درحال اجرا است و خروجی نداره، ممنون میشم راهنمایی کنید. مثلا کد زیر:
DF4 = tse.Get_Price_History(stock=’شپنا’,
start_date=’1397-01-01′,
end_date=’1399-01-01′,
ignore_date=False,
adjust_price=True,
show_weekday=True,
double_date=True)
ممنون از مطالب ارزشمند شما
آیا امکان دریافت تاریخچه قیمتی در تایم فریم های کمتر از روزانه وجود داره؟
از مطالب شما نتونستم بفهمم که میشه یا نه؟
سلام ممنون بابت مطالب ارزشمندتون .من تازه پایتون رو شروع کردم متاسفانه نمیتونم خروجی گرافیکی نمودارها رو بگیرم
سلام، در صورتی که خطای مربوط به عدم وجود کتابخانه matplotlib یا mplfinance را دریافت میکنید، با اجرای دستور pip install matplotlib mpl-finance در CMD این دو کتابخانه را نصب کنید. در صورتی که از سیستم عاملی به جز ویندوز استفاده میکنید، باید دستور مربوط به آن سیستم عامل را اجرا کنید.
سلام برای دریافت سابقه قیمت پایانی کل سهام ها در یک تابع باید چه کاری انجام بدم؟
قصد داشتم از حلقه ی تکرار برای لیست کل اسم سهام استفاده کنم اما موقق نشدم
سلام،
از تابع finpy_tse.Build_Market_StockList() میتوانید برای دریافت لیست تمامی نمادها استفاده کنید. تابع finpy_tse.Build_PricePanel() نیز با دریافت همان لیست، میتواند پنل قیمت برای تمامی نمادها را نمایش دهد.
سلام، با توجه به تغییر طراحی سایت بورس اطلاعات از طریق توابع بالا قابل دریافت نیستند لذا یا باید به اول تمام آدرسهای داخل توابع .old اضافه شود یا توابع متناسب با آدرس جدید نوشته شود، از کجا میتوانیم به source توابع فوق دسترسی پیدا کنیم؟
آیا میتونم برای داده های پایان نامه حسابداری (اقلام ترازنامه.سود و زیان.صورت جریان وجه نقد) در ۵ سال اخیر از پایتون استفاده کنم؟ چطور باید اینکار رو انجام بدم؟
سلام، در صورتی که این اطلاعات بر روی یک سایت در دسترس باشد یا توسط یک API در اختیار ما قرار گیرد، به راحتی میتوان آنها را جمعآوری کرد. توجه داشته باشید که هرگونه تغییر در چینش، ترتیب و … ایگونه فایلهای متنی، ممکن است باعث مشکلاتی در روند کار کدها نوشته شده شود، به همین دلیل باید تمامی فایلها از یک الگوی ثابت یا حداقل یک روند ثابت پیروی کنند.
سلام
واسه من همین کد ارور Unable to parse string “i.d=function(e” at position 0
میده .
چجوری میتونم اینو رفع کنم ؟
تشکر
سلام وقت بخیر
من میخوام دیتاهارو بگیرم با این خطا مواجه میشم
HTTPSConnectionPool(host=’www.ifb.ir’, port=443): Max retries exceeded
محدودیت دانلود داریم ؟
سلام، همانگونه که از پیام Max retries exceeded مشخص است، تعداد درخواستهای زیادی در واحد زمان از سایت انجام شده است و سایت موقتاٌ دسترسی شما به این سرویس را بسته است. برای جلوگیری از این مشکل میتوانید تعداد درخواستها را کم کرده و مجموعه دادههای دریافتی را برای استفادههای بعدی ذخیره کنید.
درود، امکان دریافت تاریخچه تایم فریم زیر روزانه وجود داره آیا؟
Documentationهارو خوندم، مشخص نبود این موضوع
فرض کنید یک اکسل داریم که اطلاعات روزانه برای هر نماد رو در یک سطر داره
و هر نماد هم سابقش تا روز معاملاتی قبل در اکسل مخصوص خودش هست.
حالا من باید نماد رو از هرسطر بخونم وفایل اکسل اون نماد رو باز کنم و اطلاعات روز رو در سطر آخر اکسل سابقه بنویسم و ببندمش و برای تک تک نماد ها یا سطر اکسل اطلاعات روزانه (همون خروجی اکسل لینک فیلتر بورس) انجامش بده
سلام
خسته نباشین
چطور میتونم این داده ها رو تو برنامه نویسی اندروید پیاده کنم؟ آیا بورس توابعی برای استفاده از داده هاش داره که بشه ازش استفاده کرد؟و اینکه شما توابع رو از کجا اوردین
ممنونم
سلام،
وقتتون بخیر،
اگر قصد استفاده از زبان برنامهنویسی پایتون را داشته باشید، میتوانید از کتابخانههای موجود استفاده کنید، در غیر این صورت میتواند با توجه به کد هر نماد، اطلاعات آن را از سایت بورس تهران دریافت نمایید.
سلام، با استفاده از کتابخانه Pandas و ماژول os این کار قابل انجام میباشد.
سلام باتشکر از مقاله شما
بببخشید من میخوام مظنه قیمت تو اولین پله سفارشات روبعد از هر معامله برای ی سهم ببینم
چجوری می تونم این کار رو انجام بدم
سلام، این اطلاعات از دفتر سفارش (Order Book) قابل استخراج است. با توجه به بازار و نماد مورد نظر، میتوان از امکانات و APIهای مختلف استفاده نمود. برای دریافت و پردازش دفاتر سفارش در پایتون، در حوزه رمزارزها آموزشی تهیه و منتشر شده است.
سلام
آیا میشه برای تایم فریم مثلا ده دقیقه اطلاعات لحظه ای و تاریخچه رو دانلود کرد؟
سلام،
برای بررسی امکانات موجود در این کتابخانه، میتوانید به Documentationهای ایجاد شده مراجعه نمایید.
در صورت نبود چنین امکاناتی، میتوان با استفاده از Web Crawling اطلاعات مورد نیاز را استخراج کرد. مجموعه فرادرس آموزشهای متنوعی در این حوزه تهیه کرده است.
درود بر شما
من میخواستم corr بین یک نماد وشاخص رو بگیرم، خطا داد گفت تعداد نمونه ها برابر نیست.
این مشکل رو باید چه جوری برطرف کرد؟
با توجه به اینکه شاخص به ازای تمامی روزهای غیرتعطیل موجود میباشد اما قسمت نماد ممکن است برای برخی روزهای غیرتعطیل ناموجود باشد، خطای طول را خواهیم داشت. برای رفع این مشکل میتواند تنها از تواریخی برای محاسبه همبستگی استفاده کرد که مقدار شاخص و نماد هر دو موجود هستند. به این منظور میتوانید دو دیتافریم مربوط به قیمت نماد و مقدار شاخص را با استفاده از تابع pandas.concat به هم چسبانده و سطور حاوی مقادیر NaN را با استفاده از DF.drona حذف نمایید.
سلام بسیار ممنون از شما به خاطر مقاله جامع – دقیق – روان و مفیدی در سایت فرادرس قرار دادید
برای من که اطلاعاتم کم بود اموزنده بود
سلام.
آیا امکان داره که رسم نمودارpnf را کاملتر توضیح بدید؟؟
سلام
ایا میشه کدی برای سرخطی زدن نوشت؟ ممنون میشم راهنمایی کنید
سلام، برای این منظور میتوانید ورودی type مربوط به تابع mplfinance.plot را به pnf تغییر دهید.