- Contract.php: 返回合约账户余额(balance_contract) - My.php: 地址管理增加BTC/ETH - AppContract.php: 一键平仓(closeall) - AppProxy.php: 代理专属注册链接 + 分级权限(L1/L2) - site.php: 手续费减半(0.018→0.009) - agent_permission_setup.sql: 代理权限SQL - crypto_news_crawler.py: 新闻自动采集脚本
924 lines
41 KiB
PHP
Executable File
924 lines
41 KiB
PHP
Executable File
<?php
|
|
|
|
namespace app\api\controller;
|
|
|
|
use app\api\library\exchange\Binance;
|
|
use app\common\controller\Api;
|
|
use app\common\library\Ems;
|
|
use app\common\library\Sms;
|
|
use fast\Random;
|
|
use think\Validate;
|
|
use think\Config;
|
|
use think\Db;
|
|
use app\api\library\exchange\Huobi;
|
|
use function fast\e;
|
|
|
|
/**
|
|
* 量化任务接口
|
|
*/
|
|
class Tasklh extends Api
|
|
{
|
|
|
|
// 无需登录的接口,*表示全部
|
|
protected $noNeedLogin = ['*'];
|
|
// 无需鉴权的接口,*表示全部
|
|
protected $noNeedRight = ['*'];
|
|
|
|
public function update_coin(){
|
|
$t = time();
|
|
$coin = Db::name('app_rate a')
|
|
->where("bb_type",1)
|
|
->field('a.*')
|
|
->select();
|
|
$rate = 6.45;
|
|
echo "update---";
|
|
$url = 'https://api.huobi.pro/market/tickers';
|
|
$data = json_decode(http_curl($url),true);
|
|
|
|
$data_forex = json_decode(http_curl("http://f-test.js-stock.top/getkine?symbol=XAUUSD&cmd=quote&key=jssj2023keykey123"), true);
|
|
|
|
if($data['status'] != "ok"){
|
|
echo "获取失败";exit;
|
|
}
|
|
foreach ($coin as $key=>$value)
|
|
{
|
|
foreach ($data['data'] as $k=>$v)
|
|
{
|
|
if($value['symbol'] == $v['symbol']){
|
|
$update = [
|
|
'open' => $v['open'],
|
|
'close' => $v['close'],
|
|
'high' => $v['high'],
|
|
'low' => $v['low']
|
|
];
|
|
$update['increase'] = sprintf('%.4f',($update['close']-$update['open'])/$update['open']);
|
|
$update['updatetime'] = time();
|
|
$update['price'] = $update['close'];
|
|
|
|
//获取交易经度 ai用
|
|
// $url1 = 'https://api.huobi.pro/v1/common/symbols';
|
|
// $data1 = json_decode(http_curl($url1),true);
|
|
// if(isset($data1['status']) && $data1['status'] == 'ok')
|
|
// {
|
|
// $datarr = array_column($data1['data'], 'amount-precision','symbol');
|
|
// }
|
|
// $update['precision'] = $datarr[$value['symbol']];
|
|
|
|
Db::name('app_ai_coin')->where('id',$value['id'])->update($update);
|
|
//修改rate
|
|
$tradedata = $v;
|
|
$updatearr = [
|
|
'amount' => $tradedata['amount'],
|
|
'open' => $tradedata['open'],
|
|
'close' => $tradedata['close'],
|
|
'high' => $tradedata['high'],
|
|
'low' => $tradedata['low'],
|
|
'usdt' => $tradedata['close'],
|
|
'rmb' => $tradedata['close']*$rate,
|
|
'updatetime' => time()
|
|
];
|
|
$updatearr['increase'] = sprintf("%.4f",
|
|
($updatearr['close']-$updatearr['open'])/$updatearr['open']);
|
|
Db::name('app_rate')->where('symbol',$value['symbol'])->update($updatearr);
|
|
//修改curr
|
|
Db::name("app_currency")->where("suffix",$value['symbol'])->update(['exchange'=>$updatearr['close']]);
|
|
echo $value['symbol'].'---';
|
|
}
|
|
}
|
|
|
|
if($value['symbol'] == "xauusd"){
|
|
$update = [
|
|
'open' => floatval($data_forex['open']),
|
|
'close' => floatval($data_forex['close']),
|
|
'high' => floatval($data_forex['high']),
|
|
'low' => floatval($data_forex['low']),
|
|
];
|
|
$update['increase'] = sprintf('%.4f',($update['close']-$update['open'])/$update['open']);
|
|
$update['updatetime'] = time();
|
|
$update['price'] = $update['close'];
|
|
|
|
Db::name('app_ai_coin')->where('id',$value['id'])->update($update);
|
|
//修改rate
|
|
$tradedata = $data_forex;
|
|
$updatearr = [
|
|
'amount' => floatval($tradedata['bid']),
|
|
'open' => floatval($tradedata['open']),
|
|
'close' => floatval($tradedata['close']),
|
|
'high' => floatval($tradedata['high']),
|
|
'low' => floatval($tradedata['low']),
|
|
'usdt' => floatval($tradedata['close']),
|
|
'rmb' => floatval($tradedata['close'])*$rate,
|
|
'updatetime' => time()
|
|
];
|
|
$updatearr['increase'] = sprintf("%.4f",
|
|
($updatearr['close']-$updatearr['open'])/$updatearr['open']);
|
|
Db::name('app_rate')->where('symbol',$value['symbol'])->update($updatearr);
|
|
//修改curr
|
|
Db::name("app_currency")->where("suffix",$value['symbol'])->update(['exchange'=>$updatearr['close']]);
|
|
echo $value['symbol'].'---';
|
|
}
|
|
}
|
|
echo "执行时长:".(time()-$t)."秒";
|
|
}
|
|
|
|
//同步火币价格
|
|
// public function update_coin()
|
|
// {
|
|
// $t = time();
|
|
// $coin = Db::name('app_ai_coin a')
|
|
// ->field('a.*')
|
|
// ->where('a.status','1')
|
|
// ->select();
|
|
// $rate = 6.45;
|
|
// echo "update---";
|
|
// foreach ($coin as $key=>$value)
|
|
// {
|
|
// $url1 = 'https://api.huobi.pro/v1/common/symbols';
|
|
// $data1 = json_decode(http_curl($url1),true);
|
|
// if(isset($data1['status']) && $data1['status'] == 'ok')
|
|
// {
|
|
// $datarr = array_column($data1['data'], 'amount-precision','symbol');
|
|
// }
|
|
|
|
// $url = 'https://api.huobi.pro/market/history/kline?period=1day&size=1&symbol='.$value['symbol'];
|
|
// $data = json_decode(http_curl($url),true);
|
|
// if(isset($data['status']) && $data['status'] == 'ok')
|
|
// {
|
|
// $update = [
|
|
// 'open' => $data['data'][0]['open'],
|
|
// 'close' => $data['data'][0]['close'],
|
|
// 'high' => $data['data'][0]['high'],
|
|
// 'low' => $data['data'][0]['low']
|
|
// ];
|
|
// $update['increase'] = sprintf('%.4f',($update['close']-$update['open'])/$update['open']);
|
|
// $update['updatetime'] = time();
|
|
// $update['price'] = $update['close'];
|
|
// $update['precision'] = $datarr[$value['symbol']];
|
|
// Db::name('app_ai_coin')->where('id',$value['id'])->update($update);
|
|
// //修改rate
|
|
// $tradedata = $data['data'][0];
|
|
// $updatearr = [
|
|
// 'amount' => $tradedata['amount'],
|
|
// 'open' => $tradedata['open'],
|
|
// 'close' => $tradedata['close'],
|
|
// 'high' => $tradedata['high'],
|
|
// 'low' => $tradedata['low'],
|
|
// 'usdt' => $tradedata['close'],
|
|
// 'rmb' => $tradedata['close']*$rate,
|
|
// 'updatetime' => time()
|
|
// ];
|
|
// $updatearr['increase'] = sprintf("%.4f",
|
|
// ($updatearr['close']-$updatearr['open'])/$updatearr['close']);
|
|
// Db::name('app_rate')->where('symbol',$value['symbol'])->update($updatearr);
|
|
// //修改curr
|
|
// Db::name("app_currency")->where("suffix",$value['symbol'])->update(['exchange'=>$updatearr['close']]);
|
|
// echo $value['symbol'].'---';
|
|
// }
|
|
// }
|
|
// echo "执行时长:".(time()-$t)."秒";
|
|
|
|
// }
|
|
|
|
//开启策略
|
|
public function open_strategy()
|
|
{
|
|
$strategyid = $this->request->get('strategy_id');
|
|
if(!$strategyid)
|
|
{
|
|
echo "error id";exit;
|
|
}
|
|
|
|
$redis = getRedis();
|
|
$running = $redis->get('strategyo-'.$strategyid);
|
|
if($running) {
|
|
echo "运行未完成";exit;
|
|
}
|
|
$redis->set('strategyo-'.$strategyid, time(), 60);
|
|
|
|
//查询任务
|
|
$tasks = Db::name('app_ai_task')
|
|
->where('strategy_id',$strategyid)->find();
|
|
if(empty($tasks)) echo '任务未创建';
|
|
|
|
$msg = '策略-'.$strategyid.'||';
|
|
$strategy = Db::name('app_ai_strategy')
|
|
->where('id',$strategyid)
|
|
->where('status','1')->find();
|
|
if(empty($strategy))
|
|
{
|
|
$msg .= '未查询到策略'.$strategyid;
|
|
$result = del_bt_cron($strategyid);
|
|
if(isset($result['status']) && $result['status'] === true)
|
|
{
|
|
$msg .= '策略-'.$strategyid.'暂停成功---';
|
|
}else{
|
|
$msg .= '策略-'.$strategyid.'暂停失败---';
|
|
}
|
|
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
|
|
}
|
|
|
|
$coin = Db::name('app_ai_coin a')
|
|
->field('a.*')
|
|
->where('a.id',$strategy['coin_id'])
|
|
->find();
|
|
$strategy_order = Db::name('app_ai_strategy_order')
|
|
->where('strategy_id',$strategy['id'])
|
|
->order('id','desc')
|
|
->find();
|
|
//获取分钟K线
|
|
$url = 'https://api.huobi.pro/market/history/kline?period=1min&size=10&symbol='.$coin['symbol'];
|
|
$data = json_decode(http_curl($url),true);
|
|
$prices = [];
|
|
$nowtime1 = strtotime(date('Y-m-d H:i:00'));
|
|
if(isset($data['status']) && $data['status'] == 'ok') {
|
|
foreach ($data['data'] as $k => $val) {
|
|
if($val['id'] >= $nowtime1) continue; // 当前分钟线不算
|
|
$prices[] = [
|
|
'coin_id' => $coin['id'],
|
|
'coinname' => $coin['symbol'],
|
|
'get_id' => $val['id'],
|
|
'open' => $val['open'],
|
|
'close' => $val['close'],
|
|
'high' => $val['high'],
|
|
'low' => $val['low'],
|
|
'increase' => sprintf('%.4f', ($val['close'] - $val['open']) / $val['open']),
|
|
'createtime' => time(),
|
|
];
|
|
}
|
|
$last_names = array_column($prices,'get_id');
|
|
array_multisort($last_names,SORT_DESC,$prices);
|
|
}else{
|
|
$msg .= '火币接口异常0'.var_dump($data);
|
|
$redis->set('strategyo-' . $strategy['id'], false);
|
|
echo $msg;
|
|
exit;
|
|
}
|
|
|
|
$coindata = json_decode(http_curl('https://api.huobi.pro/market/trade?symbol='.$coin['symbol']),true);
|
|
if(!isset($coindata['status']) || $coindata['status'] != 'ok')
|
|
{
|
|
$msg .= '火币接口异常'.var_dump($data);
|
|
$redis->set('strategyo-'.$strategy['id'], false);echo $msg;exit;
|
|
}
|
|
$newprice = $coindata['tick']['data'][0]['price'];
|
|
$orderid = $coindata['tick']['data'][0]['trade-id'];
|
|
|
|
$nowtimes = time();
|
|
$lasttime = $prices[0]['get_id'];
|
|
$difftimes = $nowtimes - $lasttime;
|
|
echo '最新价格时间:'.date("Y-m-d H:i:s",$lasttime).'--';
|
|
if($difftimes > 120)
|
|
{
|
|
$msg .= '价格未同步,'.$coin['coinname'].':时间差'.$difftimes;
|
|
$redis->set('strategyo-'.$strategy['id'], false);echo $msg;exit;
|
|
}
|
|
$comein = false;
|
|
$msg .= 'a';
|
|
$nowuser = Db::name('user')->where('id',$strategy['user_id'])->find();
|
|
|
|
//判断是不是首单
|
|
if(empty($strategy_order) || $strategy_order['type'] == '2')
|
|
{
|
|
$msg .= 'b';
|
|
//根据往期判断入场时机
|
|
//最高点附近不入、连续下跌不入、连续上涨不入
|
|
$fall = 0;
|
|
$rise = 0;
|
|
foreach ($prices as $k => $val)
|
|
{
|
|
if($val['increase'] < 0) $fall += 1;
|
|
else $rise += 1;
|
|
if(($fall - $rise >=2) && $rise > 0 && $rise<2)
|
|
{
|
|
$comein = true;
|
|
break;
|
|
}
|
|
//连续涨或连续跌
|
|
if($rise >=2 || ($fall >= 2 && $rise < 1)) break;
|
|
if($k == 0 && $fall >=1) break; //第一根是跌的情况
|
|
}
|
|
|
|
if($strategy['is_now'] == '1'){
|
|
$comein = true;
|
|
}
|
|
|
|
if(!$comein){
|
|
$msg .= '未达入场条件--'.date("Y-m-d H:i:s");
|
|
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
|
|
}
|
|
|
|
if($strategy['in_price'] > 0 && $newprice > $strategy['in_price'])
|
|
{
|
|
$msg .= '未达设置的入场价格:now-'.$newprice.'-set-'.$strategy['in_price'].'--'.date("Y-m-d H:i:s");
|
|
$redis->set('strategyo-'.$strategy['id'], false);echo $msg;exit;
|
|
}
|
|
|
|
$num = sprintf('%.6f',$strategy['first_num']/$newprice);
|
|
$dou = pow(10,$coin['precision']);
|
|
//发起交易所接口---- 判断信誉值够不够!!!!!!!!
|
|
|
|
$user_usdt = Db::name("app_currency_user")->where("user_id",$strategy['user_id'])->where("curr_id",1)->find();
|
|
if($user_usdt['num_lh'] < $strategy['first_num']){
|
|
$msg .= '余额不足,当前余额'.$user_usdt['num_lh'].'--'.date("Y-m-d H:i:s");
|
|
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
|
|
}
|
|
$detailed = [
|
|
'user_id' => $strategy['user_id'],
|
|
'curr_id' => '1',
|
|
'price' => $strategy['first_num'],
|
|
'cart' => '2',
|
|
'type' => '2',
|
|
'description' => '量化入场',
|
|
'createtime' => time(),
|
|
'before_num' => $user_usdt['num_lh'],
|
|
'after_num' => $user_usdt['num_lh']-$strategy['first_num']
|
|
];
|
|
Db::name('app_currency_user')->where('id',$user_usdt['id'])->update(['num_lh'=>$user_usdt['num_lh']-$strategy['first_num']]);
|
|
Db::name("app_detailed_lh")->insert($detailed);
|
|
$order = [
|
|
'user_id' => $strategy['user_id'],
|
|
'coin_id' => $coin['id'],
|
|
'strategy_id' => $strategy['id'],
|
|
'type' => '1',
|
|
'order_sn' => $orderid,
|
|
'num' => $num,
|
|
'amount' => $strategy['first_num'],
|
|
'price' => $newprice,
|
|
'fee' => sprintf('%.8f', $num * 0.002),
|
|
'bc_time' => 0,
|
|
'createtime' => time(),
|
|
];
|
|
|
|
if(empty($strategy_order)) $order['strategy_code'] = 1;
|
|
else $order['strategy_code'] = $strategy_order['strategy_code'] + 1;
|
|
//需要扣除手续费后 根据精度算出真实持仓数量
|
|
$ccnums = intval(($order['num']- $order['fee'])*pow(10,8))/pow(10,8);
|
|
$ccprices = intval($order['amount']/$ccnums*pow(10,8))/pow(10,8);
|
|
Db::name('app_ai_strategy_order')->insert($order);
|
|
Db::name('app_ai_strategy')
|
|
->where('id',$strategy['id'])->update(['cc_price'=>$ccprices,'cc_num'=>$ccnums,
|
|
'cc_amount'=>$order['amount'],'updatetime'=>time()]);
|
|
$msg .= '策略:'.$strategy['id'].'开始量化---'.date("Y-m-d H:i:s");
|
|
}else if($strategy_order['type'] == '1')
|
|
{
|
|
$msg .= 'c';
|
|
//判断补仓还是卖出
|
|
// $newprice = 52405.84;
|
|
if($newprice > $strategy_order['price']) { //涨 平仓
|
|
//判断是否达平仓条件
|
|
//止盈比例
|
|
$percent = $strategy['zy_percent'];
|
|
if($strategy['cc_price'] > 0) {
|
|
$nowpercent = sprintf("%.4f", ($newprice - $strategy['cc_price']) / $strategy['cc_price']);
|
|
}else{
|
|
$nowpercent = 0;
|
|
}
|
|
//判断是否是最高点---
|
|
//达止盈条件,含回调
|
|
|
|
//盈利最大化,防止持续上涨,盈利不足
|
|
$comein0 = false;
|
|
$fall = $rise = 0;
|
|
foreach ($prices as $k => $val)
|
|
{
|
|
if($val['increase'] < 0) $fall += 1;
|
|
else $rise += 1;
|
|
//连续涨或连续跌
|
|
if($rise >= $fall) break;
|
|
if($k == 0 && $rise >=1) break; //第一根是涨的情况
|
|
//回调是否取当前这分钟K线跌幅0.3%???
|
|
if($k == 0 && $val['increase'] < 0 && abs($val['increase']) >= $strategy['zy_ht'])
|
|
{
|
|
$comein0 = true;
|
|
break;
|
|
}else if($fall >=2){
|
|
$comein0 = true;
|
|
break;
|
|
}
|
|
|
|
}
|
|
if($nowpercent >= $percent && $comein0)
|
|
{
|
|
$comein = true;
|
|
}
|
|
echo '条件:1-'.$nowpercent.'|2-'.$percent.'|3-'.$prices[0]['increase'].'|4-'.$prices[0]['get_id'];
|
|
if($comein) { //达到止盈条件,平仓
|
|
//总持仓数量
|
|
$sumnum = Db::name('app_ai_strategy_order')
|
|
->where('strategy_id',$strategy['id'])
|
|
->where('strategy_code',$strategy_order['strategy_code'])
|
|
->where('type','1')
|
|
->sum('num');
|
|
|
|
//发起交易所接口----
|
|
$num = $sumnum;
|
|
|
|
$outamount = Db::name('app_ai_strategy_order')
|
|
->where('strategy_id',$strategy['id'])
|
|
->where('strategy_code',$strategy_order['strategy_code'])
|
|
->where('type','1')
|
|
->sum('amount');
|
|
//总手续费
|
|
$sumfee = Db::name('app_ai_strategy_order')
|
|
->where('strategy_id',$strategy['id'])
|
|
->where('strategy_code',$strategy_order['strategy_code'])
|
|
->where('type','1')
|
|
->sum('fee');
|
|
|
|
$dou = pow(10,$coin['precision']);
|
|
$newnum = intval(($num-$sumfee)*$dou)/$dou;
|
|
$newnum1 = intval($num*$dou)/$dou;
|
|
$amount = sprintf('%.6f',$newnum*$newprice);
|
|
|
|
$income = sprintf('%.6f',$amount - $outamount);
|
|
if($income < 0 ) {
|
|
$msg .= '-策略:' . $strategy['id'] . '平仓失败,实际交易价格不足-' . $newprice . ',盈亏:
|
|
' . $income . '交易数量-'.$newnum.'--' . date("Y-m-d H:i:s");
|
|
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
|
|
}
|
|
|
|
//扣除信誉值
|
|
$kouchu = sprintf('%.4f',Config::get('site.xinyu_percent')*$income);
|
|
$currency = Db::name('app_currency_user')
|
|
->where('user_id',$strategy['user_id'])
|
|
->where('curr_id','2')->find();
|
|
$diffnum = sprintf('%.4f',$currency['num_lh'] - $kouchu);
|
|
if($diffnum < 0)
|
|
{
|
|
$msg .= '-策略:'.$strategy['id'].'平仓失败,信誉值不足:余额-'.$currency['num'].',需扣除信誉值:
|
|
'.$kouchu.'---'.date("Y-m-d H:i:s");
|
|
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
|
|
}
|
|
|
|
$order = [
|
|
'user_id' => $strategy['user_id'],
|
|
'coin_id' => $coin['id'],
|
|
'strategy_id' => $strategy['id'],
|
|
'type' => '2',
|
|
'order_sn' => $orderid,
|
|
'num' => $num,
|
|
'amount' => $amount,
|
|
'price' => $newprice,
|
|
'fee' => sprintf('%.4f', $amount * 0.0012),
|
|
'bc_time' => 0,
|
|
'createtime' => time(),
|
|
'strategy_code' => $strategy_order['strategy_code'],
|
|
'income' => $income,
|
|
];
|
|
$user_usdt = Db::name("app_currency_user")->where("user_id", $strategy['user_id'])->where("curr_id",1)->find();
|
|
$detailed[] = [
|
|
'user_id' => $strategy['user_id'],
|
|
'curr_id' => '1',
|
|
'price' => $amount,
|
|
'cart' => '1',
|
|
'type' => '2',
|
|
'description' => '量化卖出',
|
|
'createtime' => time(),
|
|
'before_num' => $user_usdt['num_lh'],
|
|
'after_num' => $user_usdt['num_lh']+$amount
|
|
];
|
|
$detailed[] = [
|
|
'user_id' => $strategy['user_id'],
|
|
'curr_id' => '2',
|
|
'price' => $kouchu,
|
|
'cart' => '2',
|
|
'type' => '2',
|
|
'description' => '扣取信誉值',
|
|
'createtime' => time(),
|
|
'before_num' => $currency['num_lh'],
|
|
'after_num' => $diffnum
|
|
];
|
|
|
|
Db::startTrans();
|
|
try {
|
|
//收支操作
|
|
Db::name('app_currency_user')->where('id',$user_usdt['id'])->update(['num_lh'=>$user_usdt['num_lh']+$amount]);
|
|
Db::name('app_currency_user')->where('id',$currency['id'])->update(['num_lh'=>$diffnum]);
|
|
Db::name('app_ai_strategy_order')->insert($order);
|
|
|
|
Db::name('app_ai_strategy')
|
|
->where('id',$strategy['id'])->update(['cc_price'=>0,'cc_num'=>0,'cc_amount'=>0,'updatetime'=>time()]);
|
|
if($strategy['type'] == '1'){ //单次循环暂停
|
|
Db::name('app_ai_strategy')
|
|
->where('id',$strategy['id'])
|
|
->update(['status'=>'0','updatetime'=>time()]);
|
|
}
|
|
|
|
//上级反信誉值
|
|
$users = Db::name('user')->where('id',$strategy['user_id'])->find();
|
|
if($users['lh_act'] == 1){
|
|
$usersarr = array_filter(array_reverse( explode('|',$users['path'])));
|
|
$level = 0;
|
|
$ai_push_profit = Config::get("site.ai_push_profit");//直推
|
|
$level_arr = Db::name("app_ai_grade")->field("id,name,level,team_prize")->where("team_prize",">",0)->select();
|
|
$team_prize = 0;
|
|
|
|
foreach ($usersarr as $ks => $vals)
|
|
{
|
|
if(!is_numeric($vals) || empty($vals)) continue;
|
|
if($vals == 1) continue;
|
|
if($vals == $users['id']) continue;
|
|
|
|
$usera = Db::name('user')->where('id',$vals)->find();
|
|
$currencys = Db::name('app_currency_user')
|
|
->where('user_id',$usera['id'])
|
|
->where('curr_id','2')->find();
|
|
//先算直推
|
|
if($ks == 2){
|
|
$push_price = sprintf("%.6f",$kouchu*$ai_push_profit);
|
|
$detailed[] = array(
|
|
'user_id' => $usera['id'],
|
|
'curr_id' => '2',
|
|
'price' => $push_price,
|
|
'cart' => '1',
|
|
'type' => '3',
|
|
'description' => '直推获取信誉值',
|
|
'createtime' => time(),
|
|
'before_num' => $currencys['num_lh'],
|
|
'after_num' => $currencys['num_lh']+$push_price,
|
|
);
|
|
Db::name("app_currency_user")->where("id",$currencys['id'])->update(['num_lh'=>$currencys['num_lh']+$push_price]);
|
|
continue;
|
|
}
|
|
if($usera['level_id'] == 1 || $usera['level_id']<=$level){
|
|
continue;
|
|
}
|
|
// 团队将
|
|
foreach ($level_arr as $kk => $vv) {
|
|
if($vv['id'] == $usera['level_id']){
|
|
$team_price = sprintf("%.6f",$kouchu*($vv['team_prize']-$team_prize)/100);
|
|
$detailed[] = array(
|
|
'user_id' => $usera['id'],
|
|
'curr_id' => '2',
|
|
'price' => $team_price,
|
|
'cart' => '1',
|
|
'type' => '4',
|
|
'description' => '团队获取信誉值',
|
|
'createtime' => time(),
|
|
'before_num' => $currencys['num_lh'],
|
|
'after_num' => $currencys['num_lh']+$team_price,
|
|
);
|
|
Db::name("app_currency_user")->where("id",$currencys['id'])->update(['num_lh'=>$currencys['num_lh']+$team_price]);
|
|
$level = $usera['level_id'];
|
|
$team_prize = $vv['team_prize'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Db::name('app_detailed_lh')->insertAll($detailed);
|
|
//真实发起交易----
|
|
Db::commit();
|
|
$msg .= '已平仓,盈利'.$income.'---'.date("Y-m-d H:i:s");
|
|
} catch (Exception $e) {
|
|
Db::rollback();
|
|
$msg .= '数据库操作失误2';
|
|
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
|
|
}
|
|
}else{
|
|
$msg .= '未达平仓条件---'.date("Y-m-d H:i:s");
|
|
}
|
|
}else{
|
|
$msg .= 'd';
|
|
$bcjson = json_decode($strategy['bcjson'],true);
|
|
//是否停止补仓
|
|
if($strategy['pc_status'] == '1')
|
|
{
|
|
$msg .= '已设置停止补仓---'.date("Y-m-d H:i:s");
|
|
$redis->set('strategyo-'.$strategy['id'], false);echo $msg;exit;
|
|
}
|
|
//判断是不是达到补仓条件
|
|
//已补仓次数
|
|
$newpc = Db::name('app_ai_strategy_order')
|
|
->where('strategy_id', $strategy['id'])
|
|
->where('strategy_code', $strategy_order['strategy_code'])
|
|
->order('bc_time', 'desc')
|
|
->find();
|
|
$bctime = $newpc['bc_time'];
|
|
if ($bctime >= $strategy['num']) //达到最大补仓次数
|
|
{
|
|
$msg .= '已达最大补仓次数---'.date("Y-m-d H:i:s");
|
|
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
|
|
}
|
|
$bctimes = (string)($bctime + 1);
|
|
$percent = $bcjson[$bctimes];
|
|
if($strategy['cc_price'] > 0) {
|
|
$nowpercent = sprintf("%.4f", abs($newprice - $strategy['cc_price']) / $strategy['cc_price']);
|
|
}else{
|
|
$nowpercent = 0;
|
|
}
|
|
//达补仓条件,并且最新有回调
|
|
if ($nowpercent >= $percent && $prices[0]['increase'] > 0 && $prices[0]['increase'] > $strategy['bc_ht']) {
|
|
$comein = true;
|
|
}
|
|
if($comein) { //达到补仓条件
|
|
//是否倍投
|
|
if ($strategy['is_double'])
|
|
$amount = $strategy_order['amount'] * 2;
|
|
else $amount = $strategy_order['amount'];
|
|
|
|
//发起交易所接口----
|
|
|
|
$num = sprintf('%.6f', $amount / $newprice);
|
|
$dou = pow(10,$coin['precision']);
|
|
|
|
$user_usdt = Db::name("app_currency_user")->where("user_id",$strategy['user_id'])->where("curr_id",1)->find();
|
|
if($user_usdt['num_lh'] < $amount){
|
|
$msg .= '余额不足,当前余额'.$user_usdt['num_lh'].'--'.date("Y-m-d H:i:s");
|
|
$redis->set('strategyo-'.$strategyid,"");echo $msg;exit;
|
|
}
|
|
$detailed = [
|
|
'user_id' => $strategy['user_id'],
|
|
'curr_id' => '1',
|
|
'price' => $amount,
|
|
'cart' => '2',
|
|
'type' => '2',
|
|
'description' => '量化补仓',
|
|
'createtime' => time(),
|
|
'before_num' => $user_usdt['num_lh'],
|
|
'after_num' => $user_usdt['num_lh']-$amount
|
|
];
|
|
Db::name('app_currency_user')->where('id',$user_usdt['id'])->update(['num_lh'=>$user_usdt['num_lh']-$amount]);
|
|
Db::name("app_detailed_lh")->insert($detailed);
|
|
$order = [
|
|
'user_id' => $strategy['user_id'],
|
|
'coin_id' => $coin['id'],
|
|
'strategy_id' => $strategy['id'],
|
|
'type' => '1',
|
|
'order_sn' => $orderid,
|
|
'num' => $num,
|
|
'amount' => $amount,
|
|
'price' => $newprice,
|
|
'fee' => sprintf('%.8f', $num * 0.002),
|
|
'bc_time' => $bctimes,
|
|
'createtime' => time(),
|
|
'strategy_code' => $strategy_order['strategy_code'],
|
|
];
|
|
|
|
Db::name('app_ai_strategy_order')->insert($order);
|
|
//更新持仓均价
|
|
$allamount = Db::name('app_ai_strategy_order')
|
|
->where('strategy_id',$strategy['id'])
|
|
->where('strategy_code',$strategy_order['strategy_code'])
|
|
->where('type','1')
|
|
->sum('amount');
|
|
$allnum = Db::name('app_ai_strategy_order')
|
|
->where('strategy_id',$strategy['id'])
|
|
->where('strategy_code',$strategy_order['strategy_code'])
|
|
->where('type','1')
|
|
->sum('num');
|
|
$allfee = Db::name('app_ai_strategy_order')
|
|
->where('strategy_id',$strategy['id'])
|
|
->where('strategy_code',$strategy_order['strategy_code'])
|
|
->where('type','1')
|
|
->sum('fee');
|
|
$ccnums = intval(($allnum - $allfee)*pow(10,8))/pow(10,8);
|
|
$ccprices = intval($allamount/$ccnums*pow(10,8))/pow(10,8);
|
|
Db::name('app_ai_strategy')
|
|
->where('id',$strategy['id'])->update(['cc_price'=>$ccprices,'cc_num'=>$ccnums,
|
|
'cc_amount'=>$allamount,'updatetime'=>time()]);
|
|
$msg .= '策略:'.$strategy['id'].'已补仓'.$bctimes.'次---'.date("Y-m-d H:i:s");
|
|
}else{
|
|
$msg .= '策略:'.$strategy['id'].',未达补仓条件,补仓次数'.$bctimes.',持仓均价:'.$strategy['cc_price'].
|
|
',最新价格'.$newprice.',亏损比例'.$nowpercent.',达补仓比例'.$percent.'回调比例:'.$strategy['bc_ht'].
|
|
'目前涨幅比例:'.$prices[0]['increase'].'---'.date("Y-m-d H:i:s");
|
|
}
|
|
}
|
|
|
|
}
|
|
$redis->set('strategyo-'.$strategyid,"");
|
|
echo $msg.date("Y-m-d H:i:s");exit;
|
|
}
|
|
|
|
//定时启动策略
|
|
public function start_cron()
|
|
{
|
|
echo '监听策略状态|-|';
|
|
$strategy = Db::name('app_ai_strategy a')
|
|
->field('a.*,b.id as task_id')
|
|
->join('app_ai_task b','a.id=b.strategy_id','left')
|
|
->where('b.id',null)
|
|
->where('a.status','1')
|
|
->limit(300)
|
|
->select();
|
|
foreach ($strategy as $key=>$value)
|
|
{
|
|
$task = Db::name('app_ai_task')
|
|
->where('strategy_id',$value['id'])->find();
|
|
if($value['status'] == '1' && empty($task))
|
|
{
|
|
$result = create_bt_cron($value['id']);
|
|
if(isset($result['status']) && $result['status'] === true)
|
|
{
|
|
echo '策略-'.$value['id'].'启动成功---';
|
|
}else{
|
|
echo '策略-'.$value['id'].'启动失败---';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//定时关闭策略
|
|
public function close_cron()
|
|
{
|
|
echo '监听策略状态|-|';
|
|
$strategy = Db::name('app_ai_strategy')
|
|
->where('status','0')
|
|
->select();
|
|
foreach ($strategy as $key=>$value)
|
|
{
|
|
$task = Db::name('app_ai_task')
|
|
->where('strategy_id',$value['id'])->find();
|
|
if($value['status'] == '0' && !empty($task))
|
|
{
|
|
$result = del_bt_cron($value['id']);
|
|
if(isset($result['status']) && $result['status'] === true)
|
|
{
|
|
echo '策略-'.$value['id'].'暂停成功---';
|
|
}else{
|
|
echo '策略-'.$value['id'].'暂停失败---';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//计算用户累计收益
|
|
public function js_allincome()
|
|
{
|
|
$today = time() - 120;
|
|
$user = Db::name('user a')
|
|
->field('a.id,b.updatetime')
|
|
->join('app_ai_user_income_all b','a.id=b.user_id','left')
|
|
->where('b.updatetime','<',$today)
|
|
->whereOr('b.updatetime',null)
|
|
->limit(5)
|
|
->order('b.updatetime','asc')
|
|
->select();
|
|
echo 'update-';
|
|
foreach ($user as $key=>$value)
|
|
{
|
|
$valss['id'] = 1;
|
|
$jstime = date('Y-m-d');
|
|
$jsarr = Db::name('app_ai_user_income')
|
|
->where('user_id',$value['id'])
|
|
->where('exchange_id',$valss['id'])
|
|
->select();
|
|
$jsarrs = array_column($jsarr,'id','jstime');
|
|
|
|
$datas = Db::name('app_ai_strategy_order a')
|
|
->field('a.income,a.createtime,a.amount')
|
|
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
|
|
->where('b.exchange_id',$valss['id'])
|
|
->where('a.type','2')
|
|
->where('a.user_id',$value['id'])
|
|
->where('a.income','>',0)
|
|
->order('a.id', 'asc')
|
|
->select();
|
|
|
|
$insert = [];
|
|
$update = [];
|
|
$today = strtotime(date('Y-m-d 00:00:00'));
|
|
foreach ($datas as $keys=>$values)
|
|
{
|
|
$jjtime = date('Y-m-d',$values['createtime']);
|
|
if(!isset($jsarrs[$jjtime]))
|
|
{
|
|
if(!isset($insert[$jjtime])) {
|
|
$insert[$jjtime]['income'] = $values['income'];
|
|
$insert[$jjtime]['pcnum'] = $values['amount'];
|
|
}else {
|
|
$insert[$jjtime]['income'] += $values['income'];
|
|
$insert[$jjtime]['pcnum'] += $values['amount'];
|
|
}
|
|
}else
|
|
{
|
|
if(!isset($update[$jjtime])) {
|
|
$update[$jjtime]['income'] = $values['income'];
|
|
$update[$jjtime]['pcnum'] = $values['amount'];
|
|
}
|
|
else {
|
|
$update[$jjtime]['income'] += $values['income'];
|
|
$update[$jjtime]['pcnum'] += $values['amount'];
|
|
}
|
|
}
|
|
}
|
|
|
|
if(!empty($insert)){
|
|
$insertarr = [];
|
|
foreach ($insert as $k => $val)
|
|
{
|
|
$insertarr[] = [
|
|
'user_id' => $value['id'],
|
|
'num' => $val['income'],
|
|
'jstime' => $k,
|
|
'createtime' => time(),
|
|
'pcnum' => $val['pcnum'],
|
|
'income_per' => sprintf('%.4f',$val['income']/($val['pcnum'] - $val['income'])),
|
|
'exchange_id' => $valss['id'],
|
|
];
|
|
}
|
|
Db::name('app_ai_user_income')->insertAll($insertarr);
|
|
}
|
|
|
|
if(!empty($update))
|
|
{
|
|
foreach ($update as $k=>$val)
|
|
{
|
|
Db::name('app_ai_user_income')
|
|
->where('user_id',$value['id'])
|
|
->where('exchange_id',$valss['id'])
|
|
->where('jstime',$k)->update(['num'=>$val['income'],
|
|
'pcnum' => $val['pcnum'],
|
|
'income_per' => sprintf('%.4f',$val['income']/($val['pcnum'] - $val['income'])),
|
|
'updatetime'=>time()]);
|
|
}
|
|
}
|
|
|
|
$all_num = sprintf('%.6f', Db::name('app_ai_strategy_order a')
|
|
->field('a.income,a.createtime')
|
|
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
|
|
->where('b.exchange_id',$valss['id'])
|
|
->where('a.type','2')
|
|
->where('a.user_id',$value['id'])
|
|
->where('a.income','>',0)
|
|
->order('a.id', 'desc')->sum('amount'));
|
|
$all_income = sprintf('%.6f', Db::name('app_ai_strategy_order a')
|
|
->field('a.income,a.createtime')
|
|
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
|
|
->where('b.exchange_id',$valss['id'])
|
|
->where('a.type','2')
|
|
->where('a.user_id',$value['id'])
|
|
->where('a.income','>',0)
|
|
->order('a.id', 'desc')->sum('income'));
|
|
$all_fee = sprintf('%.6f', Db::name('app_ai_strategy_order a')
|
|
->field('a.income,a.createtime')
|
|
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
|
|
->where('b.exchange_id',$valss['id'])
|
|
->where('a.type','2')
|
|
->where('a.user_id',$value['id'])
|
|
->where('a.income','>',0)
|
|
->order('a.id', 'desc')->sum('fee'));
|
|
if($all_num>0)
|
|
$income_per = sprintf('%.4f',$all_income/($all_num-$all_income));
|
|
else $income_per = 0;
|
|
$allnums = [
|
|
'user_id' => $value['id'],
|
|
'income' => $all_income,
|
|
'fee' => $all_fee,
|
|
'income_per' => $income_per,
|
|
'createtime' => time(),
|
|
'pcnum' => $all_num,
|
|
'exchange_id' => $valss['id']
|
|
];
|
|
$incomeall = Db::name('app_ai_user_income_all')
|
|
->where('user_id', $value['id'])
|
|
->where('exchange_id',$valss['id'])
|
|
->find();
|
|
if($incomeall)
|
|
{
|
|
unset($allnums['createtime']);
|
|
$allnums['updatetime'] = time();
|
|
Db::name('app_ai_user_income_all')
|
|
->where('id',$incomeall['id'])->update($allnums);
|
|
}else{
|
|
Db::name('app_ai_user_income_all')->insert($allnums);
|
|
}
|
|
echo '-'.$value['id'].'-';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 量化等级计算
|
|
*/
|
|
public function lh_level_upd()
|
|
{
|
|
$t = time();
|
|
$user = Db::name("user a")->field("a.id,b.level,a.path,a.lh_act")
|
|
->join("app_ai_grade b","a.grade_id=b.id","left")
|
|
->order("a.updatetime asc")
|
|
->limit(50)
|
|
->select();
|
|
if(empty($user)){
|
|
echo "empty";exit;
|
|
}
|
|
foreach ($user as $key => $value) {
|
|
$user_update = array(
|
|
"updatetime" => time(),
|
|
);
|
|
//下一个等级
|
|
$next_level = Db::name("app_ai_grade")->where("level",">",$value['level'])->order("level asc")->find();
|
|
if(!empty($next_level) && $value['lh_act'] == 1){
|
|
//达标升级
|
|
$team_num = Db::name("user")->field("id")->where("path","like",$value['path']."%")->where("id","neq",$value['id'])->where("lh_act",1)->count();
|
|
|
|
if($team_num >= $next_level['team_num']){
|
|
$user_update['grade_id'] = $next_level['id'];
|
|
}
|
|
}
|
|
Db::name("user")->where("id",$value['id'])->update($user_update);
|
|
}
|
|
echo "执行时长:".(time()-$t);
|
|
}
|
|
|
|
|
|
}
|