Files
li 1b24994e74 feat: 后端全量更新 - 含所有本次需求
- 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: 新闻自动采集脚本
2026-03-30 20:16:32 +08:00

1426 lines
56 KiB
PHP
Executable File

<?php
namespace app\api\controller;
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 function GuzzleHttp\Psr7\str;
use app\api\library\exchange\Huobi;
use app\api\library\exchange\Binance;
use think\Queue;
use addons\btpanel\library\Api as Btapi;
/**
* 量化接口
*/
class Strategy extends Api
{
protected $noNeedLogin = ['test'];
protected $noNeedRight = '*';
public function _initialize()
{
parent::_initialize();
$this->btapi = new Btapi();
}
//获取价格币种
public function get_coin()
{
$data = Db::name('app_ai_coin a')
->field('a.*,b.api_url')
->join('app_ai_exchange b','b.id=a.exchange_id','left')
->where('a.status','1')
->order('a.weigh','desc')
->limit(3)
->select();
foreach ($data as $key=>$value)
{
$data[$key]['price'] = sprintf('%.2f',$value['price']);
}
$this->success('success',$data);
}
//获取信誉值数
public function get_xinyus()
{
$strategy = Db::name('app_ai_strategy')
->where('status','1')
->where('user_id',$this->auth->id)
->select();
$cc_amount = 0;
foreach ($strategy as $key=>$value)
{
if($value['cc_price'] <= 0) continue;
$strategy_order = Db::name('app_ai_strategy_order')
->where('strategy_id',$value['id'])
->order('id','desc')->find();
if($strategy_order['type'] == '2') continue;
$sum = Db::name('app_ai_strategy_order')
->where('strategy_id',$value['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('amount');
$cc_amount += $sum;
}
//平均收益比
$income_per = Db::name('app_ai_strategy')
->where('user_id',$this->auth->id)
->where('status','1')
->sum('zy_percent');
if($strategy) {
$xinyu = sprintf('%.4f', $cc_amount * ($income_per / count($strategy)) * Config::get('site.xinyu_percent'));
}else{
$xinyu = 0;
}
$balances = Db::name('app_currency_user')
->where('user_id',$this->auth->id)
->where('curr_id','1')->find();
if($balances)
{
$warning['num'] = sprintf('%.4f', $balances['num_lh']);
}else{
$warning['num'] = sprintf('%.4f',0);
}
if($warning['num'] < $xinyu)
{
$warning['xinyu'] = '1';
}else{
$warning['xinyu'] = '0';
}
$lang = $this->request->request("lang");
switch ($lang) {
case "zh-cn":
$xinyu_waring = Config::get("site.xinyu_waring");
break;
default:
$xinyu_waring = Config::get("site.xinyu_waring_en");
break;
}
$warning['xinyu_waring'] = $xinyu_waring;
$this->success('ok',$warning);
}
//获取所有币种
public function get_exchange()
{
$coin_type = 1;
$strategy = Db::name('app_ai_strategy')
->where('user_id',$this->auth->id)
->select();
$strategy1 = array_column($strategy,'type','coin_id');
$strategy2 = array_column($strategy,'status','coin_id');
$value = [];
$coin = Db::name('app_ai_coin')
->where('status', '1')
->where('exchange_id', 1)
->where('coin_type',$coin_type)
->select();
$youxian = [];
foreach ($coin as $k=>$val){
if(isset($strategy1[$val['id']]))
{
$val['type'] = $strategy1[$val['id']];
$val['status'] = $strategy2[$val['id']];
}else{
$val['type'] = '2';
$val['status'] = '0';
}
$val['image'] = Config::get('site.image_url').$val['image'];
$stretagy_order = Db::name('app_ai_strategy_order')
->where('coin_id',$val['id'])
->where('type','2')
->where('createtime','>',strtotime(date('Y-m-d 00:00:00')))
->count();
$val['strategy_xhcode'] = $stretagy_order;
if($val['symbol'] == 'btcusdt' || $val['symbol'] == 'ethusdt'){
$youxian[] = $val;
unset($coin[$k]);
}else{
$coin[$k] = $val;
}
}
$last_names = array_column($coin,'strategy_xhcode');
array_multisort($last_names,SORT_DESC,$coin);
$coin = array_merge_recursive($youxian,$coin);
$user_usdt = Db::name("app_currency_user")->where("user_id",$this->auth->id)->where("curr_id",1)->value("num_lh");
$value['usdtnum'] = $user_usdt;
$value['coins'] = $coin;
$value['ws_url'] = 'wss://api.hadax.com/ws';
$data[] = $value;
$this->success('success',$data);
}
//搜索币种
public function search_coin()
{
$params = $this->request->post();
if(!isset($params['coin']) || empty($params['coin']))
{
$this->error(__('请输入要搜索的币种'));
}
$coin = strtoupper($params['coin']);
$coins = Db::name('app_ai_coin')
->whereLike('coinname','%'.$coin.'%')
->select();
$this->success('success',$coins);
}
//获取循环策略
public function get_strategy()
{
$params = $this->request->post();
$type = (isset($params['type']) && !empty($params['type']))?$params['type']:'2';
$coin_type = 1;
$exchangeid = 1;
$data = Db::name('app_ai_strategy a')
->field('a.*,b.coinname,b.price,b.image,b.symbol,b.coin_type,b.coin_desc')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('a.user_id', $this->auth->id)
->where('a.type', $type)
->where('b.coin_type',$coin_type)
->where('b.exchange_id',$exchangeid)
->order('a.status', 'desc')
->paginate(50, false, ['query' => request()->param()]);
foreach ($data as $key=>$value)
{
$order_sell = Db::name('app_ai_strategy_order')
->where('strategy_id',$value['id'])
->where('type','2')
->order('id','desc')->find();
if(empty($order_sell))
{
$order_sell['id'] = 1;
}
$strategy_code = Db::name('app_ai_strategy_order')
->where('coin_id',$value['coin_id'])
->where('user_id',$this->auth->id)
->where('createtime','>',strtotime(date('Y-m-d')))
->where('type','2')->count();
$value['strategy_xhcode'] = $strategy_code;
if($value['cc_amount'] <=0 && $value['cc_price'] > 0) {
$value['cc_num'] = sprintf('%.6f' , Db::name('app_ai_strategy_order')
->where('strategy_id',$value['id'])
->where('type','1')
->where('id','>',$order_sell['id'])
->order('id','desc')->sum('amount'));
$value['cc_nums'] = sprintf('%.6f' , Db::name('app_ai_strategy_order')
->where('strategy_id',$value['id'])
->where('type','1')
->where('id','>',$order_sell['id'])
->order('id','desc')->sum('num'));
$value['increase'] = sprintf('%.4f', ($value['price'] - $value['cc_price']) / $value['cc_price']);
}else if($value['cc_amount'] > 0 && $value['cc_price']>0){
$value['cc_nums'] = $value['cc_num'];
$value['cc_num'] = $value['cc_amount'];
$value['increase'] = sprintf('%.4f', ($value['price'] - $value['cc_price']) / $value['cc_price']);
}else{
$value['cc_nums'] = 0;
$value['increase'] = '0.00';
}
//浮亏 最新价格持仓-目前持仓
$newamount = $value['cc_nums'] * $value['price'];
$ccamount = $value['cc_nums'] * $value['cc_price'];
$value['fukui'] = sprintf('%.6f',$newamount-$ccamount);
$value['image'] = Config::get('site.image_url').$value['image'];
$data[$key] = $value;
}
$this->success('success',$data);
}
//获取币种策略
public function get_strategy_coin()
{
$params = $this->request->post();
if(!isset($params['coin_id']) || empty($params['coin_id'])){
$this->error(__('请输入要查询的币种'));
}
$coin = Db::name('app_ai_coin')
->where('id',$params['coin_id'])
->where('status','1')->find();
if(!$coin)
{
$this->error(__('币种不存在'));
}
$stretagy = Db::name('app_ai_strategy')
->where('coin_id',$params['coin_id'])
->where('user_id',$this->auth->id)
->find();
$strategy_code = 0;
$stretagy_order = Db::name('app_ai_strategy_order')
->where('strategy_id',$stretagy['id'])
->order('id','desc')->find();
if(empty($stretagy))
{
$bcjson = Config::get('site.bcjson');
$bcjsons = [];
$stretagy = [
'amount' => 0.000000,
"coin_id" => $coin['id'],
"status" => "0",
"first_num" => Config::get('site.first_num'),
"order_num" => Config::get('site.order_num'),
"zy_percent" => Config::get('site.zy_percent'),
"zy_ht" => Config::get('site.zy_ht'),
"bcjson" => $bcjsons,
"bc_ht" => Config::get('site.bc_ht'),
"cc_price" => "0.000000",
"type" => "1",
"is_double" => Config::get('site.is_double'),
"double_max" => Config::get('site.double_max'),
"coinname" => $coin['coinname'],
"price" => "0.000000",
'coin_price' => $coin['price'],
'bc_time' => 0,
'cc_num' => '0.000000',
'symbol' => $coin['symbol'],
'bcdf' => '0%',
'bcjg' => '0.0000',
'cc_amount' => '0.0000',
'in_price' => '0.000000',
'pc_status' => '0',
'is_now' => '0'
];
if($coin['coin_type'] == '2'){
$bcjson = Config::get('site.fmjson');
}
foreach ($bcjson as $key=>$value)
{
$stretagy['bcs_'.$key] = $value;
}
}else{
$order_sell = Db::name('app_ai_strategy_order')
->where('strategy_id',$stretagy['id'])
->where('type','2')
->order('id','desc')->find();
if(empty($order_sell))
{
$order_sell['id'] = 0;
}else{
$strategy_code = $order_sell['strategy_code'];
}
$order = Db::name('app_ai_strategy_order')
->where('strategy_id',$stretagy['id'])
->where('type','1')
->where('id','>',$order_sell['id'])
->order('bc_time','desc')->find();
if(empty($order)) $order['bc_time'] = 0;
else{
$strategy_code = $order['strategy_code'];
}
$stretagy['cc_num'] = Db::name('app_ai_strategy_order')
->where('strategy_id',$stretagy['id'])
->where('type','1')
->where('id','>',$order_sell['id'])
->order('id','desc')->sum('num');
$stretagy['bc_time'] = $order['bc_time'];
$bcjson = json_decode($stretagy['bcjson'],true);
$bcjsons = [];
foreach ($bcjson as $key=>$value)
{
$stretagy['bcs_'.$key] = $value;
}
$stretagy['bcjson'] = $bcjsons;
$stretagy['coin_price'] = $coin['price'];
$stretagy['symbol'] = $coin['symbol'];
$stretagy['order_num'] = $stretagy['num'];
//已补仓次数
$bctime = $order['bc_time'];
if($bctime >= $stretagy['num']) ; //达到最大补仓次数
$bctimes = (string)($order['bc_time'] + 1);
// var_dump($bctimes,$bcjson,$bcjsons);exit;
if(isset($bcjson[$bctimes])) {
$percent = $bcjson[$bctimes];
$stretagy['bcdf'] = ($percent*100).'%';
$stretagy['bcjg'] = sprintf('%.4f',$stretagy['cc_price'] * (1-$percent));
}else{
$percent = 0;
$stretagy['bcdf'] = '0%';
$stretagy['bcjg'] = '0';
}
}
if($stretagy['cc_amount'] <= 0 && $stretagy['cc_price'] > 0) {
$stretagy['cc_amount'] = Db::name('app_ai_strategy_order')
->where('strategy_id', $stretagy['id'])
->where('type', '1')
->where('id', '>', $order_sell['id'])
->order('id', 'desc')->sum('amount');
$stretagy['cc_amount'] = sprintf('%.4f',$stretagy['cc_amount']);
$allamount = $stretagy['cc_amount'];
$allnum = Db::name('app_ai_strategy_order')
->where('strategy_id', $stretagy['id'])
->where('strategy_code', $stretagy_order['strategy_code'])
->where('type', '1')
->sum('num');
$allfee = Db::name('app_ai_strategy_order')
->where('strategy_id', $stretagy['id'])
->where('strategy_code', $stretagy_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);
$stretagy['cc_price'] = $ccprices;
$stretagy['cc_num'] = $ccnums;
$ret1 = Db::name('app_ai_strategy')
->where('id',$stretagy['id'])->update(['cc_price'=>$ccprices,'cc_num'=>$ccnums,'cc_amount'=>$allamount,'updatetime'=>time()]);
$stretagy['increase'] = (sprintf('%.4f', ($coin['price'] - $stretagy['cc_price']) / $stretagy['cc_price']) * 100) . '%';
}else if($stretagy['cc_amount'] > 0 && $stretagy['cc_price']){
$stretagy['increase'] = (sprintf('%.4f', ($coin['price'] - $stretagy['cc_price']) / $stretagy['cc_price']) * 100) . '%';
}else $stretagy['increase'] = '0.00%';
//查询信誉值
//当前持仓总量U
$strategy = Db::name('app_ai_strategy')
->where('user_id',$this->auth->id)
->where('status','1')
->select();
$cc_amount = $pc_amount = 0;
foreach ($strategy as $key=>$value)
{
if($value['cc_price'] <= 0) continue;
$strategy_order = Db::name('app_ai_strategy_order')
->where('strategy_id',$value['id'])
->order('id','desc')->find();
if($strategy_order['type'] == '2') continue;
$sum = Db::name('app_ai_strategy_order')
->where('strategy_id',$value['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('amount');
$cc_amount += $sum;
}
$stretagy['strategy_xhcode'] = $strategy_code;
//平均收益比
$income_per = Db::name('app_ai_strategy')
->where('user_id',$this->auth->id)
->where('status','1')
->sum('zy_percent');
if($strategy) {
$xinyu = sprintf('%.4f', $cc_amount * ($income_per / count($strategy)) * Config::get('site.xinyu_percent'));
}else{
$xinyu = 0;
}
$balances = Db::name('app_currency_user')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
if($balances)
{
$data['num'] = sprintf('%.4f', $balances['num_lh']);
}else{
$data['num'] = sprintf('%.4f',0);
}
if($data['num'] < $xinyu)
{
$stretagy['xinyu'] = '1';
}else{
$stretagy['xinyu'] = '0';
}
$lang = $this->request->request("lang");
switch ($lang) {
case "zh-cn":
$coin_waring = Config::get("site.coin_waring");
$xinyu_waring = Config::get("site.xinyu_waring");
break;
default:
$coin_waring = Config::get("site.coin_waring_en");
$xinyu_waring = Config::get("site.xinyu_waring_en");
break;
}
$stretagy['xinyu_waring'] = $xinyu_waring;
if($coin['increase'] <0 && abs($coin['increase']) > Config::get('site.increase_waring'))
{
$stretagy['coin_tx'] = '1';
$stretagy['coin_waring'] = $coin_waring.abs($coin['increase']*100)."%";
}else{
$stretagy['coin_tx'] = '0';
$stretagy['coin_waring'] = $coin_waring.(Config::get('site.increase_waring')*100)."%";
}
$stretagy['image'] = Config::get('site.image_url').$coin['image'];
$stretagy['price_precision'] = $coin['price_precision'];
$stretagy['exchange_id'] = $coin['exchange_id'];
if($stretagy['exchange_id'] == 1){
$stretagy['ws_url'] = 'wss://api.hadax.com/ws';
}else if($stretagy['exchange_id'] == 2){
$stretagy['ws_url'] = 'ws://172.247.4.178:8989';
}
$this->success('success',$stretagy);
}
//获取交易记录
public function get_order()
{
$params = $this->request->post();
$type = (isset($params['type']) && !empty($params['type']))?$params['type']:'';
if(!empty($type))
{
$w['a.type'] = $type;
}
$w['b.exchange_id'] = 1;
if(isset($params['symbol']) && !empty($params['symbol']))
{
$w['b.symbol'] = ['LIKE','%'.$params['symbol'].'%'];
}
if(isset($params['starttime']) && !empty($params['starttime']))
{
$params['starttime'] = strtotime($params['starttime'].' 00:00:00');
$w['a.createtime'] = ['>',$params['starttime']];
}
if(isset($params['endtime']) && !empty($params['endtime']))
{
$params['endtime'] = strtotime($params['endtime'].' 00:00:00');
if(isset($params['starttime']) && !empty($params['starttime'])){
$w['a.createtime'] = ['between',$params['starttime'].",".$params['endtime']];
}else{
$w['a.createtime'] = ['<',$params['endtime']];
}
}
$w['a.user_id'] = $this->auth->id;
$data = Db::name('app_ai_strategy_order a')
->field('a.*,b.coinname,b.image')
->join('app_ai_coin b','a.coin_id = b.id','left')
->where($w)
->order('a.id','desc')
->paginate(20,false,['query' => request()->param()]);
foreach ($data as $key=>$value)
{
$value['createtime'] = date('Y-m-d H:i:s',$value['createtime']);
$value['image'] = Config::get("site.image_url").$value['image'];
$data[$key] = $value;
}
$this->success('success',$data);
}
//设置策略
public function set_strategy()
{
$params = $this->request->post();
if(!isset($params['coin_id']) || empty($params['coin_id']))
{
$this->error(__('请选择要设置的币种'));
}
//实名认证判断
if(!controller("Common")->get_auth()){
$this->error(__("请先完成实名认证"),['jump'=>1]);
}
$coinids = explode(',',$params['coin_id']);
$paramss = $params;
foreach ($coinids as $keys => $values) {
$params = $paramss;
$params['coin_id'] = $values;
$coin = Db::name('app_ai_coin')
->where('id', $params['coin_id'])
->where('status', '1')->find();
if (!$coin) {
$this->error(__('币种已下架或不存在'));
}
$strategy = Db::name('app_ai_strategy')
->where('user_id', $this->auth->id)
->where('coin_id', $params['coin_id'])
->find();
if (!isset($params['first_num']) || empty($params['first_num'])) {
if (empty($strategy)) {
$params['first_num'] = Config::get('site.first_num');
} else {
$params['first_num'] = $strategy['first_num'];
}
}
if ($params['first_num'] < Config::get('site.min_buy')) {
$this->error(__('最低买单数量为:') . Config::get('site.min_buy'));
}
if (!isset($params['order_num']) || empty($params['order_num'])) {
if (empty($strategy)) {
$params['order_num'] = Config::get('site.order_num');
} else {
$params['order_num'] = $strategy['num'];
}
} else if ($params['order_num'] > Config::get('site.order_num')) {
$this->error(__('最高做单数量') . Config::get('site.order_num'));
}
$params['double_max'] = $params['order_num'];
if (!isset($params['zy_percent']) || empty($params['zy_percent'])) {
if (empty($strategy)) {
$params['zy_percent'] = Config::get('site.zy_percent');
} else {
$params['zy_percent'] = $strategy['zy_percent'];
}
}
if (!isset($params['zy_ht']) || empty($params['zy_ht'])) {
if (empty($strategy)) {
$params['zy_ht'] = Config::get('site.zy_ht');
} else {
$params['zy_ht'] = $strategy['zy_ht'];
}
}
$params['bcjson'] = [];
foreach ($params as $key => $value) {
if (strpos($key, 'bcs_') !== false) {
$keys = str_replace('bcs_', '', $key);
$params['bcjson'][$keys] = $value;
}
}
if (!isset($params['bcjson']) || empty($params['bcjson'])) {
if (empty($strategy)) {
$params['bcjson'] = Config::get('site.bcjson');
} else {
$params['bcjson'] = json_decode($strategy['bcjson'], true);
}
}
if (!isset($params['bc_ht']) || empty($params['bc_ht'])) {
if (empty($strategy)) {
$params['bc_ht'] = Config::get('site.bc_ht');
} else {
$params['bc_ht'] = $strategy['bc_ht'];
}
}
if (!isset($params['is_double']) || empty($params['is_double'])) {
if (empty($strategy)) {
$params['is_double'] = Config::get('site.is_double');
} else {
$params['is_double'] = $strategy['is_double'];
}
}
if (!isset($params['double_max']) || empty($params['double_max'])) {
if (empty($strategy)) {
$params['double_max'] = Config::get('site.double_max');
} else {
$params['double_max'] = $strategy['double_max'];
}
}
if (!isset($params['type']) || empty($params['type'])) {
if (empty($strategy)) {
$params['type'] = '2';
} else {
$params['type'] = $strategy['type'];
}
}
if (!isset($params['status']) || (empty($params['status']) && $params['status'] != 0)) {
if (empty($strategy)) {
$params['status'] = '0';
} else {
$params['status'] = $strategy['status'];
}
}
if($params['status'] == '1')
{
//查询信誉值
//当前持仓总量U
$strategys = Db::name('app_ai_strategy')
->where('user_id',$this->auth->id)
->where('status','1')
->select();
$cc_amount = $pc_amount = 0;
foreach ($strategys as $key=>$value)
{
if($value['cc_price'] <= 0) continue;
$strategy_order = Db::name('app_ai_strategy_order')
->where('strategy_id',$value['id'])
->order('id','desc')->find();
if($strategy_order['type'] == '2') continue;
$sum = Db::name('app_ai_strategy_order')
->where('strategy_id',$value['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('amount');
$cc_amount += $sum;
}
//平均收益比
$income_per = Db::name('app_ai_strategy')
->where('user_id',$this->auth->id)
->where('status','1')
->sum('zy_percent');
if($strategys) {
$xinyu = sprintf('%.4f', $cc_amount * ($income_per / count($strategy)) * Config::get('site.xinyu_percent'));
}else{
$xinyu = 0;
}
$balances = Db::name('app_currency_user')
->where('user_id',$this->auth->id)
->where('curr_id',1)->find();
if($balances['num_lh'] <= $xinyu)
{
$this->error(__('信誉值不足,请充值'));
}
}
if (!isset($params['pc_status']) || (empty($params['pc_status']) && $params['pc_status'] != 0)) {
if (empty($strategy)) {
$params['pc_status'] = '0';
} else {
$params['pc_status'] = $strategy['pc_status'];
}
}
if (!isset($params['is_now']) || (empty($params['is_now']) && $params['is_now'] != 0)) {
if (empty($strategy)) {
$params['is_now'] = '0';
} else {
$params['is_now'] = $strategy['pc_status'];
$params['is_now'] = $strategy['is_now'];
}
}
if (!isset($params['in_price']) || (empty($params['in_price']) && $params['pc_status'] != 0)) {
if (empty($strategy)) {
$params['in_price'] = '0.000000';
} else {
$params['in_price'] = $strategy['in_price'];
}
}
$update = [
'user_id' => $this->auth->id,
'coin_id' => $coin['id'],
"status" => $params['status'],
"first_num" => $params['first_num'],
"num" => $params['order_num'],
"zy_percent" => $params['zy_percent'],
"zy_ht" => $params['zy_ht'],
"bcjson" => json_encode($params['bcjson']),
"bc_ht" => $params['bc_ht'],
"type" => $params['type'],
"is_double" => $params['is_double'],
"double_max" => $params['double_max'],
'in_price' => $params['in_price'],
'pc_status' => $params['pc_status'],
'is_now' => $params['is_now'],
];
$inserts = false;
if ($strategy) {
$update['updatetime'] = time();
$ret = Db::name('app_ai_strategy')
->where('id', $strategy['id'])
->update($update);
} else {
$update['createtime'] = time();
$ret = Db::name('app_ai_strategy')
->insertGetId($update);
$strategy['id'] = $ret;
$strategy['status'] = $params['status'];
$inserts = true;
}
}
if($ret)
{
$this->success(__('提交成功'));
}else{
$this->error(__('系统繁忙'));
}
}
//获取电子账单
public function get_bill()
{
$params = $this->request->post();
$type = (isset($params['type']) && !empty($params['type']))?$params['type']:'1';
$today = strtotime(date('Y-m-d 00:00:00'));
$w['a.user_id'] = $this->auth->id;
$size = (isset($params['size']))?$params['size']:20;
$exchangeid = 1;
if($type == '1')
{
$data = Db::name('app_ai_strategy_order a')
->field('a.order_sn,a.createtime,a.income,b.coinname,b.image')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('a.type','2')
->where('a.user_id',$this->auth->id)
->where('a.createtime','>',$today)
->where('a.income','>',0)
->where('b.exchange_id',$exchangeid)
->order('a.id', 'desc')
->paginate($size, false, ['query' => request()->param()])->each(function($item){
$item['createtime'] = date('Y-m-d H:i:s',$item['createtime']);
$item['image'] = Config::get('site.image_url').$item['image'];
return $item;
})->toArray();
$data['today_num'] = sprintf('%.6f', Db::name('app_ai_strategy_order a')
->field('a.order_sn,a.createtime,a.income,b.coinname')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('a.type','2')
->where('a.user_id',$this->auth->id)
->where('a.income','>',0)
->where('b.exchange_id',$exchangeid)
->where('a.createtime','>',$today)->sum('income'));
$data['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('a.type','2')
->where('a.user_id',$this->auth->id)
->where('a.income','>',0)
->where('b.exchange_id',$exchangeid)
->order('a.id', 'desc')->sum('income'));
}else {
$jstime = date('Y-m-d');
$jsarr = Db::name('app_ai_user_income')
->where('user_id',$this->auth->id)
->where('exchange_id',$exchangeid)
->select();
$jsarrs = array_column($jsarr,'id','jstime');
$datas = Db::name('app_ai_strategy_order a')
->field('a.income,a.createtime')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('a.type','2')
->where('a.user_id',$this->auth->id)
->where('a.income','>',0)
->where('b.exchange_id',$exchangeid)
->order('a.id', 'asc')
->select();
$insert = [];
$update = [];
$today = strtotime(date('Y-m-d 00:00:00'));
foreach ($datas as $key=>$value)
{
$jjtime = date('Y-m-d',$value['createtime']);
if(!isset($jsarrs[$jjtime]))
{
if(!isset($insert[$jjtime]))
$insert[$jjtime] = $value['income'];
else $insert[$jjtime] += $value['income'];
}else
{
if(!isset($update[$jjtime]))
$update[$jjtime] = $value['income'];
else $update[$jjtime] += $value['income'];
}
}
if(!empty($insert)){
$insertarr = [];
foreach ($insert as $key => $value)
{
$insertarr[] = [
'user_id' => $this->auth->id,
'num' => $value,
'jstime' => $key,
'createtime' => time(),
'exchange_id' => $exchangeid,
];
}
Db::name('app_ai_user_income')->insertAll($insertarr);
}
if(!empty($update))
{
foreach ($update as $key=>$value)
{
Db::name('app_ai_user_income')
->where('user_id',$this->auth->id)
->where('exchange_id',$exchangeid)
->where('jstime',$key)->update(['num'=>$value,'updatetime'=>time()]);
}
}
$data = Db::name('app_ai_user_income a')
->field('a.num as income,a.jstime as createtime')
->where('a.user_id',$this->auth->id)
->where('a.exchange_id',$exchangeid)
->order('a.id', 'desc')
->paginate($size, false, ['query' => request()->param()])->toArray();
$data['today_num'] = sprintf('%.6f',Db::name('app_ai_strategy_order a')
->field('a.order_sn,a.createtime,a.income,b.coinname')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('a.type','2')
->where('a.user_id',$this->auth->id)
->where('a.income','>',0)
->where('b.exchange_id',$exchangeid)
->where('a.createtime','>',$today)->sum('income'));
$data['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('a.type','2')
->where('a.user_id',$this->auth->id)
->where('a.income','>',0)
->where('b.exchange_id',$exchangeid)
->order('a.id', 'desc')->sum('income'));
}
//计算今日数据
//当前持仓总量U
$strategy = Db::name('app_ai_strategy a')
->field('a.*')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('b.exchange_id',$exchangeid)
->where('a.user_id',$this->auth->id)
->select();
$cc_amount = $pc_amount = 0;
foreach ($strategy as $key=>$value)
{
$cc_amount += $value['cc_amount'];
}
$pc_amount = Db::name('app_ai_strategy_order a')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('b.exchange_id',$exchangeid)
->where('a.type','2')
->where('a.user_id',$this->auth->id)
->where('a.createtime','>',$today)->sum('amount');
if($pc_amount <= 0 && $data['today_num'] <= 0)
{
$yk_percent = '0.0000';
}else
$yk_percent = sprintf('%.4f', $data['today_num']/($pc_amount - $data['today_num']) );
//今日平仓总量、今日平均盈亏比例
$data['cc_amount'] = sprintf('%.4f',$cc_amount);
$data['pc_amount'] = sprintf('%.4f',$pc_amount);
$data['yk_percent'] = $yk_percent;
//交易所手续费
$data['exchange_fee'] = sprintf('%.6f',Db::name('app_ai_strategy_order a')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('b.exchange_id',$exchangeid)
->where('a.user_id',$this->auth->id)
->where('a.type','2')->sum('a.fee'));
//信誉值
$data['xinyu_fee'] = sprintf('%.6f',$data['all_num'] * Config::get('site.xinyu_percent'));
//净收益
$data['all_income'] = sprintf('%.6f',$data['all_num'] - $data['exchange_fee'] - $data['xinyu_fee']);
//今日交易所手续费
$data['toexchange_fee'] = sprintf('%.6f',Db::name('app_ai_strategy_order a')
->join('app_ai_coin b', 'a.coin_id = b.id', 'left')
->where('b.exchange_id',$exchangeid)
->where('a.user_id',$this->auth->id)
->where('a.type','2')
->where('a.createtime','>',$today)
->sum('a.fee'));
//今日信誉值
$data['toxinyu_fee'] = sprintf('%.6f',$data['today_num'] * Config::get('site.xinyu_percent'));
//今日净收益
$data['toall_income'] = sprintf('%.6f',$data['today_num'] - $data['toexchange_fee'] - $data['toxinyu_fee']);
$data['balance'] = Db::name("app_currency_user")->where("user_id", $this->auth->id)->where("curr_id",1)->value("num_lh");
$this->success('success',$data);
}
//清仓卖出
public function clean_cang()
{
$params = $this->request->post();
if(!isset($params['coin_id']) || empty($params['coin_id']))
{
$this->error(__('请选择操作币种'));
}
$coinarr = explode(',',$params['coin_id']);
//redis防重复点击
$symbol = "qingcang" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
$msg = '清仓卖出';
$url = "https://api.huobi.pro";
foreach ($coinarr as $key=>$value)
{
$coin = Db::name('app_ai_coin a')
->field('a.*')
->where('a.id',$value)
->find();
if(empty($coin)) continue;
//判断是否是最高点---
$coindata = json_decode(http_curl($url.'/market/trade?symbol='.$coin['symbol']),true);
if (!isset($coindata['status']) || $coindata['status'] != 'ok') {
lopRedis($symbol);
$this->error(__('系统繁忙'));
}
$newprice = $coindata['tick']['data'][0]['price'];
$orderids = $coindata['tick']['data'][0]['trade-id'];
$strategy = Db::name('app_ai_strategy')
->where('user_id',$this->auth->id)
->where('coin_id',$value)
->find();
if(empty($strategy)) continue;
$strategy_order = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->order('id','desc')
->find();
if($strategy_order['type'] == '2') continue;
//总持仓数量
$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;
$amount = sprintf('%.8f',$sumnum*$newprice);
$outamount = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->where('strategy_code',$strategy_order['strategy_code'])
->where('type','1')
->sum('amount');
//理论扣除信誉值
$kouchu = sprintf('%.4f',Config::get('site.xinyu_percent')*$outamount*$strategy['zy_percent']);
$currency = Db::name('app_currency_user')
->where('user_id',$strategy['user_id'])
->where('curr_id',1)->find();
$diffnum = sprintf('%.4f',$currency['num_lh'] - $kouchu);
if($diffnum < 0)
{
$msg .= '策略币种:'.$coin['coinname'].'平仓失败,信誉值不足:余额-'.$currency['num_lh'].',需扣除信誉值:
'.$kouchu;
continue;
}
$income = sprintf('%.6f',$amount - $outamount);
$order = [
'user_id' => $strategy['user_id'],
'coin_id' => $coin['id'],
'strategy_id' => $strategy['id'],
'type' => '2',
'order_sn' => $orderids,
'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,
];
Db::startTrans();
try {
if($income > 0)
{
//扣除信誉值
$kouchu = sprintf('%.4f',Config::get('site.xinyu_percent')*$income);
$diffnum = sprintf('%.4f',$currency['num_lh'] - $kouchu);
if($diffnum < 0)
{
$diffnum = 0;
$kouchu = $currency['num_lh'];
}
$user_usdt = Db::name("app_currency_user")->where("user_id", $this->auth->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
];
Db::name('app_currency_user')->where('id',$user_usdt['id'])->update(['num_lh'=>$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::name('app_currency_user')->where('id',$currency['id'])->update(['num_lh'=>$diffnum]);
Db::name('app_detailed_lh')->insertAll($detailed);
//上级反信誉值
// $users = Db::name('user')->where('id',$strategy['user_id'])->find();
// $usersarr = array_filter(array_reverse( explode('|',$users['team_text'])));
// $lastper = 0;
// foreach ($usersarr as $ks => $vals)
// {
// if(!is_numeric($vals) || empty($vals)) continue;
// if( $vals == 1) continue; //$vals == $strategy['user_id'] ||
// $usera = Db::name('user')->where('id',$vals)->find();
// if($usera['share_percent'] <= 0) continue;
// $currencys = Db::name('app_currency_user')
// ->where('user_id',$usera['id'])
// ->where('curr_id','1')->find();
// $percents = $usera['share_percent'] - $lastper;
// if($percents <= 0) continue;
// $addnum = sprintf('%.4f',$kouchu * $percents);
// $diffnums = sprintf('%.4f',$currencys['num'] + $addnum);
//
// $detailed = [
// 'user_id' => $usera['id'],
// 'curr_id' => '7',
// 'price' => $addnum,
// 'cart' => '1',
// 'type' => '3',
// 'description' => '获取信誉值',
// 'createtime' => time(),
// 'before_num' => $currencys['num'],
// 'after_num' => $diffnums
// ];
// if($usera['share_percent'] > 0) $lastper = $usera['share_percent'];
// Db::name('app_detailed_lh')
// ->insert($detailed);
// $ret = Db::name('app_currency_user')
// ->where('user_id',$usera['id'])
// ->where('curr_id','1')->update(['num'=>$diffnums,'updatetime'=>time()]);
//
// }
}
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' && $strategy['status'] == '1'){ //单次循环暂停
$ret = Db::name('app_ai_strategy')
->where('id',$strategy['id'])
->update(['status'=>'0','updatetime'=>time()]);
}
Db::commit();
$this->success(__('已清仓,请查看交易记录详情').$msg);
} catch (Exception $e) {
Db::rollback();
lopRedis($symbol);
$this->error(__("清仓失败"));
}
}
$this->error($msg);
}
//手动加仓
public function add_cang()
{
//实名认证判断
if(!controller("Common")->get_auth()){
$this->error(__("请先完成实名认证"),['jump'=>1]);
}
$params = $this->request->post();
if(!isset($params['coin_id']) || empty($params['coin_id']))
{
$this->error(__('请选择操作币种'));
}
if(!isset($params['num']) || empty($params['num']) || !is_numeric($params['num']))
{
$this->error(__('请输入补仓数量'));
}
if($params['num'] < Config::get('site.min_buy'))
{
$this->error(__('最低买单数量为:').Config::get('site.min_buy'));
}
$coin = Db::name('app_ai_coin a')
->field('a.*')
->where('a.id',$params['coin_id'])
->find();
if(empty($coin))
{
$this->error(__('交易币种不存在'));
}
$strategy = Db::name('app_ai_strategy')
->where('user_id',$this->auth->id)
->where('coin_id',$coin['id'])
->find();
if($strategy['status'] != '1'){
$this->error(__('请开启策略'));
}
//redis防重复点击
$symbol = "jiacang" . $this->auth->id;
$submited = pushRedis($symbol);
if (!$submited) {
$this->error(__("操作频繁"));
}
$strategy_order = Db::name('app_ai_strategy_order')
->where('strategy_id',$strategy['id'])
->order('id','desc')
->find();
//判断是否是最高点---
$url = "https://api.huobi.pro";
$coindata = json_decode(http_curl($url.'/market/trade?symbol='.$coin['symbol']),true);
if (!isset($coindata['status']) || $coindata['status'] != 'ok') {
lopRedis($symbol);
$this->error(__('系统繁忙'));
}
$newprice = $coindata['tick']['data'][0]['price'];
$orderids = $coindata['tick']['data'][0]['trade-id'];
$dou = pow(10,$coin['precision']);
$user_usdt = Db::name("app_currency_user")->where("user_id",$this->auth->id)->where("curr_id",1)->find();
if($user_usdt['num_lh'] < $params['num']){
$this->error(__("余额不足"));
}
$num = sprintf('%.6f', $params['num'] / $newprice);
$order = [
'user_id' => $this->auth->id,
'coin_id' => $coin['id'],
'strategy_id' => $strategy['id'],
'type' => '1',
'order_sn' => $orderids,
'num' => $num,
'amount' => $params['num'],
'price' => $newprice,
'fee' => sprintf('%.4f', $num * 0.002),
'bc_time' => 0,
'createtime' => time(),
];
$detailed[] = [
'user_id' => $this->auth->id,
'curr_id' => '1',
'price' => $params['num'],
'cart' => '2',
'type' => '2',
'description' => '量化补仓',
'createtime' => time(),
'before_num' => $user_usdt['num_lh'],
'after_num' => $user_usdt['num_lh']-$params['num']
];
if(empty($strategy_order)) $order['strategy_code'] = 1;
else if($strategy_order['type'] == '2'){
$order['strategy_code'] = $strategy_order['strategy_code'] + 1;
}else{
$order['strategy_code'] = $strategy_order['strategy_code'];
}
Db::startTrans();
try {
//添加记录
Db::name('app_currency_user')->where('id',$user_usdt['id'])->update(['num_lh'=>$user_usdt['num_lh']-$params['num']]);
Db::name("app_detailed_lh")->insertAll($detailed);
if($strategy_order['type'] == '2'){
//需要扣除手续费后 根据精度算出真实持仓数量
$ccnums = intval(($order['num']- $order['fee'])*pow(10,8))/pow(10,8);
$ccprices = intval($order['amount']/$ccnums*pow(10,8))/pow(10,8);
$allamount = $order['amount'];
}else {
//更新持仓均价
$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');
$allamount += $params['num'];
$allnum += $order['num'];
$allfee += $order['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()]);
Db::name('app_ai_strategy_order')->insert($order);
lopRedis($symbol);
Db::commit();
$this->success(__('加仓成功'));
} catch (Exception $e) {
lopRedis($symbol);
Db::rollback();
$this->error(__('系统繁忙'));
}
}
//获取默认设置
public function get_strategy_ori()
{
$bcjson = Config::get('site.bcjson');
$bcjsons = [];
$stretagy = [
"first_num" => Config::get('site.first_num'),
"order_num" => Config::get('site.order_num'),
"zy_percent" => Config::get('site.zy_percent'),
"zy_ht" => Config::get('site.zy_ht'),
"bcjson" => $bcjsons,
"bc_ht" => Config::get('site.bc_ht'),
"is_double" => Config::get('site.is_double'),
"double_max" => Config::get('site.double_max'),
];
foreach ($bcjson as $key=>$value)
{
$stretagy['bcs_'.$key] = $value;
}
$this->success('success',$stretagy);
}
public function test()
{
$shouquan = Db::name('app_ai_shouquan a')
->field('a.*,b.api_url')
->join('app_ai_exchange b','a.exchange_id = b.id','left')
->where('a.user_id',37)->find();;
$apis = new Huobi($shouquan['api_key'], $shouquan['secret_key'], $shouquan['api_url']);
$times = (time() - 28800)*1000;
$startime = getMillisecond() - 36000*1000;
$endtime = getMillisecond();
$result = $apis->search_order('arpausdt','sell-market',$startime,$endtime);
echo "<pre>";
var_dump($result);
}
//获取通用策略限制
public function get_strategy_setting()
{
$params = $this->request->post();
if(isset($params['exchange_id'])) $exchangeid = $params['exchange_id'];
else $exchangeid = 1;
if($exchangeid == 1) {
$data = [
'bc_min_limit' => $this->auth->bc_min_limit
];
}else if($exchangeid == 2){
$data = [
'bc_min_limit' => $this->auth->bc_min_limit_ba
];
}else{
$data = [
'bc_min_limit' => 0.000000
];
}
$this->success('ok',$data);
}
//设置补仓余额最低限制,低于不进行补仓
public function setbc_limit()
{
$params = $this->request->post();
if(!isset($params['bc_min_limit']) || empty($params['bc_min_limit']) || !is_numeric($params['bc_min_limit']))
{
$this->error(__('请输入设置的补仓最低余额限制'));
}
if(isset($params['exchange_id'])) $exchangeid = $params['exchange_id'];
else $exchangeid = 1;
if($exchangeid == 1) {
$ret = Db::name('user')
->where('id',$this->auth->id)
->update(['bc_min_limit' => $params['bc_min_limit'],'updatetime'=>time()]);
}else if($exchangeid == 2){
$ret = Db::name('user')
->where('id',$this->auth->id)
->update(['bc_min_limit_ba' => $params['bc_min_limit'],'updatetime'=>time()]);
}else{
$ret = false;
}
if($ret){
$this->success(__('提交成功'));
}else{
$this->error(__('系统繁忙'));
}
}
//获取排行榜
public function get_paihang()
{
$params = $this->request->post();
$today = strtotime(date('Y-m-d'));
if(isset($params['exchange_id'])) $exchangeid = $params['exchange_id'];
else $exchangeid = 1;
if($params['type'] == 1) //日收益
{
$data = Db::name('app_ai_user_income a')
->field('a.num as income,a.jstime,b.nickname,b.avatar,a.pcnum,a.income_per')
->join('user b','b.id=a.user_id','left')
->where('a.jstime',date('Y-m-d'))
->where('a.exchange_id',$exchangeid)
->order('a.num','desc')->limit(10)->select();
foreach ($data as $key => $value)
{
$value['avatar'] = Config::get('site.image_url').$value['avatar'];
$data[$key] = $value;
}
}else if($params['type'] == 2) //总收益
{
$data = Db::name('app_ai_user_income_all a')
->field('a.income,b.nickname,b.avatar,a.pcnum,a.income_per')
->where('a.income','>',0)
->join('user b','b.id=a.user_id','left')
->where('a.exchange_id',$exchangeid)
->order('a.income','desc')->limit(10)->select();
foreach ($data as $key => $value)
{
$value['avatar'] = Config::get('site.image_url').$value['avatar'];
$data[$key] = $value;
}
}else{ //币种
$today = strtotime( date('Y-m-d'));
$data = Db::name('app_ai_strategy_order a')
->field('count(a.id) as num,b.coinname,b.id as coin_id,b.image,c.image as exchange_image')
->join('app_ai_coin b','b.id=a.coin_id','left')
->join('app_ai_exchange c','c.id=b.exchange_id','left')
->where('a.type',2)
->where('a.createtime','>',$today)
->where('b.exchange_id',$exchangeid)
->group('a.coin_id')
->limit('50')
->order('num','desc')
->select();
foreach ($data as $key=>$value)
{
$value['image'] = Config::get('site.image_url').$value['image'];
$value['exchange_image'] = Config::get('site.image_url').$value['exchange_image'];
$strategy_order = Db::name('app_ai_strategy_order')
->where('coin_id',$value['coin_id'])
->where('type','2')
->where('createtime','>',$today)
->order('id','desc')->find();
$value['last_time'] = date('H:i:s',$strategy_order['createtime']);
$data[$key] = $value;
}
}
$this->success('ok',$data);
}
}