Commit 2c573125 authored by wuxiaoli's avatar wuxiaoli

添加购买委托

parent 3d6d3313
......@@ -9,4 +9,6 @@
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------
return ['app\stock\command\Crontab'];
\ No newline at end of file
return ['app\stock\command\Crontab',
'app\stock\command\Trust',
];
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\market\command;
use app\market\model\Deal_stock;
use app\market\model\Position;
use app\market\model\SubAccountMoney;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\Db;
class Trust extends Command
{
protected function configure()
{
// 指令配置
$this->setName('Trust')
->setDescription('交易脚本');
}
protected function execute(Input $input, Output $output)
{
// 启动协程
//if(!checkTradeTime()) return false;
$time = config('trust_active_time')*60 ?? TRUST_ACTIVE_TIME;
// 处理超时委托线程
$res_c = Db::name('stock_trust')->where('status','已委托')->where("add_time", "<=", time() - $time)->select();
if (!empty($res_c)) $this->cancelTrusts($res_c);
// 处理委托交易线程
//$res_t = Db::name('stock_trust')->where('status','已委托')->where("add_time", "between",[time() - $time, time()])->whereDay('trust_date')->select()->toArray();
$res_t = Db::name('stock_trust')->where('status','已委托')->select();
if (!empty($res_t)) $this->goturnTrusts($res_t);
}
/* 将最新委托转成不可撤销状态,等待交易 */
protected function goturnTrusts($res){
$this->output->writeln(date('Y-m-d H:i:s').' 交易委托: '.count($res)." 个");
foreach ($res as $k => $item ){
//查询股票最新行情
$Qdata = z_market($item['gupiao_code']);
Db::startTrans();
if($this->checkTrust($item)){
if($item['info'] !== 'system'){
switch ($item['flag1']) {
case 0; //'买入委托'
$eprice = self::getPrice($Qdata,$item['gupiao_code'],$item['trust_price'],'buy',$item['trust_count']);
if($eprice > 0){
$item['trust_price'] = $eprice;
$this->output->writeln(date('Y-m-d H:i:s').' '.$item['gupiao_name'].$item['gupiao_code'].' '.$item['trust_price'].' 买入价格:'.$eprice);
$order_res = $this->orderTrust($Qdata, $item, 6);//实盘买入模式:6
}else{
$this->output->writeln(date('Y-m-d H:i:s').' '.$item['gupiao_name'].$item['gupiao_code'].' '.$item['trust_price'].' 价格检查:'.$eprice);
}
break;
case 1; //'卖出委托':
$eprice = self::getPrice($Qdata,$item['gupiao_code'],$item['trust_price'],'sell',$item['trust_count']);
if($eprice > 0){
$item['trust_price'] = $eprice;
$this->output->writeln(date('Y-m-d H:i:s').' '.$item['gupiao_name'].$item['gupiao_code'].' '.$item['trust_price'].' 卖出价格:'.$eprice);
$order_res = $this->orderTrust($Qdata, $item, 5);//实盘卖出模式:5
}else{
$this->output->writeln(date('Y-m-d H:i:s').' '.$item['gupiao_name'].$item['gupiao_code'].' '.$item['trust_price'].' 价格检查:'.$eprice);
}
break;
default: $order_res = [];
}
}else{//如果是系统强制平仓就不检查市价
$order_res = $this->orderTrust($Qdata, $item, 5);
}
if(isset($order_res) && !empty($order_res)){
//$this->output->writeln(date('Y-m-d H:i:s').' '.$item['gupiao_name'].$item['gupiao_code'].' 时间:'.date('H:i:s', $item['add_time']).' '.$item['trust_count'].'股 '.$item['flag2'].' 成交');
Db::commit();
}else{
Db::rollback();
continue;
}
}else{
$this->output->writeln(date('Y-m-d H:i:s').' '.$item['gupiao_name'].$item['gupiao_code'].' 交易状态更新失败');
}
}
}
/* 撤销超时委托 */
protected function cancelTrusts($res)
{
$this->output->writeln(date('Y-m-d H:i:s').' 超时委托: '.count($res)." 个");
$subaccount=new SubAccountMoney();
foreach ($res as $k => $v ){
Db::startTrans();
$info = Db::name('stock_trust')->where(['trust_no'=>$v['trust_no']])->lock(true)->find();
if(!empty($info)){
$row = [];
$row['status'] = "已撤";
$row['cancel_order_flag'] = 1;
$row['cancel_order_count'] = $v['trust_count'];
$trust = Db::name('stock_trust')->where(['trust_no'=>$v['trust_no']])->update($row);
$affect = Db::name('stock_delivery_order')->where(['trust_no'=>$v['trust_no']])->value('liquidation_amount');
if(!$affect) {
$this->output->writeln(date('Y-m-d H:i:s').' 在订单数据库中,委托单号: '.$v['trust_no']." 没有找到");
}
switch ($info['flag2']){
case '买入委托':
//解冻并转入子账户可用余额
$subm_res = $subaccount->up_moneylog($v['sub_id'], $affect, 8);
$position_in = $subm_res ? true : false;
break;
case '卖出委托':
$position = Db::name('stock_position')->where(['sub_id'=>$v['sub_id'],'gupiao_code'=>$info['gupiao_code']])->find();
$position['canbuy_count'] = $position['canbuy_count']+$v['trust_count'];
$position_in = Db::name('stock_position')->where(['sub_id'=>$v['sub_id'],'gupiao_code'=>$info['gupiao_code']])->update($position);
$subm_res = $subaccount->up_moneylog($v['sub_id'], $affect, 9);
break;
}
$delivery = Db::name('stock_delivery_order')->where(['trust_no'=>$v['trust_no']])->delete();
if($trust && $delivery && $subm_res && $position_in){
Db::commit();
}else{
Db::rollback();
continue;
}
}
//$this->output->writeln(date('Y-m-d H:i:s').' '.$v['gupiao_name'].$v['gupiao_code'].' 时间:'.date('H:i:s', $v['add_time']).' '.$v['trust_count'].'股 撤单成功');
}
}
/*写入委托表*/
protected function checkTrust($item)
{
$row = [
'status' => "已成",//状态说明
'volume' => $item['trust_count'],//成交数量
'amount' => $item['trust_count'] * $item['trust_price'],//成交金额
'cancel_order_flag' => 1, //撤单标志 1、已成
];
$trust = Db::name('stock_trust')->where(['trust_no' => $item['trust_no']])->update($row);
return $trust;
}
/*交易买入/卖出*/
protected function orderTrust($Qdata, $trust, $trustModel)
{
$subaccount=new SubAccountMoney();
//检查交割明细
$dev_info = Db::name('stock_delivery_order')->where(['trust_no'=>$trust['trust_no']])->find();
//print_r($dev_info);return false;
$affect = $dev_info['liquidation_amount'];
if(!$affect) return false;
//$moneyinfo = SubAccountMoney::getAccountMoney($trust['sub_id']);
//计算佣金
//$commission = commission($trust['trust_count'] * $trust['trust_price'],$moneyinfo['commission_scale'],$moneyinfo['min_commission']);
//如果时卖出模式时加上印花税
//$stamps = $trustModel === 5 ? stamps($trust['trust_count'] * $trust['trust_price']) : 0;
//计算过户费
//$transfer = transfer($trust['trust_count'] * $trust['trust_price']);
//计算手续费
//$fee = $commission + $stamps + $transfer;
//$cha = $dev_info['commission'] + $dev_info['transfer_fee'] - $fee;
//这里用(最新价格-委托价格*委托数量),以便加入子账户中
$Balance = round(($Qdata['current_price']-$trust['trust_price']) * $trust['trust_count'], 2);
//print_r($trust['sub_id'].' '.$affect.' '.$trustModel.' '.$Balance);return false;
//写入子账户资金变化表
$sm_res = $subaccount->up_moneylog($trust['sub_id'], $affect, $trustModel , $return_money = 0, $Balance);
//写入成交表
$deal_stock = new Deal_stock();
$deal_res = $deal_stock->add_m_deal_stock($Qdata,$trust['trust_count'],$trust['trust_price'],$trust['sub_id'],$trust['lid'],$trust['login_name'],$trust['soruce'],$trust['trust_no']);
//查询持仓表
$postmd = Db::name('stock_position')->where(['sub_id'=>$trust['sub_id'],'gupiao_code'=>$trust['gupiao_code']])->find();
$canbuy = !empty($postmd) ? $postmd['stock_count'] : 0;
//if($canbuy <= 0) $this->output->writeln(date('Y-m-d H:i:s').$trust['gupiao_name'].' '.$trust['gupiao_code'].' 可卖数量: '.$canbuy);
//组合数据后修改交割表
$delivery = [];
$position = [];
switch ($trustModel) {
case 6: //'买入委托' //实盘买入模式:6
$delivery['amount'] = $canbuy + $trust['trust_count'];
$delivery['amount'] = $canbuy + $trust['trust_count'];
$canbuy = $canbuy + $trust['trust_count'];
$this->output->writeln(date('Y-m-d H:i:s').$trust['gupiao_name'].' '.$trust['gupiao_code'].' 买入后数量: '.$canbuy);
break;
case 5: //'卖出委托' //实盘卖出模式:5
$delivery['amount'] = $canbuy - $trust['trust_count'];
$delivery['amount'] = $canbuy - $trust['trust_count'];
$canbuy = $canbuy - $trust['trust_count'];
$this->output->writeln(date('Y-m-d H:i:s').$trust['gupiao_name'].' '.$trust['gupiao_code'].' 卖出后数量: '.$canbuy);
break;
default:
$delivery['amount'] = $trust['trust_count'];
$delivery['amount'] = $trust['trust_count'];
break;
}
$delivery['status'] ='1';// 改变订单状态
//$delivery['deal_price'] = $trust['trust_price'];
//$delivery['deal_date'] = date("Y-m-d",time());
//$delivery['transfer_fee'] = $transfer;
//$delivery['commission'] = $commission;
//$delivery['residual_quantity'] = $trust['trust_count'] * $trust['trust_price'];
//$delivery['liquidation_amount'] = $trust['trust_count'] * $trust['trust_price'] + $fee;
//$delivery['residual_amount'] = $dev_info['residual_amount'] + $dev_info['liquidation_amount'] - $delivery['liquidation_amount'];
$delivery_res = Db::name('stock_delivery_order')->where(['trust_no'=>$trust['trust_no']])->update($delivery);
// 新增/修改持仓列表
$position_res = Position::add_m_position($trust['gupiao_code'],$canbuy,$trust['sub_id'],$trust['lid'],$trust['login_name'],$trust['soruce'],$trust['trust_price'],$trust['trust_no']);
//print_r($canbuy);return;
if($sm_res && $deal_res && $delivery_res && $position_res) return true;
$this->output->writeln(date('Y-m-d H:i:s').' sm_res: '.$sm_res." deal_res:".$deal_res." delivery_res:".$delivery_res." position_res:".$position_res);
return false;
}
protected function getPrice($Qdata, $stockCode, $price, $direction, $count=100)
{
try {
// 最新行情
$eprice = 0;
$Qdata = $Qdata ?: z_market($stockCode);
switch ($direction) {
case 'buy':
if($price <= 0){
// 从1档递进取价格
for ($stall=1; $stall<=5; $stall++) {
switch ($stall) {
case 1: // 卖一
$key = 'sell_one_price';//价格
$val = 'sell_one_amount';//卖一量(手)
break;
case 2: // 卖二
$key = 'sell_two_price';//价格
$val = 'sell_two_amount';//卖二量(手)
break;
case 3: // 卖三
$key = 'sell_three_price';//价格
$val = 'sell_three_amount';//卖三量(手)
break;
case 4: // 卖四
$key = 'sell_four_price';//价格
$val = 'sell_four_amount';//卖四量(手)
break;
case 5: // 卖五
$key = 'sell_five_price';//价格
$val = 'sell_five_amount';//卖五量(手)
break;
}
$price = $Qdata[$key];
if($price > 0 && $count <= $Qdata[$val]*10000){
$eprice = $price;
break;
}
}
}else{
$eprice = $price >= $Qdata['current_price'] && $Qdata['current_price'] > 0 && $price <= $Qdata['sell_five_price'] ? $price : 0;
}
break;
case 'sell':
if($price <= 0){
// 从1档递进取价格
for ($stall=1; $stall<=5; $stall++) {
switch ($stall) {
case 1: // 卖一
$key = 'buy_one_price';//价格
$val = 'buy_one_amount';//卖一量(手)
break;
case 2: // 卖二
$key = 'buy_two_price';//价格
$val = 'buy_two_amount';//卖二量(手)
break;
case 3: // 卖三
$key = 'buy_three_price';//价格
$val = 'buy_three_amount';//卖三量(手)
break;
case 4: // 卖四
$key = 'buy_four_price';//价格
$val = 'buy_four_amount';//卖四量(手)
break;
case 5: // 卖五
$key = 'buy_five_price';//价格
$val = 'buy_five_amount';//卖五量(手)
break;
}
$price = $Qdata[$key];
if($price > 0 && $count <= $Qdata[$val]*10000){
$eprice = $price;
break;
}
}
}else{
$eprice = $price <= $Qdata['current_price'] && $Qdata['current_price'] > 0 && $price <= $Qdata['buy_one_price'] ? $price : 0;
}
break;
}
} catch (\Exception $e) {
$eprice = 0;
}
return $eprice;
}
}
......@@ -323,7 +323,7 @@ class Trust extends Model{
{
//查询股票最新行情
$Qdata = z_market($data['code'],$data['market']);
$price = $data['price'] <= 0 ? $Qdata['Price'] : $data['price'];
$price = $data['price'] <= 0 ? $Qdata['current_price'] : $data['price'];
//判断股票价格是否符号购买条件
if (config('stock_buy_price') > 0) {
if ($price < config('stock_buy_price')) {
......@@ -376,7 +376,7 @@ class Trust extends Model{
{
//查询股票最新行情
$Qdata = z_market($data['code'],$data['market']);
$price = $data['price'] <= 0 ? $Qdata['Price'] : $data['price'];
$price = $data['price'] <= 0 ? $Qdata['current_price'] : $data['price'];
if(config('site_trade_sell') == 0) {
return array('status' => 0, 'message' => '系统设置不允许卖出股票');
......@@ -387,7 +387,7 @@ class Trust extends Model{
return ['status'=>0, 'message'=>'可卖股票不足'];
}
//当股票跌停时买一至买五价格为空
if(intval($Qdata["Bp1"]) <= 0 || intval($Qdata['Bv1']*100) < $data['count']){
if(intval($Qdata["buy_one_price"]) <= 0 || intval($Qdata['buy_one_amount']*100) < $data['count']){
return ['status'=>0, 'message'=>'当前买盘不足,无法即时成交!'];
}
//检查子账户余额
......@@ -398,7 +398,7 @@ class Trust extends Model{
if($data['price'] > 0 && $data['model'] == 1){ //model = 1 是委托状态
$trade_money = intval($data['count']) * intval($data['price']);
}else{
$price = $Qdata['Price'];
$price = $Qdata['current_price'];
//如果没有委托价格使用下面的公式
$trade_money = intval($data['count']) * intval($price);
}
......@@ -426,16 +426,16 @@ class Trust extends Model{
$trade_money = $count * $price;
}else{
$price = 0;
$v_arr[1] = $Qdata['Sv1'] * 100;
$v_arr[2] = $Qdata['Sv2'] * 100;
$v_arr[3] = $Qdata['Sv3'] * 100;
$v_arr[4] = $Qdata['Sv4'] * 100;
$v_arr[5] = $Qdata['Sv5'] * 100;
$p_arr[1] = $Qdata['Sp1'];
$p_arr[2] = $Qdata['Sp2'];
$p_arr[3] = $Qdata['Sp3'];
$p_arr[4] = $Qdata['Sp4'];
$p_arr[5] = $Qdata['Sp5'];
$v_arr[1] = $Qdata['sell_one_amount'] * 100;
$v_arr[2] = $Qdata['sell_two_amount'] * 100;
$v_arr[3] = $Qdata['sell_three_amount'] * 100;
$v_arr[4] = $Qdata['sell_four_amount'] * 100;
$v_arr[5] = $Qdata['sell_five_amount'] * 100;
$p_arr[1] = $Qdata['sell_one_price'];
$p_arr[2] = $Qdata['sell_two_price'];
$p_arr[3] = $Qdata['sell_three_price'];
$p_arr[4] = $Qdata['sell_four_price'];
$p_arr[5] = $Qdata['sell_five_price'];
$tmd = 0;
foreach ($v_arr as $key => $v ){
$tmd = $tmd + $v;
......@@ -464,7 +464,7 @@ class Trust extends Model{
$res = Db::name('stock_list')->where(['code' => $code, 'status' => 1])->find();
//判断是否超过该只股票限额
$pos = Db::name('stock_position')->where(['sub_id' => $subid,'gupiao_code' => $code,'buying' => 0])->sum('stock_count');
if (isset($res['quota']) && ($res['quota'] < (($pos * $Qdata['Price']) + $trade_money))) {
if (isset($res['quota']) && ($res['quota'] < (($pos * $Qdata['current_price']) + $trade_money))) {
return ['status'=>0, 'message'=>'该股票超过了单支股票最大购买限额'];
}
return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment