317 lines
10 KiB
PHP
317 lines
10 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\AccountLog;
|
|
use App\TransactionComplete;
|
|
use App\Transaction;
|
|
use App\UserChat;
|
|
use App\TransactionIn;
|
|
use App\TransactionOut;
|
|
use App\Users;
|
|
use App\UsersWallet;
|
|
use Faker\Factory;
|
|
use Illuminate\Console\Command;
|
|
use App\Robot as RobotModel;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
defined('ACCOUNT_ID') or define('ACCOUNT_ID', '50154012'); // 你的账户ID
|
|
defined('ACCESS_KEY') or define('ACCESS_KEY', 'c96392eb-b7c57373-f646c2ef-25a14'); // 你的ACCESS_KEY
|
|
defined('SECRET_KEY') or define('SECRET_KEY', ''); // 你的SECRET_KEY
|
|
|
|
class Robot extends Command
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'robot {id} {--mode=}';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = '匹配交易自动挂单机器人';
|
|
|
|
/**
|
|
* Create a new command instance.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
}
|
|
|
|
/**
|
|
* Execute the console command.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function handle()
|
|
{
|
|
$this->info('--------------------------------------------------');
|
|
$this->info('开始执行机器人:' . now()->toDateTimeString());
|
|
|
|
$id = $this->argument('id');
|
|
|
|
while (true) {
|
|
$robotList = RobotModel::where('id','>',0)->get();
|
|
foreach($robotList as $robot){
|
|
if ($robot->status == RobotModel::STOP) {
|
|
$this->info('机器人已关闭');
|
|
break;
|
|
}
|
|
|
|
$this->info('当前交易对是:' . $robot->currency_info . '/' . $robot->legal_info);
|
|
$this->info('当前数量区间:' . $robot->number_min . '-' . $robot->number_max);
|
|
|
|
try {
|
|
if ($robot->sell == RobotModel::OPEN) {
|
|
$this->info('开始卖出');
|
|
$this->sell($robot, $robot->number_max, $robot->number_min);
|
|
}
|
|
if ($robot->buy == RobotModel::OPEN) {
|
|
$this->info('开始买入');
|
|
$this->buy($robot, $robot->number_max, $robot->number_min);
|
|
}
|
|
} catch (\Exception $e) {
|
|
$this->info($e->getMessage());
|
|
}
|
|
$complete = TransactionComplete::orderBy('id', 'desc')
|
|
->where("currency", $robot->currency_id)
|
|
->where("legal", $robot->legal_id)
|
|
->take(20)
|
|
->get();
|
|
|
|
$send = array(
|
|
"type" => "deal_list",
|
|
"currency_id" => $robot->currency_id,
|
|
"legal_id" => $robot->legal_id,
|
|
"complete" => $complete,
|
|
);
|
|
echo '开始发送';
|
|
UserChat::sendChat($send);
|
|
}
|
|
$robot = RobotModel::find($id);
|
|
|
|
// if (!$robot) {
|
|
// $this->info('找不到此机器人');
|
|
// break;
|
|
// }
|
|
|
|
|
|
sleep($robot->second);
|
|
}
|
|
|
|
$this->info('机器人执行结束:' . now()->toDateTimeString());
|
|
$this->info('--------------------------------------------------');
|
|
}
|
|
|
|
protected function sell($robot, $number_max, $number_min)
|
|
{
|
|
//随机数量
|
|
$num = $this->getNumber($number_min, $number_max);
|
|
$total_number = $num;
|
|
|
|
//随机价格
|
|
$price = $this->getPrice(strtolower($robot->currency_info . $robot->legal_info), $robot->float_number_down, $robot->float_number_up);
|
|
|
|
$user = Users::find($robot->sell_user_id);
|
|
|
|
$in = TransactionIn::where("price", ">=", $price)
|
|
->where("currency", $robot->currency_id)
|
|
->where("legal", $robot->legal_id)
|
|
->where("number", ">", "0")
|
|
->orderBy('price', 'desc')
|
|
->get();
|
|
|
|
$user_currency = UsersWallet::where("user_id", $robot->sell_user_id)
|
|
->where("currency", $robot->currency_id)
|
|
->first();
|
|
|
|
$has_num = 0;
|
|
if (!empty($in)) {
|
|
foreach ($in as $i) {
|
|
if ($has_num >= $num) break;
|
|
|
|
$shengyu_num = $num - $has_num;
|
|
$this_num = $i->number > $shengyu_num ? $this_num = $shengyu_num : $this_num = $i->number;
|
|
$has_num = $has_num + $this_num;
|
|
|
|
if ($this_num > 0) {
|
|
TransactionOut::transaction($i, $this_num, $user, $user_currency, $robot->legal_id, $robot->currency_id);
|
|
}
|
|
}
|
|
// Transaction::newDealList($robot->legal_id, $robot->currency_id);
|
|
}
|
|
|
|
$num = $num;//$num - $has_num;
|
|
if ($num > 0) {
|
|
$out = new TransactionOut();
|
|
$out->user_id = $robot->sell_user_id;
|
|
$out->price = $price;
|
|
$out->number = $num;
|
|
$out->total_number = $total_number;
|
|
$out->currency = $robot->currency_id;
|
|
$out->legal = $robot->legal_id;
|
|
$out->create_time = time();
|
|
|
|
$out->save();
|
|
|
|
// $user_currency->change_balance = $user_currency->change_balance - $num;
|
|
// $user_currency->lock_change_balance = $user_currency->lock_change_balance + $num;
|
|
// $user_currency->save();
|
|
|
|
AccountLog::insertLog([
|
|
'user_id' => $robot->sell_user_id,
|
|
'value' => -$num,
|
|
'info' => "提交卖出记录扣除",
|
|
'type' => AccountLog::TRANSACTIONOUT_SUBMIT_REDUCE
|
|
]);
|
|
}
|
|
|
|
Transaction::pushNews($robot->currency_id, $robot->legal_id);
|
|
}
|
|
|
|
protected function buy($robot, $number_max, $number_min)
|
|
{
|
|
//随机数量
|
|
$num = $this->getNumber($number_min, $number_max);
|
|
$total_number = $num;
|
|
|
|
//随机价格
|
|
$price = $this->getPrice(strtolower($robot->currency_info.$robot->legal_info), $robot->float_number_down, $robot->float_number_up);
|
|
|
|
$user = Users::find($robot->buy_user_id);
|
|
|
|
$has_num = 0;
|
|
|
|
$user_legal = UsersWallet::where("user_id", $robot->buy_user_id)->where("currency", $robot->legal_id)->first();
|
|
|
|
$out = TransactionOut::where("price", "<=", $price)
|
|
->where("number", ">", "0")
|
|
->where("currency", $robot->currency_id)
|
|
->where("legal", $robot->legal_id)
|
|
->orderBy('price', 'asc')
|
|
->get();
|
|
|
|
if (!empty($out)) {
|
|
|
|
foreach ($out as $o) {
|
|
if ($has_num < $num) {
|
|
$shengyu_num = $num - $has_num;
|
|
$this_num = 0;
|
|
if ($o->number > $shengyu_num) {
|
|
$this_num = $shengyu_num;
|
|
} else {
|
|
$this_num = $o->number;
|
|
}
|
|
$has_num = $has_num + $this_num;
|
|
|
|
if ($this_num > 0) {
|
|
// echo 333;
|
|
TransactionIn::transaction($o, $this_num, $user, $robot->legal_id, $robot->currency_id);
|
|
}
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
// Transaction::newDealList($robot->legal_id, $robot->currency_id);
|
|
}else{
|
|
echo 'empty out';
|
|
}
|
|
|
|
$num = $num ;//- $has_num;
|
|
|
|
if ($num > 0) {
|
|
$in = new TransactionIn();
|
|
$in->user_id = $robot->buy_user_id;
|
|
$in->price = $price;
|
|
$in->number = $num;
|
|
$in->currency = $robot->currency_id;
|
|
$in->legal = $robot->legal_id;
|
|
$in->total_number = $total_number;
|
|
$in->create_time = time();
|
|
|
|
$in->save();
|
|
|
|
$all_balance = $price * $num;
|
|
// $user_legal->legal_balance = $user_legal->legal_balance - $all_balance;
|
|
// $user_legal->lock_legal_balance = $user_legal->lock_legal_balance + $all_balance;
|
|
// $user_legal->save();
|
|
|
|
AccountLog::insertLog([
|
|
'user_id' => $robot->buy_user_id,
|
|
'value' => -$all_balance,
|
|
'info' => "提交卖入记录扣除",
|
|
'type' => AccountLog::TRANSACTIONIN_SUBMIT_REDUCE
|
|
]);
|
|
}
|
|
// Transaction::pushNews($robot->currency_id, $robot->legal_id);
|
|
|
|
|
|
}
|
|
|
|
|
|
/**获取火币行情价格
|
|
*
|
|
* @param $symbol
|
|
* @param $float_number_down
|
|
* @param $float_number_up
|
|
*
|
|
* @return float
|
|
*/
|
|
public function getPrice($symbol, $float_number_down, $float_number_up)
|
|
{
|
|
$url = 'https://api.huobi.br.com/market/trade?symbol=' . $symbol;
|
|
$info = $this->curl($url);
|
|
$price = $info['tick']['data'][0]['price'];
|
|
|
|
$faker = Factory::create();
|
|
$price = $faker->randomFloat(2, $price - $float_number_down, $price + $float_number_up);
|
|
unset($faker);
|
|
return $price;
|
|
}
|
|
|
|
/**获取买入卖出随机数
|
|
*
|
|
* @param $number_min
|
|
* @param $number_max
|
|
*
|
|
* @return float
|
|
*/
|
|
public function getNumber($number_min, $number_max)
|
|
{
|
|
$faker = Factory::create();
|
|
$num = $faker->randomFloat(2, $number_min, $number_max);
|
|
unset($faker);
|
|
return $num;
|
|
}
|
|
|
|
public function curl($url, $type = 'GET', $postdata = [])
|
|
{
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
if ($type == 'POST') {
|
|
curl_setopt($ch, CURLOPT_POST, 1);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postdata));
|
|
}
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
curl_setopt($ch, CURLOPT_HEADER, 0);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
"Content-Type: application/json",
|
|
]);
|
|
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
|
|
$output = curl_exec($ch);
|
|
$info = curl_getinfo($ch);
|
|
curl_close($ch);
|
|
return @json_decode($output, true);
|
|
}
|
|
}
|