You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
411 lines
17 KiB
411 lines
17 KiB
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\DataRao;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Console\Command;
|
|
|
|
class FakeKline5 extends Command
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'fakeKline5';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = '定时每日伪造币种Kline数据->HIPC';
|
|
|
|
/**
|
|
* Create a new command instance.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
}
|
|
|
|
/**
|
|
* Execute the console command.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function handle()
|
|
{
|
|
// 最后一条1dayK线
|
|
$last = DataRao::query()->where('is_day', 1)->orderByDesc('Date')->first();
|
|
if (blank($last)) {
|
|
//Y-m-d H:i:s 开始结束时间
|
|
$start_date = Carbon::now()->floorDay();
|
|
$end_date = Carbon::now()->floorDay()->addDays(2);
|
|
return false;
|
|
} else {
|
|
$last_date = $last['datetime'];
|
|
//Y-m-d H:i:s 开始结束时间
|
|
$start_date = Carbon::parse($last_date)->addDays(1)->toDateTimeString();
|
|
$end_date = Carbon::parse($last_date)->addDays(2)->toDateTimeString();
|
|
|
|
$decimal = 100000;
|
|
$min_rate = get_setting_value('min_rate', 'exchange', 0.04);
|
|
$max_rate = get_setting_value('max_rate', 'exchange', 0.08);
|
|
if ($min_rate < 0) $min_rate = 0;
|
|
if ($max_rate >= 1) $max_rate = 0.99;
|
|
$up_or_down = get_setting_value('up_or_down', 'exchange', 1);
|
|
$rate = mt_rand($min_rate * $decimal, $max_rate * $decimal) / $decimal;
|
|
$change_rate = ($up_or_down == 1) ? (1 + $rate) : (1 - $rate);
|
|
$base_price = $last['Close'];
|
|
$target_price = PriceCalculate($last['Close'], '*', $change_rate, 5);
|
|
}
|
|
// dd($start_date,$end_date);
|
|
|
|
// 生成一天的所有1minK线 其他周期K线根据1minK线生成
|
|
if ($this->fake_1min_kline($change_rate, $base_price, $target_price, $start_date, $end_date)) {
|
|
$this->fake_period_kline('5min', $start_date, $end_date);
|
|
$this->fake_period_kline('15min', $start_date, $end_date);
|
|
$this->fake_period_kline('30min', $start_date, $end_date);
|
|
$this->fake_period_kline('60min', $start_date, $end_date);
|
|
$this->fake_period_kline('1day', $start_date, $end_date);
|
|
|
|
// $dt = 0 ~ 6 每周日生成1weekK线
|
|
if (Carbon::parse($start_date)->dayOfWeek == 0) {
|
|
$this->fake_period_kline('1week', $start_date, $end_date);
|
|
}
|
|
// 每月1号 生成1monK线
|
|
if (Carbon::parse($start_date)->day == 1) {
|
|
$this->fake_period_kline('1mon', $start_date, $end_date);
|
|
}
|
|
|
|
// 每天更新周线和月线
|
|
$this->update_kline('1week', $start_date);
|
|
$this->update_kline('1mon', $start_date);
|
|
}
|
|
}
|
|
|
|
// 生成1minK线
|
|
private function fake_1min_kline($change_rate, $base_price, $target_price, $start_date, $end_date)
|
|
{
|
|
$decimal = 100000;
|
|
$seconds = 60;
|
|
$flag = 'is_1min';
|
|
|
|
$is_sharp = get_setting_value('is_sharp', 'exchange', 0); //大幅拉升开关
|
|
if ($is_sharp == 1) {
|
|
$first_target_price = $base_price = PriceCalculate($base_price, '+', PriceCalculate(($target_price - $base_price), '*', 0.8, 8), 5);
|
|
}
|
|
|
|
$start = strtotime($start_date);
|
|
$end = strtotime($end_date);
|
|
|
|
$period_seconds = 60;
|
|
$periodCount = 86400 / $period_seconds; //获取一天的分钟数
|
|
$unit = custom_number_format(PriceCalculate(($target_price - $base_price), '/', $periodCount, 8), 8); //获取每分钟的涨幅单位
|
|
|
|
// 24小时 周期价格上涨下跌趋势随机 1涨2跌
|
|
$period2_seconds = 900; //15分钟
|
|
$periodCount2 = 86400 / $period2_seconds; //每天有96个15分钟
|
|
$periodsTrend = [];
|
|
for ($i = 0; $i < $periodCount2; $i++) {
|
|
if ($change_rate > 1) { //如果为涨幅
|
|
$thresholdValue = 60;
|
|
} else { //如果为跌幅
|
|
$thresholdValue = 40;
|
|
}
|
|
$periodsTrend[$start + ($i * $period2_seconds)] = (mt_rand(1, 100) <= $thresholdValue) ? 1 : 2; //一段时间的趋势 涨幅60%为趋势1 跌幅40%为趋势1
|
|
}
|
|
|
|
$ups_downs_high = abs(floor($unit * $decimal * 80)); //高
|
|
$ups_downs_value = abs(floor($unit * $decimal * 30)); //值
|
|
$ups_downs_low = floor(1); //低
|
|
|
|
$current = $start;
|
|
$kkk = 1;
|
|
// dd($current,$start,$end);
|
|
while ($current < $end) {
|
|
echo $current . '--' . $kkk . "\r\n";
|
|
$max = $base_price * ($change_rate + 0.01);
|
|
// 获取上一条
|
|
$prev = DataRao::query()->where($flag, 1)->where('Date', $current - $seconds)->first(); // 上一条K线
|
|
if (blank($prev)) {
|
|
$prev = DataRao::query()->where('is_day', 1)->orderByDesc('Date')->first();
|
|
}
|
|
$price = $prev['Close'] * $decimal;
|
|
$volume = ceil(mt_rand(535012, 2009870) / 1440) . '.' . mt_rand(10524, 99870);
|
|
$amount = ceil(mt_rand(535012, 2009870) / 1440) . '.' . mt_rand(10524, 99870);
|
|
$open = $price;
|
|
$up_or_down = mt_rand(1, 100);
|
|
|
|
$m = intval(date('i', $current));
|
|
$first = array_first($periodsTrend, function ($v, $k) use ($current, $period2_seconds) {
|
|
return $current >= $k && $current < ($k + $period2_seconds);
|
|
});
|
|
if ($first == 1) {
|
|
$value = 60;
|
|
} else {
|
|
$value = 40;
|
|
}
|
|
|
|
// 第二根线也得是跌
|
|
if ($is_sharp == 1 && $current == $start + $seconds) $up_or_down = 100;
|
|
|
|
if ($up_or_down <= $value) {
|
|
// 涨
|
|
$close = mt_rand($price, $price + mt_rand($ups_downs_low, $ups_downs_high));
|
|
$high = mt_rand($close, $close + mt_rand($ups_downs_low, $ups_downs_value));
|
|
$low = mt_rand($close - mt_rand($ups_downs_low, $ups_downs_value), $close);
|
|
} else {
|
|
// 跌
|
|
|
|
$close = mt_rand($price - mt_rand($ups_downs_low, $ups_downs_high), $price);
|
|
$high = mt_rand($close, $close + mt_rand($ups_downs_value, $ups_downs_high));
|
|
$low = mt_rand($close - mt_rand($ups_downs_low, $ups_downs_value), $close);
|
|
}
|
|
|
|
// 大幅拉升开关
|
|
if ($is_sharp == 1 && $current == $start) {
|
|
$amend = $first_target_price * $decimal - $close;
|
|
$close = $first_target_price * $decimal;
|
|
$high = $high + $amend;
|
|
$low = $low + $amend;
|
|
}
|
|
if ($is_sharp == 1) {
|
|
if ($change_rate > 1) {
|
|
$min = $first_target_price * $decimal;
|
|
$max = $target_price * $decimal;
|
|
|
|
if ($close < $min) {
|
|
$amend = $min - $close;
|
|
$close = $min;
|
|
$high = $high + $amend;
|
|
$low = $low + $amend;
|
|
}
|
|
} else {
|
|
$min = $target_price * $decimal;
|
|
$max = $first_target_price * $decimal;
|
|
|
|
if ($close > $max) {
|
|
$amend = $close - $max;
|
|
$close = $max;
|
|
$high = $high - $amend;
|
|
$low = $low - $amend;
|
|
}
|
|
if ($close <= 0) {
|
|
$amend = $min - $close;
|
|
$close = $min;
|
|
$high = $high + $amend;
|
|
$low = $low + $amend;
|
|
}
|
|
}
|
|
}
|
|
|
|
$high = max($open, $close, $high, $low);
|
|
$low = min($open, $close, $high, $low);
|
|
|
|
$open = PriceCalculate($open, '/', $decimal, 5);
|
|
$close = PriceCalculate($close, '/', $decimal, 5);
|
|
$high = PriceCalculate($high, '/', $decimal, 5);
|
|
$low = PriceCalculate($low, '/', $decimal, 5);
|
|
|
|
// dd($open,$close,$high,$low,$prev->toArray());
|
|
DataRao::query()->create([
|
|
'Date' => $current,
|
|
'datetime' => date('Y-m-d H:i:s', $current),
|
|
'Open' => $open,
|
|
'Close' => $close,
|
|
'High' => $high,
|
|
'Low' => $low,
|
|
'LastClose' => $close,
|
|
'Volume' => $volume,
|
|
'Amount' => $amount,
|
|
$flag => 1,
|
|
]);
|
|
|
|
$current += $seconds;
|
|
$kkk++;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// 根据1minK线生成其他周期K线
|
|
public function fake_period_kline($period, $start_date, $end_date)
|
|
{
|
|
$periods = [
|
|
'1min' => [60, 'is_1min'],
|
|
'5min' => [300, 'is_5min'],
|
|
'15min' => [900, 'is_15min'],
|
|
'30min' => [1800, 'is_30min'],
|
|
'60min' => [3600, 'is_1h'],
|
|
'1day' => [86400, 'is_day'],
|
|
'1week' => [604800, 'is_week'],
|
|
'1mon' => [2592000, 'is_month'],
|
|
];
|
|
$seconds = $periods[$period][0] ?? 60;
|
|
$flag = $periods[$period][1] ?? 'is_1min';
|
|
|
|
$start = strtotime($start_date);
|
|
$end = strtotime($end_date);
|
|
$current = $start;
|
|
|
|
if ($period == '1week') {
|
|
$where_start = Carbon::parse($start_date)->startOfWeek(Carbon::SUNDAY)->getTimestamp();
|
|
$where_end = Carbon::parse($start_date)->endOfWeek(Carbon::SUNDAY)->getTimestamp();
|
|
$open = DataRao::query()->where('is_1min', 1)->where('Date', '>=', $where_start)->orderBy('Date', 'asc')->first()['Open'] ?? null;
|
|
$close = DataRao::query()->where('is_1min', 1)->where('Date', '<=', $where_end)->orderBy('Date', 'desc')->first()['Close'] ?? null;
|
|
$high = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->max('High');
|
|
$low = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->min('Low');
|
|
$volume = mt_rand(535012, 2009870) . '.' . mt_rand(10524, 99870);
|
|
$amount = mt_rand(535012, 2009870) . '.' . mt_rand(10524, 99870);
|
|
|
|
DataRao::query()->updateOrCreate(
|
|
[
|
|
'Date' => $where_start,
|
|
$flag => 1,
|
|
],
|
|
[
|
|
'datetime' => date('Y-m-d H:i:s', $where_start),
|
|
'Open' => $open,
|
|
'Close' => $close,
|
|
'High' => $high,
|
|
'Low' => $low,
|
|
'LastClose' => $close,
|
|
'Volume' => $volume,
|
|
'Amount' => $amount,
|
|
]
|
|
);
|
|
} elseif ($period == '1mon') {
|
|
$where_start = Carbon::parse($start_date)->startOfMonth()->getTimestamp();
|
|
$where_end = Carbon::parse($start_date)->endOfMonth()->getTimestamp();
|
|
$open = DataRao::query()->where('is_1min', 1)->where('Date', '>=', $where_start)->orderBy('Date', 'asc')->first()['Open'] ?? null;
|
|
$close = DataRao::query()->where('is_1min', 1)->where('Date', '<=', $where_end)->orderBy('Date', 'desc')->first()['Close'] ?? null;
|
|
$high = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->max('High');
|
|
$low = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->min('Low');
|
|
$volume = mt_rand(535012, 2009870) . '.' . mt_rand(10524, 99870);
|
|
$amount = mt_rand(535012, 2009870) . '.' . mt_rand(10524, 99870);
|
|
|
|
DataRao::query()->updateOrCreate(
|
|
[
|
|
'Date' => $where_start,
|
|
$flag => 1,
|
|
],
|
|
[
|
|
'datetime' => date('Y-m-d H:i:s', $where_start),
|
|
'Open' => $open,
|
|
'Close' => $close,
|
|
'High' => $high,
|
|
'Low' => $low,
|
|
'LastClose' => $close,
|
|
'Volume' => $volume,
|
|
'Amount' => $amount,
|
|
]
|
|
);
|
|
} else {
|
|
$kkk = 1;
|
|
while ($current < $end) {
|
|
echo $current . '--' . $kkk . "\r\n";
|
|
$where_start = $current;
|
|
$where_end = $current + $seconds - 60;
|
|
|
|
$open = DataRao::query()->where('is_1min', 1)->where('Date', $where_start)->value('Open');
|
|
$close = DataRao::query()->where('is_1min', 1)->where('Date', $where_end)->value('Close');
|
|
$high = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->max('High');
|
|
$low = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->min('Low');
|
|
$volume = ceil(mt_rand(535012, 2009870) / (86400 / $seconds)) . '.' . mt_rand(10524, 99870);
|
|
$amount = ceil(mt_rand(535012, 2009870) / (86400 / $seconds)) . '.' . mt_rand(10524, 99870);
|
|
|
|
DataRao::query()->create([
|
|
'Date' => $current,
|
|
'datetime' => date('Y-m-d H:i:s', $current),
|
|
'Open' => $open,
|
|
'Close' => $close,
|
|
'High' => $high,
|
|
'Low' => $low,
|
|
'LastClose' => $close,
|
|
'Volume' => $volume,
|
|
'Amount' => $amount,
|
|
$flag => 1,
|
|
]);
|
|
|
|
$current += $seconds;
|
|
$kkk++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 更新周线和月线
|
|
public function update_kline($period, $start_date)
|
|
{
|
|
$periods = [
|
|
'1min' => [60, 'is_1min'],
|
|
'5min' => [300, 'is_5min'],
|
|
'15min' => [900, 'is_15min'],
|
|
'30min' => [1800, 'is_30min'],
|
|
'60min' => [3600, 'is_1h'],
|
|
'1day' => [86400, 'is_day'],
|
|
'1week' => [604800, 'is_week'],
|
|
'1mon' => [2592000, 'is_month'],
|
|
];
|
|
$seconds = $periods[$period][0] ?? 60;
|
|
$flag = $periods[$period][1] ?? 'is_1min';
|
|
|
|
if ($period == '1week') {
|
|
$where_start = Carbon::parse($start_date)->startOfWeek(Carbon::SUNDAY)->getTimestamp();
|
|
$where_end = Carbon::parse($start_date)->endOfWeek(Carbon::SUNDAY)->getTimestamp();
|
|
$open = DataRao::query()->where('is_1min', 1)->where('Date', '>=', $where_start)->orderBy('Date', 'asc')->first()['Open'] ?? null;
|
|
$close = DataRao::query()->where('is_1min', 1)->where('Date', '<=', $where_end)->orderBy('Date', 'desc')->first()['Close'] ?? null;
|
|
$high = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->max('High');
|
|
$low = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->min('Low');
|
|
$volume = mt_rand(535012, 2009870) . '.' . mt_rand(10524, 99870);
|
|
$amount = mt_rand(535012, 2009870) . '.' . mt_rand(10524, 99870);
|
|
|
|
DataRao::query()->updateOrCreate(
|
|
[
|
|
'Date' => $where_start,
|
|
$flag => 1,
|
|
],
|
|
[
|
|
'datetime' => date('Y-m-d H:i:s', $where_start),
|
|
'Open' => $open,
|
|
'Close' => $close,
|
|
'High' => $high,
|
|
'Low' => $low,
|
|
'LastClose' => $close,
|
|
'Volume' => $volume,
|
|
'Amount' => $amount,
|
|
]
|
|
);
|
|
} elseif ($period == '1mon') {
|
|
$where_start = Carbon::parse($start_date)->startOfMonth()->getTimestamp();
|
|
$where_end = Carbon::parse($start_date)->endOfMonth()->getTimestamp();
|
|
$open = DataRao::query()->where('is_1min', 1)->where('Date', '>=', $where_start)->orderBy('Date', 'asc')->first()['Open'] ?? null;
|
|
$close = DataRao::query()->where('is_1min', 1)->where('Date', '<=', $where_end)->orderBy('Date', 'desc')->first()['Close'] ?? null;
|
|
$high = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->max('High');
|
|
$low = DataRao::query()->where('is_1min', 1)->whereBetween('Date', [$where_start, $where_end])->min('Low');
|
|
$volume = mt_rand(535012, 2009870) . '.' . mt_rand(10524, 99870);
|
|
$amount = mt_rand(535012, 2009870) . '.' . mt_rand(10524, 99870);
|
|
|
|
DataRao::query()->updateOrCreate(
|
|
[
|
|
'Date' => $where_start,
|
|
$flag => 1,
|
|
],
|
|
[
|
|
'datetime' => date('Y-m-d H:i:s', $where_start),
|
|
'Open' => $open,
|
|
'Close' => $close,
|
|
'High' => $high,
|
|
'Low' => $low,
|
|
'LastClose' => $close,
|
|
'Volume' => $volume,
|
|
'Amount' => $amount,
|
|
]
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|