private function AnalizeBuy($exdata) { $exlen = sizeof($exdata); $prev_stok_direction = 0; // Предыдущее направление $stok_direction = 0; // Текущее направление $lastbuy = Buy::getLast(); // Получаем дату последней продажи $canbuy = false; for ($i = 0; $i < $exlen; $i++) { $exitem = $exdata[$i]; // Если есть что анализировать if ($i <= $this->buystep_n + 1) { continue; } //Определяем направление $exstep = array_slice($exdata, $i - $this->buystep_n, $this->buystep_n + 1); $stok_direction = $this->getDirection($exstep, 'buy'); Log::Add($exitem['dt'], 'Направление курса: ' . $stok_direction); // Изменение курса if ($prev_stok_direction != $stok_direction) { $canbuy = true; } // Если анализ до последней покупки - ничего не покупаем if ($exitem['dt'] <= $lastbuy->dtm) { $canbuy = false; } if ($this->virtual == 1) { // Пока не дошли до последнего (актуального) элемента не покупаем if ($i < $exlen - 1) { $canbuy = false; } } // Для логов if ($this->virtual == 1 && $i == $exlen - 1 && !$canbuy) { Log::Add($exitem['dt'], 'Не купил, курс не меняется: ' . $prev_stok_direction . ' => ' . $stok_direction, 1); } // Проверяем покупку if ($stok_direction == 1 && $canbuy) { // Если сумма покупки больше баланса то уменьшить до баланса /*if ($this->buy_sum>$this->balance) $this->buy_sum=$this->balance; $buy_value = floor(($this->buy_sum / $exitem['buy']*(1+$this->fee))*10000)/10000; // Если 0 то поищем подешевле if ($buy_value == 0) continue; */ $price = $exitem['buy'] * $this->buy_value * (1 + $this->fee); // Првоеряем остаток денег на балансе, если кончились - выходим if ($this->balance - $price < 0) { break; } // Покупаем $btc = new Buy(); $btc->dtm = $exitem['dt']; $btc->count = $this->buy_value; $btc->price = $exitem['buy']; $btc->summ = $price; if ($btc->save()) { $this->bought[] = $btc; $this->total_buy += $price; // Всего куплено $this->balance -= $price; // Актуализируем баланс RUB $this->balance_btc += $this->buy_value; // Актуализируем баланс BTC $this->order_cnt++; // Увеличиваем число сделок $canbuy = false; // Блокируем покупки до конца роста Log::Add($exitem['dt'], '<b>Купил (№' . $btc->id . ') ' . $this->buy_value . ' ед. за ' . $exitem['buy'] . ' (' . $exitem['buy'] * $this->fee . ' комиссия) на сумму ' . $price . ' руб.</b>', 1); } } $prev_stok_direction = $stok_direction; } }
public function NeedBuy() { $reason = array(); // Фиксируем причину покупки $curtime = $this->curtime; //Дата операции $dt = date('Y-m-d H:i:s', $curtime); // Есть ли деньги if ($this->balance < $this->current_exchange->buy * self::buy_value) { Log::notbuy('Не хватает денег, осталось ' . $this->balance . ', нужно ' . $this->current_exchange->buy * self::buy_value); return false; } else { $reason['balance'] = 'Хватает денег ' . $this->balance . '>' . $this->current_exchange->buy * self::buy_value; } /* // Если текущая цена выше средней не покупаем $from = date('Y-m-d H:i:s',$this->curtime-60*60*24*7); $avg_buy = Exchange::getAvg('buy', $from, date('Y-m-d H:i:s', $this->curtime)); if ($avg_buy && $avg_buy<$this->current_exchange->buy) { Log::notbuy('Цена выше средней за 7 дн. ('.$avg_buy.'<'.$this->current_exchange->buy.'), не покупаем.'); return false; } else $reason['avg_price']='Цена ниже средней за 7 дн. '.('.$avg_buy.'>'.$this->current_exchange->buy.'); */ $lastBuy = Buy::getLast(); $lastSell = Sell::getLast(); if ($lastBuy) { $tm = strtotime($lastBuy->dtm) + self::min_buy_interval; $diff = 1 - $this->current_exchange->buy / $lastBuy->price; if ($tm > $this->curtime && $diff < $this->buy_imp_dif) { // Не покупаем Log::notbuy('Уже была покупка ' . ($this->curtime - strtotime($lastBuy->dtm)) / 60 . ' мин. назад (допустимы покупки раз в ' . self::min_buy_interval / 60 . ' мин. при отсутствии ощутимого падения цены), прошлая цена ' . $lastBuy->price . ' руб., текущая ' . $this->current_exchange->buy . ' руб., разница ' . $diff . '% , мин. порог для покупки ' . $this->sell_imp_dif * 100 . '%.'); // if ($lastSell) Log::notbuy('Прошлая продажа была '.$lastSell->dtm.', это до последней покупки '.$lastBuy->dtm); return false; } else { $reason['last_buy'] = 'Прошлая покупка была ' . ($this->curtime - strtotime($lastBuy->dtm)) / 60 . ' мин. назад (допустимы покупки раз в ' . self::min_buy_interval / 60 . ' мин. при отсутствии ощутимого падения цены), прошлая цена ' . $lastBuy->price . ' руб., текущая ' . $this->current_exchange->buy . ' руб., разница ' . $diff . '% , мин. порог для покупки ' . $this->sell_imp_dif * 100 . '% '; //if ($lastSell) $reason['last_sell'] = 'Прошлая продажа была '.$lastSell->dtm.', это после последней покупки '.$lastBuy->dtm; } } $all_tracks = array(); foreach ($this->buy_periods as $period) { $all_tracks[] = $this->getGraphImage($curtime, $period, 'buy', $this->buy_imp_dif); } //Анализируем треки $tracks = array(); $tracks = $this->getBuyTracks($all_tracks); if (!$tracks || sizeof($tracks) == 0) { Log::notbuy('Не найдено подходящих для покупки треков'); return false; } //Удаляем треки по которым уже были покупки foreach ($tracks as $key => $track) { if ($this->AlreadyBought($track['period'])) { Log::notbuy('Уже была покупка PERIOD назад по треку ' . print_r($track, true)); unset($tracks[$key]); } } // Log::AddText($this->curtime, 'Оставшиеся после отсеивания треки '.print_r($tracks, true)); // Если остались треки if (sizeof($tracks) > 0) { // Треки $reason['tracks'] = $tracks; $reason['all_tracks'] = $all_tracks; // Покупаем if ($this->startBuy($reason)) { // Резервируем время покупки foreach ($tracks as $track) { //Log::AddText($this->curtime, 'Трек <b>'.$track['track'].'</b> за '.($track['period']/60).' мин.'); //Dump::d($track); $this->ReservePeriod($track['period']); } } else { Log::notbuy('Ошибка, не удалось начать покупку'); } } else { Log::notbuy('Нет интересных покупок'); } }