feat: 项目基础框架+配置+Kernel
This commit is contained in:
@@ -0,0 +1,699 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use App\Jobs\FollowOrderHandel;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Jobs\LeverClose;
|
||||
use App\Jobs\LeverPushTrade;
|
||||
use App\Jobs\LeverHandle;
|
||||
|
||||
|
||||
class LeverTransaction extends Model
|
||||
{
|
||||
const BUY = 1; //买入
|
||||
const SELL = 2; //卖出
|
||||
|
||||
const ENTRUST = 0; //挂单中
|
||||
const TRANSACTION = 1; //交易中
|
||||
const CLOSING = 2; //平仓中
|
||||
const CLOSED = 3; //已平仓
|
||||
const CANCEL = 4; //已撤单
|
||||
|
||||
protected $table = 'lever_transaction';
|
||||
public $timestamps = false;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
protected $appends = [
|
||||
'time',
|
||||
'symbol',
|
||||
'profits',
|
||||
'status_name',
|
||||
'type_name',
|
||||
'show_lever_id',//显示订单id
|
||||
];
|
||||
|
||||
protected static $statusList = [
|
||||
'挂单中',
|
||||
'交易中',
|
||||
'平仓中',
|
||||
'已平仓',
|
||||
'已撤单',
|
||||
];
|
||||
|
||||
protected static $typeList = [
|
||||
'',
|
||||
'买入',
|
||||
'卖出',
|
||||
];
|
||||
|
||||
public static function enumStatus()
|
||||
{
|
||||
return self::$statusList;
|
||||
}
|
||||
|
||||
//伪订单号
|
||||
public function getShowLeverIdAttribute()
|
||||
{
|
||||
|
||||
$id = $this->attributes['id'] ?? 0;
|
||||
$uid = $id + 10000;
|
||||
return $uid;
|
||||
}
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\Users', 'user_id', 'id')->withDefault();
|
||||
}
|
||||
|
||||
public function getMobileAttribute()
|
||||
{
|
||||
$user = $this->user()->getResults();
|
||||
return $user->phone ?? '';
|
||||
}
|
||||
|
||||
public function getAccountNumberAttribute()
|
||||
{
|
||||
$user = $this->user()->getResults();
|
||||
return $user->account_number ?? '';
|
||||
}
|
||||
|
||||
public function getStatusNameAttribute()
|
||||
{
|
||||
$status = $this->attributes['status'] ?? 0;
|
||||
return self::$statusList[$status];
|
||||
}
|
||||
|
||||
public function getTypeNameAttribute()
|
||||
{
|
||||
$type = $this->attributes['type'] ?? 0;
|
||||
return self::$typeList[$type];
|
||||
}
|
||||
|
||||
public function getTimeAttribute()
|
||||
{
|
||||
return date('Y-m-d H:i:s', $this->attributes['create_time'] ?? 0);
|
||||
}
|
||||
|
||||
public function getHandleTimeAttribute()
|
||||
{
|
||||
$handle_time = intval($this->attributes['handle_time']);
|
||||
return $handle_time != 0 ? date('Y-m-d H:i:s', $handle_time) : '';
|
||||
}
|
||||
|
||||
public function getTransactionTimeAttribute()
|
||||
{
|
||||
$transaction_time = intval($this->attributes['transaction_time']);
|
||||
return $transaction_time != 0 ? date('Y-m-d H:i:s', $transaction_time) : '';
|
||||
}
|
||||
|
||||
public function getCompleteTimeAttribute()
|
||||
{
|
||||
$complete_time = intval($this->attributes['complete_time']);
|
||||
return $complete_time != 0 ? date('Y-m-d H:i:s', $complete_time) : '';
|
||||
}
|
||||
|
||||
public function getSymbolAttribute()
|
||||
{
|
||||
$currency_id = $this->getAttribute('currency');
|
||||
$legal_id = $this->getAttribute('legal');
|
||||
$currency_match = CurrencyMatch::where('currency_id', $currency_id)
|
||||
->where('legal_id', $legal_id)
|
||||
->first();
|
||||
return $currency_match ? $currency_match->symbol : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 取每单盈利
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getProfitsAttribute()
|
||||
{
|
||||
$profits = 0;
|
||||
$type = $this->getAttribute('type');
|
||||
$number = $this->getAttribute('number');
|
||||
$status = $this->getAttribute('status');
|
||||
if ($status == self::ENTRUST || $status == self::CANCEL) {
|
||||
return 0.00;
|
||||
}
|
||||
//$multiple = $this->getAttribute('multiple');
|
||||
//$multiple_number = bc_mul($number, $multiple);
|
||||
$update_price = $this->getAttribute('update_price');
|
||||
$price = $this->getAttribute('price');
|
||||
$diff = $type == self::BUY ? bc_sub($update_price, $price) : bc_sub($price, $update_price);
|
||||
$profits = bc_mul($diff, $number);
|
||||
return $profits;
|
||||
}
|
||||
|
||||
public static function leverMultiple($key = 0,$currency_id)
|
||||
{
|
||||
$data["muit"] = LeverMultiple::where("type","=",1)->where("currency_id",$currency_id)->select("value")->get()->toArray();
|
||||
$data["share"] = LeverMultiple::where("type","=",2)->where("currency_id",$currency_id)->select("value")->get()->toArray();
|
||||
// var_dump($data);die;
|
||||
// $data = array(
|
||||
// "5" => "5倍",
|
||||
// "10" => "10倍",
|
||||
// "20" => "20倍",
|
||||
// "50" => "50倍",
|
||||
// );
|
||||
if (!empty($key) && in_array($key, $data)) {
|
||||
return $data[$key];
|
||||
} else {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单价格更新
|
||||
*
|
||||
* @param integer $legal_id 法币id
|
||||
* @param integer $currency_id 交易币id
|
||||
* @param float $price 当前交易对最新价格
|
||||
* @param float $timestamp 毫秒级时间戳
|
||||
* @return void
|
||||
*/
|
||||
public static function newPrice($legal_id, $currency_id, $price, $timestamp = null)
|
||||
{
|
||||
$timestamp == null && $timestamp = microtime(true);
|
||||
if (empty($legal_id) || empty($currency_id) || empty($price)) {
|
||||
return false;
|
||||
}
|
||||
$params = [
|
||||
'legal_id' => $legal_id,
|
||||
'currency_id' => $currency_id,
|
||||
'now_price' => $price,
|
||||
'now' => $timestamp,
|
||||
];
|
||||
$start = microtime(true);
|
||||
//先批量更新指定交易对未平仓的交易的最新价格
|
||||
LeverTransaction::where("legal", $legal_id)
|
||||
->where("currency", $currency_id)
|
||||
->where("status", '<=', self::TRANSACTION)
|
||||
->update([
|
||||
'update_price' => $price,
|
||||
'update_time' => $timestamp,
|
||||
]);
|
||||
$end = microtime(true);
|
||||
LeverHandle::dispatch($params)->onQueue('lever:handle')->onConnection('sync');
|
||||
|
||||
// echo '更新持仓订单价格消耗:' . ($end - $start) . '秒' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 价格变动处理逻辑
|
||||
*
|
||||
* @param integer $legal_id 法币id
|
||||
* @param integer $currency_id 交易币id
|
||||
* @param float $price 当前交易对最新价格
|
||||
* @param float $timestamp 毫秒级时间戳
|
||||
* @return void
|
||||
*/
|
||||
public static function tradeHandle($legal_id, $currency_id, $price, $timestamp = null)
|
||||
{
|
||||
$timestamp == null && $timestamp = microtime(true);
|
||||
if (empty($legal_id) || empty($currency_id) || empty($price)) {
|
||||
return false;
|
||||
}
|
||||
$total_start = microtime(true);
|
||||
$start = microtime(true);
|
||||
//激活满足条件的挂单
|
||||
self::entrustActivate();
|
||||
$end = microtime(true);
|
||||
//echo '激活订单消耗:' . ($end - $start) . '秒' . PHP_EOL.
|
||||
$start = microtime(true);
|
||||
//止盈止亏处理
|
||||
self::checkNeedStopPriceTrade(0, $legal_id, $currency_id);
|
||||
$end = microtime(true);
|
||||
// echo '止盈止亏消耗:' . ($end - $start) . '秒' . PHP_EOL;
|
||||
$start = microtime(true);
|
||||
$levers = LeverTransaction::where("legal", $legal_id)
|
||||
->where("currency", $currency_id)
|
||||
->where("status", self::TRANSACTION)
|
||||
->select("id", "user_id", "create_time")
|
||||
->groupBy('user_id')
|
||||
->get();
|
||||
if (count($levers) > 0) {
|
||||
foreach ($levers as $trade) {
|
||||
//推送风险率和订单
|
||||
LeverPushTrade::dispatch($trade->user_id, $legal_id, $currency_id)->onQueue('lever:push:trade');
|
||||
self::handleUserLever($trade->user_id, $legal_id);
|
||||
}
|
||||
} else {
|
||||
echo '法币id:' . $legal_id . ',交易币id:' . $currency_id . '无数据' . PHP_EOL;
|
||||
}
|
||||
|
||||
$end = microtime(true);
|
||||
//echo '检测风险率消耗:' . ($end - $start) . '秒' . PHP_EOL;
|
||||
// echo '总计消耗:' . ($end - $total_start) . '秒' . PHP_EOL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 更新用户指定交易对的杠杆交易
|
||||
*
|
||||
* @param integer $user_id 用户id
|
||||
* @param integer $legal_id 法币id
|
||||
* @param integer $currency_id 交易币id
|
||||
* @return void
|
||||
*/
|
||||
protected static function handleUserLever($user_id, $legal_id, $currency_id = 0)
|
||||
{
|
||||
if (empty($user_id)) {
|
||||
return false;
|
||||
}
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$lever_burst_hazard_rate = Setting::getValueByKey('lever_burst_hazard_rate', 0);
|
||||
$legal_wallet = UsersWallet::where("user_id", $user_id)
|
||||
->where("currency", $legal_id)
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
if (empty($legal_wallet)) {
|
||||
throw new \Exception('钱包不存在');
|
||||
}
|
||||
//取交易对总盈利和总保证金
|
||||
$profit_results = self::getUserProfit($user_id, $legal_id, $currency_id);
|
||||
extract($profit_results);
|
||||
//是否满足爆仓条件
|
||||
$need_burst = self::checkBurst($legal_wallet);
|
||||
if (!$need_burst) {
|
||||
throw new \Exception('不满足爆仓条件');
|
||||
}
|
||||
//对用户交易对做平仓中标记
|
||||
$affect_result = self::setUserLeverCover($user_id, $legal_id, $currency_id);
|
||||
if (count($affect_result) <= 0) {
|
||||
throw new \Exception('爆仓状态标记失败');
|
||||
}
|
||||
$diff = 0;
|
||||
$change = bc_add($profits_total, $caution_money_total);
|
||||
$after_balance = bc_add($legal_wallet->lever_balance, $change);
|
||||
//如果余额不够扣就抹去不够扣的金额
|
||||
// if (bc_comp($after_balance, 0) < 0) {
|
||||
// $diff = $after_balance;
|
||||
// $change = -$legal_wallet->lever_balance;
|
||||
// }
|
||||
$legal_name = $legal_wallet->currency_name;
|
||||
$extra_data = serialize([
|
||||
'legal_name' => $legal_name,
|
||||
'affect_result' => $affect_result,
|
||||
'balance' => $legal_wallet->lever_balance,
|
||||
'caution_money_total' => $caution_money_total,
|
||||
'profits_total' => $profits_total,
|
||||
'diff' => $diff,
|
||||
'lever_burst_hazard_rate' => $lever_burst_hazard_rate,
|
||||
]);
|
||||
$result = change_wallet_balance(
|
||||
$legal_wallet,
|
||||
3,
|
||||
$change,
|
||||
AccountLog::LEVER_TRANSACTION_FROZEN,
|
||||
'暴仓处理' . $legal_name . '余额(退回保证金:' . $caution_money_total . ',结算总盈亏:' . $profits_total . ')',
|
||||
false,
|
||||
0,
|
||||
$diff == 0 ? 0 : 1, //1代表有差额
|
||||
$extra_data,
|
||||
true,
|
||||
true
|
||||
);
|
||||
if ($result !== true) {
|
||||
throw new \Exception($result);
|
||||
}
|
||||
DB::commit();
|
||||
LeverClose::dispatch($affect_result, false)->onQueue('lever:close');
|
||||
return true;
|
||||
} catch (\Exception $ex) {
|
||||
DB::rollBack();
|
||||
// $path = base_path() . '/storage/logs/lever/';
|
||||
// $filename = date('Ymd') . '.log';
|
||||
// file_exists($path) || @mkdir($path);
|
||||
// error_log(date('Y-m-d H:i:s') . ' File:' . $ex->getFile() . ', Line:' . $ex->getLine() . ', Message:' . $ex->getMessage() . PHP_EOL, 3, $path . $filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取用户盈利和保证金
|
||||
*
|
||||
* @param integer $user_id 用户id
|
||||
* @param integer $legal_id 法币id
|
||||
* @param integer $currency_id 交易币id
|
||||
* @return array
|
||||
*/
|
||||
public static function getUserProfit($user_id, $legal_id = 0, $currency_id = 0)
|
||||
{
|
||||
$profits_total = 0; //交易对盈亏总额
|
||||
$caution_money_total = 0; //交易对可用本金总额
|
||||
$origin_caution_money_total = 0; //交易对原始保证金
|
||||
try {
|
||||
//优先让数据库计算盈亏和保证金
|
||||
$user_profit = LeverTransaction::where('status', self::TRANSACTION)
|
||||
->where('user_id', $user_id)
|
||||
->where(function ($query) use ($legal_id, $currency_id) {
|
||||
$legal_id > 0 && $query->where('legal', $legal_id);
|
||||
$currency_id > 0 && $query->where('currency', $currency_id);
|
||||
})
|
||||
->select('user_id')
|
||||
->selectRaw('SUM((CASE `type` WHEN 1 THEN `update_price` - `price` WHEN 2 THEN `price` - `update_price` END) * `number`) AS `profits_total`')
|
||||
->selectRaw('SUM(`caution_money`) AS `caution_money_total`')
|
||||
->selectRaw('SUM(`origin_caution_money`) AS `origin_caution_money_total`')
|
||||
->groupBy('user_id')
|
||||
->first();
|
||||
if (!$user_profit) {
|
||||
$levers = LeverTransaction::where(function ($query) use ($legal_id, $currency_id) {
|
||||
$legal_id > 0 && $query->where("legal", $legal_id);
|
||||
$currency_id > 0 && $query->where("currency", $currency_id);
|
||||
})->where("user_id", $user_id)->where("status", self::TRANSACTION)->get();
|
||||
if (count($levers) <= 0) {
|
||||
throw new \Exception('没有需要处理的交易');
|
||||
}
|
||||
//计算交易对总盈亏
|
||||
foreach ($levers as $trade) {
|
||||
$caution_money_total = bc_add($caution_money_total, $trade->caution_money);
|
||||
$origin_caution_money_total = bc_add($origin_caution_money_total, $trade->origin_caution_money);
|
||||
$profits_total = bc_add($profits_total, $trade->profits);
|
||||
}
|
||||
} else {
|
||||
$caution_money_total = $user_profit->caution_money_total;
|
||||
$origin_caution_money_total = $user_profit->origin_caution_money_total;
|
||||
$profits_total = $user_profit->profits_total;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
//echo $e->getMessage();
|
||||
}
|
||||
return [
|
||||
'profits_total' => $profits_total,
|
||||
'caution_money_total' => $caution_money_total,
|
||||
'origin_caution_money_total' => $origin_caution_money_total,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 平仓用户指定交易对交易(只是改变状态,避免价格再被更新)
|
||||
*
|
||||
* @param integer $user_id
|
||||
* @param integer $legal_id
|
||||
* @param integer $currency_id
|
||||
* @return array
|
||||
*/
|
||||
protected static function setUserLeverCover($user_id, $legal_id = 0, $currency_id = 0)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
$trades = LeverTransaction::where(function ($query) use ($legal_id, $currency_id) {
|
||||
$legal_id > 0 && $query->where("legal", $legal_id);
|
||||
$currency_id > 0 && $query->where("currency", $currency_id);
|
||||
})->where("user_id", $user_id)->where("status", self::TRANSACTION);
|
||||
$list = $trades->pluck('id')->all(); //记录下标记的交易id
|
||||
$result = $trades->update([
|
||||
'status' => self::CLOSING,
|
||||
'handle_time' => microtime(true),
|
||||
]);
|
||||
DB::commit();
|
||||
return $result > 0 ? $list : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 平仓
|
||||
*
|
||||
* @param \App\LeverTransaction $lever_transaction
|
||||
* @return bool
|
||||
*/
|
||||
public static function leverClose($lever_transaction, $is_follow = false)
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
if (empty($lever_transaction)) {
|
||||
throw new \Exception('交易不存在');
|
||||
}
|
||||
$last_price = self::getLastPrice($lever_transaction->legal, $lever_transaction->currency);
|
||||
$lever_transaction->refresh();
|
||||
if ($lever_transaction->status != self::TRANSACTION) {
|
||||
throw new \Exception('该笔交易状态异常,不能平仓' . $lever_transaction->status);
|
||||
}
|
||||
//更新状态
|
||||
$lever_transaction->update_price = $last_price;
|
||||
$lever_transaction->update_time = microtime(true);
|
||||
$lever_transaction->status = self::CLOSING;
|
||||
$lever_transaction->handle_time = microtime(true);
|
||||
$result = $lever_transaction->save();
|
||||
if (!$result) {
|
||||
throw new \Exception('平仓失败:锁定交易状态失败');
|
||||
}
|
||||
$legal_wallet = UsersWallet::where("user_id", $lever_transaction->user_id)
|
||||
->where("currency", $lever_transaction->legal)
|
||||
->lockForUpdate()
|
||||
->first();
|
||||
if (empty($legal_wallet)) {
|
||||
throw new \Exception('钱包不存在');
|
||||
}
|
||||
//计算盈亏
|
||||
$profit = $lever_transaction->profits;
|
||||
$change = bc_add($lever_transaction->caution_money, $profit); //算上本金
|
||||
//从钱包处理资金
|
||||
$pre_result = bc_add($legal_wallet->lever_balance, $change);
|
||||
$diff = 0;
|
||||
//是否余额不够扣除
|
||||
// if (bc_comp($pre_result, 0) < 0) {
|
||||
// $change = -$legal_wallet->lever_balance;
|
||||
// $diff = $pre_result;
|
||||
// }
|
||||
$extra_data = [
|
||||
'trade_id' => $lever_transaction->id,
|
||||
'caution_money' => $lever_transaction->caution_money,
|
||||
'profit' => $profit,
|
||||
'diff' => $diff,
|
||||
];
|
||||
$result = change_wallet_balance(
|
||||
$legal_wallet,
|
||||
3,
|
||||
$change,
|
||||
AccountLog::LEVER_TRANSACTION_ADD,
|
||||
'平仓资金处理',
|
||||
false,
|
||||
0,
|
||||
$diff == 0 ? 0 : 1, //1代表有差额
|
||||
serialize($extra_data),
|
||||
true ,//余额为0仍然要平仓
|
||||
true//允许资金扣为负数
|
||||
);
|
||||
if ($result !== true) {
|
||||
throw new \Exception($result);
|
||||
}
|
||||
$lever_transaction->refresh();
|
||||
$lever_transaction->status = self::CLOSED;
|
||||
$lever_transaction->fact_profits = $profit;
|
||||
$lever_transaction->complete_time = microtime(true);
|
||||
$result = $lever_transaction->save();
|
||||
if (!$result) {
|
||||
throw new \Exception('平仓失败:更新处理状态失败');
|
||||
}
|
||||
DB::commit();
|
||||
//处理跟随订单,这里用个判断防止无限递归
|
||||
if($is_follow === false) {
|
||||
FollowOrderHandel::dispatch($lever_transaction->id)->onQueue('FollowOrderHandel');
|
||||
}
|
||||
return true;
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取交易对最新价格(优先从行情获取)
|
||||
*
|
||||
* @param integer $legal_id 法币id
|
||||
* @param integer $currency_id 交易币id
|
||||
* @return integer
|
||||
*/
|
||||
public static function getLastPrice($legal_id, $currency_id)
|
||||
{
|
||||
//优先从行情取最新价格
|
||||
$last_price = 0;
|
||||
$last = CurrencyQuotation::where('legal_id', $legal_id)
|
||||
->where('currency_id', $currency_id)
|
||||
->first();
|
||||
if (!$last) {
|
||||
$last = TransactionComplete::orderBy('id', 'desc')
|
||||
->where("currency", $currency_id)
|
||||
->where("legal", $legal_id)
|
||||
->first();
|
||||
if (!empty($last)) {
|
||||
$last_price = $last->price;
|
||||
}
|
||||
} else {
|
||||
$last && $last_price = $last->now_price;
|
||||
}
|
||||
return $last_price;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取钱包的风险率(请传法币钱包)
|
||||
*
|
||||
* @param App\UsersWallet $wallet
|
||||
* @return float
|
||||
*/
|
||||
public static function getWalletHazardRate($wallet)
|
||||
{
|
||||
$hazard_rate = 0;
|
||||
$total_money = 0;
|
||||
if (!$wallet) {
|
||||
return $hazard_rate;
|
||||
}
|
||||
$profit_result = self::getUserProfit($wallet->user_id, $wallet->currency);//取用户盈利和保证金
|
||||
extract($profit_result);//函数从数组中把变量导入到当前的符号表中
|
||||
$wallet->refresh();
|
||||
$balance = $wallet->lever_balance;
|
||||
$total_money = bc_add($balance, $origin_caution_money_total);
|
||||
if (bc_comp($origin_caution_money_total, 0) <> 0) {
|
||||
$hazard_rate = bc_mul(bc_div(bc_add($total_money, $profits_total), $origin_caution_money_total), 100, 2);
|
||||
}
|
||||
return $hazard_rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测是否达到爆仓条件
|
||||
*
|
||||
* @param \App\UsersWallet $user_wallet
|
||||
* @return bool 达到返回真,否则返回假
|
||||
*/
|
||||
public static function checkBurst($user_wallet)
|
||||
{
|
||||
try {
|
||||
if (!($user_wallet instanceof UsersWallet)) {
|
||||
throw new \Exception('钱包无效');
|
||||
}
|
||||
/*
|
||||
//取交易对总盈利和总保证金
|
||||
$profit_results = self::getUserProfit($user_wallet->user_id, $user_wallet->legal_id);
|
||||
extract($profit_results);
|
||||
//判断盈亏
|
||||
if (bc_comp($profits_total, 0) >= 0) {
|
||||
throw new \Exception('不存在亏损,无须平仓');
|
||||
}
|
||||
$change = bc_add($profits_total, $caution_money_total);
|
||||
//如果本金足以抵亏就返回
|
||||
if (bc_comp($change, 0) >= 0) {
|
||||
throw new \Exception('本金充足,无须平仓');
|
||||
}
|
||||
//本金亏完,判断余额是否够扣,够直接返回
|
||||
//直接判断总额
|
||||
$total_money = bc_add($legal_wallet->lever_balance, $caution_money_total);
|
||||
$pre_total_checked = bc_add($total_money, $profits_total);
|
||||
if (bc_comp($pre_total_checked, 0) > 0) {
|
||||
throw new \Exception('总资金充足,无须平仓');
|
||||
}
|
||||
*/
|
||||
//使用输赢率来控制爆仓
|
||||
$lever_burst_hazard_rate = Setting::getValueByKey('lever_burst_hazard_rate', 0);
|
||||
$hazard_rate = self::getWalletHazardRate($user_wallet);
|
||||
$result = bc_comp($hazard_rate, $lever_burst_hazard_rate) <= 0;
|
||||
$param = [
|
||||
'hazard_rate' => $hazard_rate,
|
||||
'lever_burst_hazard_rate' => $lever_burst_hazard_rate,
|
||||
];
|
||||
// $path = base_path() . '/storage/logs/lever/';
|
||||
// $filename = date('Ymd') . '.log';
|
||||
// file_exists($path) || @mkdir($path);
|
||||
// error_log(date('Y-m-d H:i:s') . ' result: ' . var_export($result, true) . ', param:' . var_export($param, true) . PHP_EOL, 3, $path . $filename);
|
||||
return $result;
|
||||
} catch (\Exception $e) {
|
||||
$path = base_path() . '/storage/logs/lever/';
|
||||
$filename = date('Ymd') . '.log';
|
||||
file_exists($path) || @mkdir($path);
|
||||
error_log(date('Y-m-d H:i:s') . ' File:' . $e->getFile() . ', Line:' . $e->getLine() . ', Message:' . $e->getMessage() . PHP_EOL, 3, $path . $filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取设置了止盈止亏价并且价格满足的交易
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function checkNeedStopPriceTrade($user_id = 0, $legal_id = 0, $currency_id = 0)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
$need_check_lever = LeverTransaction::where('status', self::TRANSACTION)
|
||||
->where(function ($query) use ($user_id, $legal_id, $currency_id) {
|
||||
$user_id > 0 && $query->where('user_id', $user_id);
|
||||
$legal_id > 0 && $query->where('legal', $legal_id);
|
||||
$currency_id > 0 && $query->where('currency', $currency_id);
|
||||
})->where(function ($query) {
|
||||
$query->where(function ($query) {
|
||||
$query->where('type', self::BUY)->where(function ($query) {
|
||||
$query->where(function ($query) {
|
||||
$query->whereRaw('`update_price` >= `target_profit_price`')->where('target_profit_price', '>', 0);
|
||||
})->orWhere(function ($query) {
|
||||
$query->whereRaw('`update_price` <= `stop_loss_price`')->where('stop_loss_price', '>', 0);
|
||||
});
|
||||
});
|
||||
})->orWhere(function ($query) {
|
||||
$query->where('type', self::SELL)->where(function ($query) {
|
||||
$query->where(function ($query) {
|
||||
$query->whereRaw('`update_price` <= `target_profit_price`')->where('target_profit_price', '>', 0);
|
||||
})->orWhere(function ($query) {
|
||||
$query->whereRaw('`update_price` >= `stop_loss_price`')->where('stop_loss_price', '>', 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
$task_list = $need_check_lever->pluck('id')->all();
|
||||
$result = $need_check_lever->update([
|
||||
'status' => self::CLOSING,
|
||||
'handle_time' => microtime(true),
|
||||
]);
|
||||
DB::commit();
|
||||
$result > 0 && LeverClose::dispatch($task_list, true)->onQueue('lever:close');
|
||||
}
|
||||
|
||||
/**
|
||||
* 委托激活
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function entrustActivate()
|
||||
{
|
||||
/*
|
||||
逻辑:分析师认为当价格走到某个区间后会停止,然后逆向走,在停止时期进行反向投资来赚取利润
|
||||
例如:
|
||||
(1)用户认为某个币在指定周期内跌到5元已跌到谷底不可能再跌了,预测接下来行情会上涨,那应该设定在跌到5元时进行买入,等行情上涨赚钱
|
||||
(2)用户认为某个币在指定周期内涨到1000元已经达到顶峰,预测接下来行情会下跌,那应该设定在涨到1000元时进行卖出,等行情下跌赚钱
|
||||
程序逻辑:
|
||||
(1)卖出:当前价格 [大于等于] 设置价格时触发(等涨到指定价格时卖出坐等下跌)
|
||||
(2)买入:当前价格 [小于等于] 设置价格时触发(等跌到指定价格时买入坐等上涨)
|
||||
*/
|
||||
/*
|
||||
SELECT *
|
||||
FROM lever_transaction
|
||||
WHERE
|
||||
`status`=0
|
||||
AND
|
||||
(
|
||||
`type`=1 AND `update_price` <= `origin_price`
|
||||
OR
|
||||
`type`=2 AND `update_price` >= `origin_price`
|
||||
)
|
||||
*/
|
||||
$trades = LeverTransaction::where('status', LeverTransaction::ENTRUST)
|
||||
->where(function ($query) {
|
||||
$query->orWhere(function ($query) {
|
||||
$query->where('type', LeverTransaction::BUY)
|
||||
->whereRaw('`update_price` <= `origin_price`');
|
||||
})->orWhere(function ($query) {
|
||||
$query->orWhere('type', LeverTransaction::SELL)
|
||||
->whereRaw('`update_price` >= `origin_price`');
|
||||
});
|
||||
});
|
||||
$lists = $trades->pluck('id')->all();
|
||||
$result = $trades->update([
|
||||
'transaction_time' => microtime(true),
|
||||
'status' => LeverTransaction::TRANSACTION,
|
||||
]);
|
||||
return $result > 0 ? $lists : [];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user