private function getData($id) { $std = new stdClass(); $user = $this->user->idUser; $buy = Buy::findFirst(array('conditions' => 'idBuy = ?1 AND idUser = ?2', 'bind' => array(1 => $id, 2 => $user))); if (!$buy) { $std->data = array('No se han encontrado datos, por favor valide la información'); $std->code = 404; return $std; } else { $rec = array(); $payment = Payment::find(array('conditions' => 'idBuy = ?1 ORDER BY date DESC', 'bind' => array(1 => $id))); if (count($payment) > 0) { foreach ($payment as $p) { $array = array(); $array['id'] = $p->idPayment; $array['value'] = '$' . number_format($p->receiptValue); $array['date'] = $p->date; $rec[] = $array; } } $datos = array('code' => $buy->idBuy, 'value' => '$' . number_format($buy->value), 'dif' => '$' . number_format($buy->value - $buy->debt), 'debt' => '$' . number_format($buy->debt)); $data = array($datos, $rec); $std->data = $data; $std->code = 200; return $std; } }
public function actionTest() { $start = time(); Yii::app()->cache->flush(); Yii::app()->db->createCommand()->truncateTable(Buy::model()->tableName()); Yii::app()->db->createCommand()->truncateTable(Sell::model()->tableName()); Yii::app()->db->createCommand()->truncateTable(Order::model()->tableName()); Yii::app()->db->createCommand()->truncateTable(Balance::model()->tableName()); // Тест на 10 000 руб. Status::setParam('balance', 10000); Status::setParam('balance_btc', 0); $exs = Exchange::getAllByDt('btc_rur', '2013-12-16', '2014-01-06'); $cnt = 0; foreach ($exs as $exchange) { $obj = new stdClass(); $obj->dtm = $exchange['dt']; $obj->buy = $exchange['buy']; $obj->sell = $exchange['sell']; $cnt++; $bot = new Bot($obj); $bot->run(); } $end = time(); echo '<b>Elapsed time: ' . ($end - $start) / 60 . ' min.<br/>'; echo '<b>Steps count: ' . $cnt . '<br/>'; }
/** * Acheter ou sélectionner un objet. * * @param int $obj_id * @param int $obj_credit * @param String $trace * @return int $state */ public function select($obj_id, $obj_credit, $trace) { if (isset($this->Buyer)) { $trace .= " via SBUY"; return parent::select($obj_id, $obj_credit, $trace, $this->Buyer->getId()); } else { return 409; } }
/** * Acheter ou sélectionner des objets. * * @param String $obj_ids * @param String $trace * @return int $state */ public function multiselect($obj_ids, $trace) { if (isset($this->Buyer)) { $trace .= " via PBUY"; return parent::multiselect($obj_ids, $obj_credit, $trace, $this->Seller->getId()); } else { return 409; } }
public static function getNotSold() { $sql = "\r\n\t\t\t\t\tSELECT\r\n\t\t\t\t\t\t\tb.*\r\n\t\t\t\t\tFROM `buy` b\n\t\t\t\t\tleft join `order` o on o.buy_id = b.id\r\n\t\t\t\t\twhere\n\t\t\t\t\t\tb.sold = 0\n\t\t\t\t\t\tand\r\n\t\t\t\t\t\to.id is null\t\n\t\t\t\t\t\tand\n\t\t\t\t\t\tb.count >= " . Bot::min_order_val . "\t\t\t\t\t\r\n\t\t\t\t\t"; //if ($curtime == '2013-12-11 16:42:00') $list = Buy::model()->findAllBySql($sql); return $list; }
public function actionSell() { if ($_SERVER['HTTP_HOST'] !== 'btcbot.loc') { return; } $btc_rur = Exchange::updatePrices('btc_rur'); $bot = new Bot($btc_rur); $info = $bot->api->getInfo(); if ($info) { $bot->setBalance($info['funds']['rur']); $bot->setBalanceBtc($info['funds']['btc']); Status::setParam('balance', $info['funds']['rur']); Status::setParam('balance_btc', $info['funds']['btc']); Balance::actualize('rur', $bot->balance); Balance::actualize('btc', $bot->balance_btc); } $buy = Buy::model()->findByPk(1); $bot->startSell($buy, array('test' => 'test')); }
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 testShoulReturnTwoBillsOfOne() { $change = new Buy(8); $result = $change->getBuy(10); $this->assertEquals(array(1 => 2), $result); }
public function NeedSell() { // Составляем причину покупки $reason = array(); $curtime = $this->curtime; //Дата операции $dt = date('Y-m-d H:i:s', $curtime); //Смотрим, что продать //$bought = Buy::model()->findAll(array('condition'=>'sold=0 and order_id=0')); $bought = Buy::getNotSold(); // Если нечего продавать if (sizeof($bought) == 0) { return false; } /* // Если текущая цена ниже средней не продаем $from = date('Y-m-d H:i:s',$this->curtime-60*60*24*7); $avg_sell = Exchange::getAvg('sell', $from, date('Y-m-d H:i:s', $this->curtime)); if ($avg_sell>$this->current_exchange->sell) { Log::notsell('Цена ниже средней за 7 дн. ('.$avg_sell.'>'.$this->current_exchange->buy.'), не продаем.'); return false; } else $reason['avg_price'] = 'Текущая цена выше средней за 7 дней '.('.$this->avg_sell.'>'.$this->current_exchange->buy.'); */ // Проверяем была ли уже продажа за последнее время, если была и цена была более выгодная чем текущая то не продаем $lastSell = Sell::getLast(); if ($lastSell) { $tm = strtotime($lastSell->dtm) + self::min_sell_interval; $diff = 1 - $lastSell->price / $this->current_exchange->sell; if ($tm > $this->curtime && $diff < $this->sell_imp_dif) { Log::notsell('Уже была продажа, ждем до ' . date('Y-m-d H:i:s', $tm) . ' текущая цена ' . $this->current_exchange->sell . ' меньше прошлой ' . $lastSell->price); return false; } else { $reason['avg_price'] = 'Прошлая продажа была ' . ($this->curtime - strtotime($lastSell->dtm)) / 60 . ' мин. назад (допустимы покупки раз в ' . self::min_sell_interval / 60 . ' мин. при отсутствии ощутимого роста цены), цена отличалась от текущей на ' . $diff * 100 . '%, минимальное отличие должно быть ' . $this->sell_imp_dif * 100 . '% '; } } //Перебираем периоды $all_tracks = array(); foreach ($this->sell_periods as $period) { $all_tracks[] = $this->getGraphImage($curtime, $period, 'sell', $this->sell_imp_dif); } //Анализируем треки $tracks = $this->getSellTracks($all_tracks); if (sizeof($tracks) == 0) { Log::notsell('Нет подходящих треков для продажи'); return false; } $reason['tracks'] = $tracks; $reason['all_tracks'] = $all_tracks; // Совершаем вынужденные продажи $this->NecesarySell($all_tracks, $bought); // Ищем выгодные продажи foreach ($bought as $key => $buy) { // Цена продажи $curcost = $buy->count * $this->current_exchange->sell * (1 - self::fee); // Сколько заработаем при продаже (комиссия была уже вычтена в btc при покупке) $income = $curcost - $buy->summ; // Достаточно ли заработаем if ($income / $buy->summ < self::min_income) { if ($income > 0) { Log::notsell('Не продали (№' . $buy->id . '), доход слишком мал ' . $income . ' < ' . self::min_income * $curcost . ' купил за ' . $buy->summ . ' можно продать за ' . $curcost . ' sell=' . $this->current_exchange->sell); } continue; } // Записываем причину покупки $reason['buy'] = 'Найдена подходящая продажа №' . $buy->id . ' с доходом от сделки ' . $income . ' руб., что составляет ' . $income / $buy->summ * 100 . '% от цены покупки'; Log::Add('Начало продажи №' . $buy->id); $this->startSell($buy, $reason); //unset($bought[$key]); break; // не более одной продажи по расчету за раз } }