پیش‌بینی قیمت سهام با استفاده از لایبرری PHP-ML

گرچه PHP زبانی ایده‌آل برای ساخت یک اپلیکیشن هوش‌مصنوعی نیست، اما این کار امکان‌پذیر است و کاملا به خوبی کار می‌کند. در این پست، در ساعت 16، قیمت‌های بسته شدن (ساعت 17) شرکت‌های DAX30  آلمان را پیش‌بینی می‌کنیم. البته می‌توانید از DAX30 نیز استفاده کنید. بنابراین، در عمل یک توصیه به اقدام (خرید/فروش) دریافت می‌کنیم و بازده مورد انتظارمان را می‌بینیم. سپس CFDها را با لوریج بالا معامله می‌کنیم و پولدار می‌شویم.

پیش‌بینی قیمت سهام با کمک هوش‌مصنوعی - یادگیری ماشین در PHP

اصطلاحات فنی

CFD قراردادی بین طرفین معامله است که خریدار و فروشنده نامیده می‌شوند و به واسطه آن، فروشنده مابه‌تفاوت بین ارزش فعلی دارایی و ارزش آن در زمان عقد قرارداد را می‌پردازد و اگر این تفاوت منفی باشد، خریدار باید مابه‌تفاوت را بپردازد. در واقع هدف از این قراردادها کسب مالکیت نیست، بلکه معامله صرفا به منظور کسب سود ناشی از تفاوت قیمت است.

لوریج (Leverage) یا اهرم مالی، ابزار یا اعتباری است که توسط کارگزار در اختیار معامله‌گران قرار می‌گیرد تا قدرت معامله تا چندین برابر سرمایه خود داشته باشند. برای مثال لوریج 1:100 (یک به صد که خیلی زیاد است)، یعنی برای هر معامله نیاز به سرمایه‌ای معادل یک درصد آن است. البته باید توجه کنید که لوریج سود و زیان بالقوه را خیلی افزایش می‌دهد و همانطور که استفاده از آن با کسب سود، سرمایه شما را سریعتر افزایش می‌دهد، هرگونه ضرر نیز، با همان نسبت سرمایه شما را از بین می‌برد، در واقع لوریج مانند تیغ دو لبه‌ای است که هم می‌تواند فرصت باشد و هم تهدید.

دیتابیس ما بر اساس تمام قیمت‌های  DAX30 طی یک سال با تاخیر 5 دقیقه‌ای ایجاد شده است. داده‌ها را از سال 2015 (بیش از 2 میلیون رکورد) داریم، اما آموزش به صورت همیشگی ادامه خواهد داشت... بنابراین، برای اولین تست‌ها به طور قابل توجهی از میزان داده کمتری (حدود 40 هزار رکورد) استفاده می‌کنیم.

چگونه به صورت آنی قیمت‌های سهام را به دست آوریم

راه‌اندازی هوش مصنوعی بسیار سریع و ساده است. این کار را با 3 خط کد می‌توان انجام داد:

  • تعریف متغییرها
  • آموزش
  • پیش‌بینی

به همین سادگی. به دست آوردن داده‌ها و تبدیل آن‌ها به یک فرمت مناسب، بسیار سخت‌تر است.

اگر پول دارید، می‌توانید دسترسی به یک API را برای دسترسی به داده‌ها بخرید. از آنجا که ما نمی‌خواهیم پول بپردازیم و در ابتدا می‌خواهیم با استفاده از این هوش‌مصنوعی پول به دست بیاوریم، اسکریپتی کوچک نوشته‌ایم که قیمت‌ها را هر 5 دقیقه یکبار از finanzen.net (یک صفحه سهام آلمانی) دریافت می‌کند. قیمت‌های آنی سهام DAX30 را می‌توانید در قیمت‌های آنی DAX30 بیابید.

این صفحه به شما اجازه می‌دهد تا به خوبی در داده‌ها خزیده و داده‌ها را به شکل زیر به دست آورید:

$html = file_get_contents('http://www.finanzen.net/aktien/DAX-Realtimekurse');
$table = explode('<table class="table table-vertical-center">',$html);
$table = explode('</table>',$table[1]);
$table = explode('</thead>',$table[0]);
$rows = explode('<tr>',$table[1]);
unset($rows[0]);
$rows = array_slice($rows,0,31);
foreach($rows AS $row){
$cols = explode('',$row);
$name = utf8_encode(strip_tags($cols[1]));
$lastday = toNumber(strip_tags($cols[3]));
$bid = toNumber(strip_tags($cols[4]));
$ask = toNumber(strip_tags($cols[5]));
$percent = toNumber(strip_tags($cols[6]));
$sql = "INSERT INTO dax30(name,lastday,bid,ask,percent,timestamp)VALUES(?,?,?,?,?,NOW())";
$stmt = $db->prepare($sql);
$stmt->bind_param('sdddd',$name,$lastday,$bid,$ask,$percent);
$stmt->execute();
$stmt->close();
echo $name.': Last Day: '.$lastday.', Bid: '.$bid.', Ask: '.$ask.', Percent: '.$prozent."";
}
function toNumber($n){
return trim(str_replace('%','',str_replace(',','.',str_replace('.','',$n))));
}

گرچه این تمیزترین کد نیست، اما به اندازه کافی خوب کار می‌کند. فانکشن toNumber() مقادیر ورودی را بدون توجه به اینکه چه هستند به عدد تبدیل می‌کند. حالا یک کرون‌جاب راه‌اندازی می‌کنیم تا هر پنج دقیقه یکبار صفحه را لود کند. متوجه خواهید شد که داده‌ها بسیار سریع لود می‌شوند. به خاطر داشته باشید که خزنده شما نباید در تعطیلات و پس از ساعت بسته شده بازار سهام (در آلمان ساعت بازار سهام 9 تا 17:30 باز است) به جمع‌آوری اطلاعات بپردازد.

نصب PHP-ML - روشی آسان

ما از لایبرری PHP-ML به عنوان هوش‌مصنوعی استفاده می‌کنیم. سورس‌کد آن را در گیت‌هاب و داکیومنت آن را در باورژن می‌توانید بیابید. با استفاده از کامپوزر، آن را سریع و آسان نصب کنید (یا آن را از گیت‌هاب دانلود کرده و از زیپ خارج کنید):

composer require php-ai/php-ml

داده‌های خود را آماده کنید

اکنون (پس از گذشت حدود 2 هفته گذشته) که به اندازه کافی داده داریم، داده‌ها را از دیتابیس گرفته و در یک آرایه بزرگ چند بعدی قرار می‌دهیم. در درجه‌ی اول به ستون درصد (percent) علاقمند هستیم. که تغییر در درصد با قیمت بسته شدن روز قبل (آخرین روز) مقایسه شده است. ما این کار را به شکل زیر انجام می‌دهیم:

$sql = "SELECT percent,DATE_FORMAT(timestamp,'%d.%m.%Y'),DATE(timestamp),name FROM dax30 WHERE TIME(timestamp) >= '09:00:00' AND TIME(timestamp) < '17:36:00' ORDER BY name ASC, timestamp ASC";
$stmt = $db->prepare($sql);
$stmt->execute();
$stmt->bind_result($percent,$date,$date2,$name);
$stmt->store_result();
$i = 0;
$prev = '';
$prevD = '';
while($stmt->fetch()){
    if($prev != $name || $date != $prevD){
        $i = 0;
        $prev = $name;
        $prevD = $date;
    }
    if($i < $maxInput) // $maxInput should be the number of today's entries
        $stocks[$name][$date]['price'][] = $percent;
    $stocks[$name][$date]['closing'] = $percent;
    $i++;
}
$stmt->free_result();
$stmt->close();

از آنجایی که در روز پیش‌بینی قیمت‌ها، فقط قیمت‌ها تا زمان فعلی را می‌دانیم، هوش مصنوعی تنها باید با داده‌های روز قبل تا به حال آموزش داده شود. بیایید آرایه را دوباره فرمت (داده‌های آن را مرتب) کنیم، تا بتوانیم آن را در هوش‌مصنوعی استفاده کنیم. هوش‌مصنوعی به دو آرایه نیاز دارد: TrainingSet و ResultSet. آرایه TrainingSet شامل تمامی قیمت‌های روز تا ساعت 16 است، در حالی که ResultSet حاوی قیمت‌های مربوط به بسته شدن در ساعت 17:30 است.

foreach($stocks AS $name=>$stock){
    $today[$name] = array_pop($stock); // We skip the current day obviously
    foreach($stock AS $data=>$stockDay){
        $trainingsSet[] = $stockDay["price"];
        $resultSet[] = $stockDay["closing"];
    }
}

کدام برآوردگر (estimator) مناسب‌تر است

اگر به داکیومنت هوش مصنوعی مراجعه کنید، متوجه خواهید شد که برآوردگرهای (همان فانکشن تخمین در هوش‌مصنوعی) مختلف بسیاری در دسترس هستند، از جمله classification و regression و clustering و غیره. علاوه بر آماده‌سازی داده‌ها، انتخاب درست برآوردگر، موضوع اساسی است.

چیت‌شیت برآوردگر PHP-ML

چیت‌شیت برآوردگر PHP-ML - منبع

Classification

Classification برای طبقه‌بندی ورودی‌های خاص استفاده می‌شود. بدیهی است که اهمیت استفاده از آن زمانی است که Classification برای اختصاص ورودی‌ها به یک گروه استفاده می‌شود. برای مثال، رنگ‌های مختلفی را به عنوان ورودی دارید و می‌خواهید به هوش‌مصنوعی بیاموزید که رنگ تیره است یا روشن.

Clustering

Clustering برای اختصاص ورودی‌ها به گروه‌های مختلف استفاده می‌شود. به عنوان مثال، می‌توانید خصوصیات مختلف افراد (سن، جنسیت، درآمد و غیره) را به عنوان ورودی‌ها استفاده کنید و خروجی می‌تواند تحصیلات افراد باشد.

Regression

یک regression سعی می‌کند تا رابطه‌ها را به صورت کمی (یعنی قابل سنجش و اندازه گیری)، پیش‌بینی یا توصیف نماید. ورودی‌ها و خروجی‌ها، مقادیر کمی هستند. برای مثال قیمت‌های سهام. بله، ما در این پروژه، رگرسیون را انتخاب می‌کنیم.

این به من خیلی کمک نمی‌کند

بله، می‌دانیم و درک می‌کنیم. خوشبختانه Scikit-Learn فلوچارتی برای تشخیص برآوردگر صحیح تهیه کرده است که در این پست قرار داده‌ایم. استفاده از این فلوچارت یافتن برآوردگر مناسب برای پروژه شما را نسبتا ساده می‌سازد.

در PHP-ML دو نوع متفاوت از regression وجود دارد: LeastSquares و SVR. چیت‌شیت بالا را مشاهده کنید، به نظر می رسد که SVR کاملا مناسب باشد.

PHP-ML: آموزش دادن به اپلیکیشن هوش‌مصنوعی

اکنون که داده‌ها را آماده کرده‌ایم، می‌توانیم اپلیکیشن هوش‌مصنوعی را آموزش دهیم. همانطوری که در ابتدای پست گفتیم، PHP الزاما بهترین و سریع‌ترین زبان در حوزه یادگیری ماشین نیست. سعی کنید بیش از حد داده به آن نخورانید. برای 2 میلیون رکورد، تقریبا به 4 ساعت زمان برای آموزش نیاز دارد.

راه اندازی اولیه PHP-ML

راه اندازی PHP-ML را با تعریف رگرسیون با استفاده از کرنل POLYNOMIAL شروع کردیم. (Linear و RBF و SIGMOID مقادیر خوبی را ارائه نمی‌دهند.)

require_once '/var/www/vendor/autoload.php';
use Phpml\Regression\SVR;
use Phpml\SupportVectorMachine\Kernel;
use Phpml\ModelManager;
$regression = new SVR(Kernel::POLYNOMIAL, 3, 0.1, 10,0.3,0.1,3,200,true); 

متغییرهای نمونه SVR() بهترین نتایج را به ما دادند. البته، می‌توانید آن‌ها را تغییر داده و با مقادیر متفاوتی امتحان کنید.

آموزش با استفاده از PHP-ML

بیایید آموزش دادن را شروع کنیم. برای چیزی که اکنون انتظار داریم، کد زیر فوق العاده بی نظیر است:

$regression->train($trainingsSet, $resultSet);

همه کاری که باید انجام دهید همین است و بس. از آنجایی که داده‌هایی داریم که در بالا آن‌ها را به خوبی آماده کرده‌ایم، نیاز به هیچ کار بیشتری نداریم که مجبور باشیم اینجا انجام دهیم. به دلیلی ممکن است کسی انتظار بیشتر از این را داشته باشد. اینکه چقدر جادو در این یک خط کد اتفاق افتاده است را در زمان اجرای اسکریپت متوجه خواهیم شد. بخش آموزش دشوار است و بسته به مقدار داده‌های آزمون ، مدت زمانی طول می‌کشد.

آموزش را برای پیش‌بینی‌های سریع‌تر ذخیره کنید

این مرحله اختیاری است و تنها برای مجموعه‌های داده خیلی بزرگ سودمند است. چیز خوبی که در مورد PHP AI وجود دارد، توانایی ذخیره آموزش‌ها است. به این معنی که مجبور نیستیم برای هر پیش‌بینی، دوباره آموزش را از ابتدا انجام دهیم. می‌توانیم آموزش‌های داده شده را بعدا باز کنیم و پیش‌بینی را بر اساس آن‌ها انجام دهیم. این کار به میزان زیادی در وقت صرفه‌جویی می‌کند و تنظیمات مختلف آسان و سریع را می‌توانید مقایسه کنید:

$filepath = VENDOR.'php-ai/php-ml/var/model.data';
$modelManager = new ModelManager();
$modelManager->saveToFile($this->regression, $filepath);

برای لود آموزش‌ها در آینده، تنها نیاز به لود کردن فایل model.data داریم:

$filepath = VENDOR.'php-ai/php-ml/var/model_long.data';
$modelManager = new ModelManager();
$regression = $modelManager->restoreFromFile($filepath);

پیش‌بینی به وسیله PHP-ML

برای پیش‌بینی قیمت بسته شده امروز، به قیمت‌های امروز نیاز داریم (که در $today ذخیره کرده‌ایم). اکنون امیدواریم که قیمت بسته‌شدن پیش‌بینی شده، تا حد ممکن به قیمت بسته‌شدن واقعی نزدیک باشد.

foreach($today AS $name=>$predict){
    $predicted = round($regression->predict($predict["price"]),2);
    $predictedPerformance = $predicted - $predict["price"][(count($predict["price"])-1)];
    $price = $predict["price"][count($predict["price"])-1];
    echo $name.": Price: ".$price.", Predicted: ".$predicted.", Performance: ".$predictedPerformance."
";
}

خروجی ما باید چیزی شبیه به این باشد:

نتیجه پیش‌بینی قیمت بسته شدن سهام

به عبارت دیگر، در معاملات CFD برای تمامی مقادیر پیش‌بینی شده کمتر از صفر، باید بفروشید و برای تمامی مقادیر بزرگتر از صفر باید بخرید. به جهت واضح‌تر ساختن پیش‌بینی، آن را در دیتابیس ذخیره کردیم و یک دید کلی از آپدیت تمامی مقادیر با فواصل 5 دقیقه‌ای ساختیم.

دید کلی از مقادیر

این دیدکلی به ما نشان می‌دهد که کدام معاملات ارزشمند هستند و چگونه باید معامله کنیم. اگر عملکرد پیش‌بینی شده کمتر از 0.6٪ باشد، توصیه‌ای دریافت نخواهیم کرد، اما اگر بزرگتر از 5٪ باشد، Check ظاهر خواهد شد به این معنی که خیلی بعید است و احتمالا هوش‌مصنوعی اشتباه کرده است. در حالت واقعی، باید عملکردی کمتر از 2.5٪ یا بیشتر را انتخاب کنید.

نتیجه‌گیری

متاسفانه، با این ابزار به ندرت می‌توان پولی کسب کرد. هدف اصلی این پست، آشنا نمودن شما با هوش‌مصنوعی و یادگیری ماشین است. لایبرری PHP-ML بسیار تمیز است و به خوبی کار می‌کند. گرچه برآوردگر رگرسیون 100 درصد مناسب نیست، اما در بیش از 60٪ موارد به سمت نتایج صحیح انحراف دارد.

همه چیز با یک شبکه عصبی بازگشتی (Recurrent Neual Network) مانند LSTM، جالب‌تر و بهتر می‌شود. بنابراین، ممکن است که هوش‌مصنوعی (مانند یک انسان) تصمیمات معناداری را در پرتو گذشته و رویدادهای گذشته بگیرد. تا آنجایی که ما می‌دانیم، PHP هیچ لایبرری آماده‌ای برای استفاده ندارد و احتمالا هرگز نخواهد داشت. با استفاده از زبان پایتون و به وسیله تنسورفلو (TensorFlow) که لایبرری هوش مصنوعی گوگل است، این کار امکان‌پذیراست.

مجتبی پاکزاد

مجتبی پاکزاد

حل مساله و چالش رو خیلی دوست دارم و رابطه خیلی خوبی با ریاضیات، برنامه‌نویسی و اقتصاد دارم. علاقه زیادی به هوش‌مصنوعی، یادگیری ماشین و موضوعات مرتبط دارم.

دیدگاه‌ها


ثبت دیدگاه