/** * Загружает ряды в класс по идентификатору котировки * * @param int $stockId идентификатор котировки * @param int $type тип сравнения (1 - красный, 2 - синий) * @param array $dateRange периуд для расчета * ```php * [ * 'min' => 'yyyy-mm-dd' * 'max' => 'yyyy-mm-dd' * ] * ``` * * @return static * @throws \cs\web\Exception */ public static function initStock($stockId, $type, $dateRange = null) { $where = null; if ($dateRange) { $where = ['between', 'date', $dateRange['min'], $dateRange['max']]; } $kurs = StockKurs::query(['stock_id' => $stockId])->select(['`date`, `kurs` as `value`'])->orderBy(['date' => SORT_ASC]); if ($where) { $kurs->where($where); } $kurs = $kurs->all(); $class = null; switch ($type) { case 1: $rows = StockPrognosisRed::query(['stock_id' => $stockId])->select(['`date`, `delta` as `value`'])->orderBy(['date' => SORT_ASC]); if ($where) { $rows->where($where); } $class = \app\service\CalculatingProbability::initRows($kurs, $rows->all()); break; case 2: $rows = StockPrognosisBlue::query(['stock_id' => $stockId])->select(['`date`, `delta` as `value`'])->orderBy(['date' => SORT_ASC]); if ($where) { $rows->where($where); } $class = \app\service\CalculatingProbability::initRows($kurs, $rows->all()); break; default: throw new \cs\web\Exception('Не верный тип $dateRange'); } return $class; }
/** * Импортирует курсы сразу для всех индексов */ public function actionCandels() { $rows = Stock::query()->all(); foreach ($rows as $row) { $stock_id = $row['id']; $this->log('Попытка получить данные для: ' . $row['name']); $importer = ['params' => ['market' => $row['finam_market'], 'em' => $row['finam_em'], 'code' => $row['finam_code']]]; $class = new \app\service\DadaImporter\Finam($importer); $date = new \DateTime(); $date->sub(new \DateInterval('P7D')); $data = $class->importCandels($date->format('Y-m-d')); // стратегия: Если данные есть то, они не трогаются $dateArray = ArrayHelper::getColumn($data, 'date'); sort($dateArray); $rows2 = StockKurs::query(['between', 'date', $dateArray[0], $dateArray[count($dateArray) - 1]])->andWhere(['stock_id' => $stock_id])->all(); $dateArrayRows = ArrayHelper::getColumn($rows2, 'date'); $new = []; foreach ($data as $row) { if (!in_array($row['date'], $dateArrayRows)) { $new[] = [$stock_id, $row['date'], $row['open'], $row['high'], $row['low'], $row['close'], $row['volume'], $row['close']]; } } if (count($new) > 0) { \Yii::info('Импортированы данные: ' . VarDumper::dumpAsString($new), 'cap\\importer\\index'); $this->log('Импортированы данные: ' . VarDumper::dumpAsString($new)); StockKurs::batchInsert(['stock_id', 'date', 'open', 'high', 'low', 'close', 'volume', 'kurs'], $new); } else { $this->log('Нечего импортировать'); } } }
/** * Рисует графики с прошлым и будущим * * @param int $id идентификатор курса * * @return string */ public function actionStock_item3($id) { $item = \app\models\Stock::find($id); $start = (new \DateTime())->sub(new \DateInterval('P31D')); $end = (new \DateTime())->sub(new \DateInterval('P1D')); $isPaid = Yii::$app->user->identity->isPaid($id); $defaultParams = ['start' => $start, 'end' => $end, 'formatX' => 'd.m']; $params = ArrayHelper::merge($defaultParams, ['rows' => [\app\models\StockKurs::query(['stock_id' => $id])->andWhere(['between', 'date', $start->format('Y-m-d'), $end->format('Y-m-d')])->all()]]); $lineArrayKurs = \app\service\GraphExporter::convert($params); $params = ArrayHelper::merge($defaultParams, ['rows' => [\app\models\StockPrognosisRed::query(['stock_id' => $id])->andWhere(['between', 'date', $start->format('Y-m-d'), $end->format('Y-m-d')])->select(['date', 'delta as kurs'])->all()]]); $lineArrayRed = \app\service\GraphExporter::convert($params); $params = ArrayHelper::merge($defaultParams, ['rows' => [\app\models\StockPrognosisBlue::query(['stock_id' => $id])->andWhere(['between', 'date', $start->format('Y-m-d'), $end->format('Y-m-d')])->select(['date', 'delta as kurs'])->all()]]); $lineArrayBlue = \app\service\GraphExporter::convert($params); $lineArrayPast = \app\service\GraphUnion::convert(['x' => $lineArrayRed['x'], 'y' => [$lineArrayKurs['y'][0], $lineArrayRed['y'][0], $lineArrayBlue['y'][0]]]); if ($isPaid) { $start = new \DateTime(); $end = (new \DateTime())->add(new \DateInterval('P30D')); $defaultParams = ['start' => $start, 'end' => $end]; $params = ArrayHelper::merge($defaultParams, ['rows' => [\app\models\StockPrognosisRed::query(['stock_id' => $id])->andWhere(['between', 'date', $start->format('Y-m-d'), $end->format('Y-m-d')])->select(['date', 'delta as kurs'])->all()]]); $lineArrayRed = \app\service\GraphExporter::convert($params); $params = ArrayHelper::merge($defaultParams, ['rows' => [\app\models\StockPrognosisBlue::query(['stock_id' => $id])->andWhere(['between', 'date', $start->format('Y-m-d'), $end->format('Y-m-d')])->select(['date', 'delta as kurs'])->all()]]); $lineArrayBlue = \app\service\GraphExporter::convert($params); $lineArrayFuture = \app\service\GraphUnion::convert(['x' => $lineArrayRed['x'], 'y' => [$lineArrayRed['y'][0], $lineArrayBlue['y'][0]]]); } else { $lineArrayFuture = null; } return $this->render(['item' => $item, 'lineArrayPast' => $lineArrayPast, 'lineArrayFuture' => $lineArrayFuture, 'isPaid' => $isPaid]); }
public function actionKurs_edit($id) { return $this->render(['items' => \app\models\StockKurs::query(['stock_id' => $id])->orderBy(['date' => SORT_DESC])->all(), 'item' => \app\models\Stock::find($id)]); }
<?php use yii\helpers\Url; use yii\helpers\Html; /* @var $this \yii\web\View */ /* @var $item \app\models\Stock */ $this->title = $item->getField('name'); ?> <h1 class="page-header"><?php echo $this->title; ?> </h1> <?php echo \cs\Widget\ChartJs\Line::widget(['width' => 800, 'lineArray' => \app\service\GraphExporter::convert(['rows' => [\app\models\StockKurs::query(['stock_id' => $item->getId()])->all(), \app\models\StockPrognosis::query(['stock_id' => $item->getId()])->all()]])]);
/** * Импортирует данные с Finam в таблицу курсов * * @param int $stock_id * @param string $start дата 'yyyy-mm-dd' * @param string $end дата 'yyyy-mm-dd' * @param bool $isReplaceExisting Заменять уже имеющиеся данные * true - если в таблице уже есть курс на эту дату то он будет перезатерт * false - если в таблице уже есть курс на эту дату то он сохранится * * @throws \yii\base\InvalidConfigException */ public static function importCandels($stock_id, $start, $end, $isReplaceExisting = false) { $row = Stock::find($stock_id)->getFields(); $data = ['params' => ['market' => $row['finam_market'], 'em' => $row['finam_em'], 'code' => $row['finam_code']]]; $importer = new \app\service\DadaImporter\Finam($data); $data = $importer->importCandels($start, $end); $dateArrayRows = StockKurs::query(['between', 'date', $start, $end])->select(['date'])->andWhere(['stock_id' => $stock_id])->column(); $insert = []; $update = []; foreach ($data as $row) { if (in_array($row['date'], $dateArrayRows)) { $date = $row['date']; $row['kurs'] = $row['close']; unset($row['date']); $update[$date] = $row; } else { $insert[] = [$stock_id, $row['date'], $row['open'], $row['high'], $row['low'], $row['close'], $row['volume'], $row['close']]; } } StockKurs::batchInsert(['stock_id', 'date', 'open', 'high', 'low', 'close', 'volume', 'kurs'], $insert); if ($isReplaceExisting) { foreach ($update as $date => $fields) { (new Query())->createCommand()->update(StockKurs::TABLE, $fields, ['date' => $date, 'stock_id' => $stock_id])->execute(); } } }