سری‌های زمانی و بیت‌کوین

تا حالا به این فکر کردید که روزی چند ساعت توی تلگرام هستید؟ چند ساعت از روزتون رو دارید درس می‌خونید؟ میزان خوابتون توی ۳ ماه اخیر چقدر کم یا زیاد شده؟ بخش عظیمی از اطلاعات اطرافمون رو می‌شه با سری‌های زمانی مدل کرد. سری‌های زمانی تمام اطلاعاتی هستند که یک بُعد زمان هم دارند. بُعد زمان می‌تونه دقت‌های مختلفی داشته باشه، از میلی‌ثانیه گرفته تا سال و قرن. توی این پست می‌خوام در مورد این که چقدر استخراج سری‌های زمانی از اینترنت راحته صحبت کنم و چند ابزار کاربردی معرفی کنم. بیت‌کوینبیت‌کوین واحد پول الکترونیکی هستش که اخیراً خیلی سر و صدا به پا کرده و از ۳۰۰ دلار در سال ۲۰۱۰، الان تونسته به ۳۰۰۰ دلار برسه و افرادی که اون اوایل روش سرمایه‌گذاری کرده بودند الان میلیاردر شدند. من هم اخیراً یه مقداری بیتکوین خریدم و برام مهم بود که بدونم کی دارم ضرر می‌کنم، کی سود می‌کنم، چه موقعی بخرم بهتره و چه موقعی بفروشم بیشترین سود رو کردم. در ایران نیز چندین سایت هستند که می‌تونید ازشون بیتکوین بخرید، من برای این کار سایت coinex رو انتخاب کردم. این سایت مثل اکثر سایت‌های دیگه فقط قیمت لحظه‌ای خرید و فروش رو نشون می‌داد و نمی‌گفت که مثلاً نسبت به ۳ ساعت پیش بیشتر شده یا کمتر. با دیدن یک عدد نمی‌شد فهمید که آیا الان موقع خوبی برای خرید و فروش هستش یا نه، نمودارهای سایت‌های خارجی هم به دلار بود و دیگه نرخ تبدیل رو در نظر نمی‌گرفتند. بنابراین مجبور شدم دست به کار بشم و خودم نمودارشو بکشم.جمع‌آوریجمع‌آوری داده کار سختی نبود، کافی بود به کمک یک اسکریپت پایتون، هر دقیقه یک بار صفحه اول سایت رو بگیرم و اطلاعاتی که می‌خوام رو از توش دربیارم. تنها نکته‌ای که همیشه باید تو نوشتن چنین کدهایی حواستون بهش باشه اینه که شما دارید با اینترنت کار می‌کنید! به هر دلیلی اینترنتتون یا سایت موردنظرتون به مشکل بخوره و دقیقه بعدی درست بشه، اما برنامه شما نباید متوقف بشه، بنابراین مجبورید که کل کدتون رو دور یه try/except گنده بذارید یا اگر حوصله دارید دونه دونه حالات خطا رو در نظر بگیرید:import requests import time import re from datetime import datetime while True: try: txt=requests.get('https://coinex.ir').text bit_sell = int(re.findall(u'<h2>قیمت فروش هر بیت کوین: (.+) ریال</h2>',txt)[0].replace(',','')) bit_buy = int(re.findall(u'<h2>قیمت خرید هر بیت کوین: (.+) ریال</h2>',txt)[0].replace(',','')) except Exception as e: print('Problem %s at %s' % (e, datetime.now())) time.sleep(60) continue # send the data time.sleep(60) 1234567891011121314151617ذخیره‌سازیگرافیت یک ابزار برای کارکردن با سری‌های زمانی هستش و یک پایگاه‌داده برای ذخیره‌سازی سری‌های زمانی به صورت بهینه داره. به چنین پایگاه داده‌هایی، پایگاه داده سری‌زمانی یا Time series database می‌گن. ما از این ابزار تو شرکتمون برای مانیتور کردن وضعیت سرورها و اینجور چیزها استفاده می‌کنیم و خیلی هم راحت و خوب داره کارشو می‌کنه. برای راه‌اندازیش این ایمیج داکر رو پیشنهاد می‌کنم. خوبی گرافیت در راحتی استفاده ازش هست. به تکه کد زیر توجه کنید:import graphitesend graphitesend.send('bitcoin.buy', bit_buy) 12اینجا توی خط دوم داریم می‌گیم که مقدار متریک bitcoin.buy در زمان فعلی رو برابر با مقدار bit_buy قرار بده و بقیه اش رو دیگه خودش هندل می‌کنه. و اما متریک چیه دیگه؟متریکدر مجموعه اصطلاحات گرافیت به یک سری زمانی می‌گن متریک. هر متریک یک اسم داره که یک ساختار درختی مشابه ساختار فایل‌ها تو سیستم عامل داره. مثلاً من دو تا متریک bitcoin.buy و bitcoin.sell دارم و اگر بخوام جفتشون رو انتخاب کنم می‌تونم بنویسم *.bitcoin یعنی انگار زیر فولدر bitcoin دو تا فایل buy و sell وجود داره که اینجوری جفتشون رو انتخاب می‌کنم. خب حالا توی هر متریک دقیقاً چی ذخیره می‌شه؟ در واقع هر متریک تعداد زیادی جفت مرتب (زمان، مقدار) هستش که داره نشون می‌ده تو هر زمانی مقدار این متریک چقدر بوده. متریک‌ها به مرور زمان تجمیع می‌شن که حجم کمتری بگیرن و کلی کارهای مختلف می‌شه روشون انجام داد.تصویرسازیگرافانا ابزاری برای نمایش دادن سری‌های زمانی هستش که به تعداد زیادی دیتابیس مختلف می‌تونه وصل بشه. استک گرافانا+ statsd (که در موردش توضیح ندادم) + graphite یک استک خیلی قوی و بالغ برای مانیتورینگ هستش که خیلی جاها دارن ازش استفاده می‌کنن. من نیز از همین ابزار برای نمایش نمودارهام استفاده کردم. نتیجه‌گیریراحتی تعامل با داده یکی از مهم‌ترین ویژگی‌های این مجموعه ابزار هستش. گرافیت و گرافانا کار ذخیره‌سازی و نمایش رو خیلی آسون می‌کنن. این که به راحتی بتونید با دیتا سر و کله بزنید و ازش اطلاعات استخراج کنید خیلی فاکتور مهمیه و به نظرم این کار با این ابزارها شدنی هستش. ممکنه راه‌اندازی این ابزارها کمی براتون سخت باشه، در این صورت استفاده از این سایت رو برای تست بهتون پیشنهاد می‌کنم. ما تونستیم با حدود ۱۰ خط کد و راه‌اندازی گرافیت، دیتای قیمت بیت‌کوین رو در طول زمان داشته باشیم و تصمیمات عاقلانه‌تری نسبت به خرید و فروشش بگیریم. با گرافیت می‌تونید کوئری‌های خیلی پیچیده‌ای روی متریک‌ها بزنید. مثلاً دو تا سری زمانی رو تو هم ضرب کنید، سری زمانی که کمترین میانگین رو داره رو پیدا کنید و کلی کارهای هیجان‌انگیز دیگه! کاربرد اصلی این ابزارها برای مانیتورینگ سرورها و دیدن اطلاعات حیاتی مثل تعداد درخواست‌ها بر ثانیه، میزان رم خالی و ... هستش، اما ازشون می‌شه برای کارهای این مدلی هم استفاده کرد. این ابزارها قطعاً قرار نیست جواب تمام سوالاتتون از سری‌های زمانی رو بدن، ازشون توقع آچارفرانسه نداشته باشید. همچنان برای انجام کارهای پیچیده‌تر باید به ابزارهای تخصصی خودشون رجوع کنیم.پی‌نوشت: نسخه‌اول این پست حدود ۳ ماه پیش نوشته شده بود. بیت‌کوین رکورد ۴۰۰۰ دلار رو هم شکوند.پی‌نوشت ۲: گرافانا در نسخه‌های جدیدش قابلیت وصل شدن به دیتابیس MySql رو هم اضافه کرده، اگر کلی داده‌ی زمانی تو همچین دیتابیسی دارید می‌تونید خوشحال باشید!