<?php
/**
	* 
	* Start 
	* Create Date: 27 Jan, 2022
	* This module file using for commmonly used method in all controller.
	* Created yogeshwaran.
	* @see no link
	* Last Updated: 29 Jan, 2022
	* End
	* 
*/
	namespace App\Models;
	use CodeIgniter\Model;
	use Binance;
	// $api = new Binance\API($key,$secret,true);
	Class Subbin_Strategy extends Model {

		public function __construct(){
			$this->db = \Config\Database::connect();
			

			$this->common_model = model('CommonModel');
		}

		public function index(){

		}


		public function subbin_strategy(){

			$subbin_strategy_users = $this->db->table('trade_process')->select('uusersid')->where('strategy_mode','2')->distinct()->where('trade_status','1')->get()->getResult();
            $i=0;
			foreach ($subbin_strategy_users as $key => $value) {
				$userid[$i] = $value->uusersid;
				$i++;
			}
			// $userid = explode(',', $userid);


			$userid = array_filter($userid);

			for ($i=0; $i < count($userid); $i++) { 

				$userid_bind_process = $this->db->table('bind_process')->where('uusersid',$userid[$i])->get()->getRow();

				$trade_process_array = $this->db->table('trade_process')->where('uusersid',$userid[$i])->where('trade_status','1')->get()->getResult();

			

				for ($j=0; $j <count($trade_process_array); $j++) { 

					$trade_process = $trade_process_array[$j];

					if ($userid_bind_process && $trade_process && $trade_process->trade_status == '1') {
						$key = $userid_bind_process->api_key;
						$secret = $userid_bind_process->secret_key;
						$api = new Binance\API($key,$secret);

					$ticker = $api->prices($trade_process->pair); // Make sure you have an updated ticker object for this to work
					
					$trade_where = array(
						'uuserid' => $userid[$i],
						'type' => '1',
						'trade_process_id' => $trade_process->id
					);

					$last_buy = $this->db->table('api_trade_history')->where($trade_where)->orderBy('id','DESC')->get()->getRow();

					$last_buy_live_price = $last_buy->live_price;

					$live_price =  $ticker[$trade_process->pair];

					$ticks = $api->candlesticks($trade_process->pair, "15m");
					$res = end($ticks);
					$previous_high_price = $res['close'];

				    echo"<pre>";
					print_r("Last Buy Live Price: ".$last_buy_live_price);
					echo "\n";
					print_r("Current Live Price: ".$live_price);
					echo"</pre>";

						if ($last_buy_live_price > $live_price) {
							
					// normal margin call drop buy function
                        if($last_buy->type == 1)  {  
						$margin_call_drop = $trade_process->margincall_drop;
						$explode_margin_call_drop = explode(',', $margin_call_drop);
						$exploded = array_combine(range(1, count($explode_margin_call_drop)), $explode_margin_call_drop);
						$old_price = '';

					
         
						for ($k=1; $k<=count($exploded); $k++) {

					        $last_buy = $this->db->table('api_trade_history')->where($trade_where)->orderBy('id','DESC')->get()->getRow();
							if ($old_price == '') {
								$old_price = $last_buy->live_price;
							}

							$call_drop_where = array(
								'trade_process_id' => $trade_process->id,
								'uuserid' => $userid[$i],
								'margin_call_drops' => $k,
							);

							$call_drop_where1 = array(
								'trade_process_id' => $trade_process->id,
								'uuserid' => $userid[$i],
								'type' => 2,
								'margin_call_drops' => $k,
								'status' => 0
							);


							$call_drop = $this->db->table('api_trade_history')->where($call_drop_where)->get()->getRow();
						
							

							if($k > 5){
								if($call_drop != ""){
                                      $call_drop_new = $this->db->table('api_trade_history')->where($call_drop_where1)->get()->getRow();
                                      if($call_drop_new){
                                      	$call_drop = "";
                                      }else{
                                      	$call_drop = true;
                                      }
                                     
                                      echo"<pre>";
							echo "second<br>";
							print_r($k." ".$call_drop);
							echo"</pre>";
								}
							}
							
							
                 			if (!$call_drop) {
								$check_percentage = ($old_price - $live_price) / $old_price * 100;
								echo"<pre>";
								print_r("Old price".$old_price);
								print_r("Current Down".$check_percentage);
								print_r("Next call percentage".$k." :".$exploded[$k]);
								echo"</pre>";

								if ($check_percentage >= $exploded[$k]) {

									$explode_buyin_ratio_times = explode(',', $trade_process->buyin_ratio_times);
									$exploded_buy_ratio = array_combine(range(1, count($explode_buyin_ratio_times)), $explode_buyin_ratio_times);

									if($trade_process->open_position_doubled != 'on' || $trade_process->open_position_doubled == '')
										$quantity = 1;
									else
										$quantity = 2;
									$price = $trade_process->first_buy_amount * $quantity;

									$quantity = $price * $exploded_buy_ratio[$k];

									if ($trade_process->margin_call == '1' ) {
										$buy_done = $this->marketbuy($userid[$i],$trade_process->id,$quantity,$k,$api,$trade_process->pair);
										$call_drop_where1 = array(
										'trade_process_id' => $trade_process->id,
										'uuserid' => $userid[$i],
										// 'margin_call_drops' => $k
										);
								
								$call_drop = $this->db->table('api_trade_history')->where($call_drop_where1)->orderBy('id','DESC')->get()->getRow();

								$old_price = $call_drop->live_price;
					
									}
								}
                            break;
							}else{

								$call_drop_where1 = array(
									'trade_process_id' => $trade_process->id,
									'uuserid' => $userid[$i],
									// 'margin_call_drops' => $k
								);
								
								$call_drop = $this->db->table('api_trade_history')->where($call_drop_where1)->orderBy('id','DESC')->get()->getRow();

								$old_price = $call_drop->live_price;
							}
						if($buy_done)
						break;
						}

					}
				else if($last_buy->type == 2){
					 $trade = $this->db->table('trade_process')->where("id",$trade_process->id)->get()->getRow();
			        if($previous_high_price < $live_price && $trade->flag_buy != 1){
                  		$sell_record_update = $this->db->table('trade_process')->set('flag_buy','1')->where("id",$trade_process->id)->update();
                  		$buy_in_callback_temp = $live_price * $trade_process->buyin_callback / 100;
					$buy_in_callback_temp = $buy_in_callback_temp + $live_price;
					$sell_record_update1 = $this->db->table('trade_process')->set('buy_limit',$buy_in_callback_temp)->where("id",$trade_process->id)->update();
                  	}

					 $trade = $this->db->table('trade_process')->where("id",$trade_process->id)->get()->getRow();
                  	 
                  	  echo"<pre>";
                  	  print_r($trade);
                  	  echo"</pre>";
                  	  // exit();
                  	


                  	if($trade->flag_buy == 1) {

                  	$buy_in_callback_temp = $trade->buy_limit;

					echo"<pre>";
					print_r("buy in call back price".$buy_in_callback_temp);
					echo"</pre>";

					if($buy_in_callback_temp <= $live_price){

						if($trade_process->open_position_doubled != 'on' || $trade_process->open_position_doubled == ''){
								$quantity = 1;
						}
						else
						{
								$quantity = 2;
						}
								$price = $trade_process->first_buy_amount * $quantity;
								$quantity = $price ;

								echo"<pre>";
								print_r($exploded_buy_ratio[$k]);
								echo "\n";
								print_r($quantity);
								echo "\n";
								print_r($trade_process->margin_call);
								echo"</pre>";
								// exit();

								$ticker = $api->prices(); // Make sure you have an updated ticker object for this to work
								$balances = $api->balances($ticker);
								$total_asset = $balances['USDT']['available'];
								$k = "";

										if($quantity >= 11 && $total_asset > $quantity)
										$buy_result = $this->marketbuy($userid[$i],$trade_process->id,$quantity,$k,$api,$trade_process->pair);
										$call_drop_where1 = array(
										'trade_process_id' => $trade_process->id,
										'uuserid' => $userid[$i],
										// 'margin_call_drops' => $k
										);
								
								$call_drop = $this->db->table('api_trade_history')->where($call_drop_where1)->orderBy('id','DESC')->get()->getRow();

								$old_price = $call_drop->live_price;
								
					            }
                  	}
				}
						}else{
												if($last_buy->type == 2){  //after take profit call market up buyincallback call
					$buy_in_callback_temp = $last_buy->live_price * $trade_process->buyin_callback / 100;
					$buy_in_callback_temp = $buy_in_callback_temp + $last_buy->live_price;

					echo"<pre>";
					print_r("sell ".$buy_in_callback_temp);
					print_r("live_price ".$live_price);
					echo"</pre>";

					if($buy_in_callback_temp <= $live_price){

						if($trade_process->open_position_doubled != 'on' || $trade_process->open_position_doubled == '')
								$quantity = 1;
						else
								$quantity = 2;
								$price = $trade_process->first_buy_amount * $quantity;
								$quantity = $price ;

								echo"<pre>";
								print_r($exploded_buy_ratio[$k]);
								echo "\n";
								print_r($quantity);
								echo "\n";
								print_r($trade_process->margin_call);
								echo"</pre>";
								// exit();

								$ticker = $api->prices(); // Make sure you have an updated ticker object for this to work
								$balances = $api->balances($ticker);
								$total_asset = $balances['USDT']['available'];

								echo"<pre>";
								print_r("profit buy");
								echo"</pre>";

								$k = "";
								

										if($quantity >= 11 && $total_asset > $quantity)
										$buy_result = $this->marketbuy($userid[$i],$trade_process->id,$quantity,$k,$api,$trade_process->pair);
										$call_drop_where1 = array(
										'trade_process_id' => $trade_process->id,
										'uuserid' => $userid[$i],
										// 'margin_call_drops' => $k
										);
								
								$call_drop = $this->db->table('api_trade_history')->where($call_drop_where1)->orderBy('id','DESC')->get()->getRow();

								$old_price = $call_drop->live_price;
								
								
					            }

				}
					    else{ 

							$trade_where = array(
								'uuserid' => $userid[$i],
								'type' => '1',
								'trade_process_id' => $trade_process->id,
								'margin_call_drops <=' => '4',
								'status' => 0
							);

							$subbin_trade_where = array(
								'uuserid' => $userid[$i],
								'type' => '1',
								'trade_process_id' => $trade_process->id,
								'margin_call_drops >' => '4',
								'status' => 0
							);

							$profit_where = array(
								'uuserid' => $userid[$i],
								'type' => '3',
								'trade_process_id' => $trade_process->id,
								'status' => 0
							);
         
							$buy_records = $this->db->table('api_trade_history')->selectAvg('live_price')->where($trade_where)->where('margin_call_drops <=',4)->orderBy('id','DESC')->get()->getRow();

							$subbin_buy_records = $this->db->table('api_trade_history')->where($subbin_trade_where)->where('margin_call_drops >',4)->orderBy('id','DESC')->get()->getResult();

	                        $avgProfit = $this->db->table('api_trade_history')->selectSum('avg_price')->where($trade_where)->orderBy('id','DESC')->get()->getRow();



							$margin_call_drop = $trade_process->sub_position;

							$explode_margin_call_drop = explode(',', $margin_call_drop);
							$exploded = array_combine(range(1, count($explode_margin_call_drop)), $explode_margin_call_drop);


						if($subbin_buy_records) {

							foreach ($subbin_buy_records as $key => $value) {

						    $buyprice[$value->margin_call_drops] = $value->live_price;
							
							$avg_price = $value->live_price * $exploded[$value->margin_call_drops - 4] / 100;
 
							$max_increase_price_sub[$value->margin_call_drops] = $value->live_price + $avg_price ;
							
						$max_increase_price_sub[$value->margin_call_drops] = round($max_increase_price_sub[$value->margin_call_drops],2);

							$max_down_percentage = $max_increase_price_sub[$value->margin_call_drops] * $trade_process->sub_position_callback / 100;

							$max_down_price_sub[$value->margin_call_drops] = $max_increase_price_sub[$value->margin_call_drops] - $max_down_percentage;

							$max_down_price_sub[$value->margin_call_drops] = round($max_down_price_sub[$value->margin_call_drops],2);


						}
						}else{
								if($buy_records->live_price != '' || $buy_records->live_price > 0) {

							$avg_price = $buy_records->live_price * $trade_process->whole_profit_ratio / 100;

							$avg_price = ($avg_price - $avgProfit);
 
							$max_increase_price = $buy_records->live_price + $avg_price;
							
							$max_increase_price = round($max_increase_price,2);

							$max_down_percentage = $max_increase_price * $trade_process->whole_profit_callback / 100;

							$max_down_price = $max_increase_price - $max_down_percentage;

							$max_down_price = round($max_down_price,2);

							// $live_price = $max_increase_price;
						}
						}

				
							if(!empty($max_increase_price) || $max_increase_price > 0){
							if ($live_price >= $max_increase_price) {
								
								$buyed_quantity = $this->db->table('api_trade_history')->selectSum('received_amount')->where($trade_where)->orderBy('id','DESC')->get()->getRow();


								$quantity = round($buyed_quantity->received_amount,2);
								$price = $max_increase_price; // Try to sell it for 0.5 btc
								$stopPrice = $max_down_price; // Sell immediately if price goes below 0.4 btc

								$margin_call = "";
								
				$this->take_profit($userid[$i],$trade_process->id,$quantity,$price,$stopPrice,$api,$trade_process->pair,0,$margin_call);

								if ($trade_process->strategy_type != 'Cycle Strategy') {
									
									$this->db->table('trade_process')->set('trade_status','2')->where('id',$trade_process->id)->update();
								}

											$margin_call_drop = $trade_process->margincall_drop;

								$explode_margin_call_drop = explode(',', $margin_call_drop);
								$exploded = array_combine(range(1, count($explode_margin_call_drop)), $explode_margin_call_drop);

								$last_call_drop = array_key_last($exploded);

								$call_drop_where = array(
									'trade_process_id' => $trade_process->id,
									'uuserid' => $userid[$i],
									'margin_call_drops' => $last_call_drop
								);

								$call_drop_check = $this->db->table('api_trade_history')->where($call_drop_where)->get()->getRow();

								if ($call_drop_check != '') {
									$this->db->table('trade_process')->set('trade_status','2')->where('id',$trade_process->id)->update();
								}

							}
						}

			

							if(!empty($max_increase_price_sub)){
								foreach ($max_increase_price_sub as $key => $value) {
									
									if ($live_price >= $value) {
								
								$buyed_quantity = $this->db->table('api_trade_history')->select('received_amount')->where($subbin_trade_where)->where('margin_call_drops',$key)->orderBy('id','DESC')->get()->getRow();

								


								$quantity = round($buyed_quantity->received_amount,2);
								$price = $max_increase_price_sub[$key]; // Try to sell it for 0.5 btc
								$stopPrice = $max_down_price_sub[$key]; // Sell immediately if price goes below 0.4 btc

								$startPrice = $buyprice[$key];

								
								
						$this->take_profit($userid[$i],$trade_process->id,$quantity,$price,$stopPrice,$api,$trade_process->pair,1,$key,$startPrice);

								if ($trade_process->strategy_type != 'Cycle Strategy') {

									$this->db->table('trade_process')->set('trade_status','2')->where('id',$trade_process->id)->update();

								}
							}
								}
							}
						}

						}
					}
			}
		}

	}

	public function marketbuy($userid,$trade_process_id,$quantity,$margin_call_drops,$api,$pair){	
		// print_r($api);
		// exit();
		$flags['isQuoteOrder'] = true;
				// $order = $api->buy("BNBUSDT", "10",0,"MARKET",$flags);
				// $order = $api->marketQuoteSell("BNBUSDT", "100",$flags);
		$order = $api->marketQuoteBuy($pair, $quantity,$flags);
		$order_history = array(
			'pair' => $order['symbol'],
			'order_id' => $order['orderId'],
			'trade_process_id' => $trade_process_id,
			'uuserid' => $userid,
			'type' => '1',
			'quantity' => $order['cummulativeQuoteQty'],
			' original_quantity' => $quantity,
			'time' => $order['transactTime'],
			'received_amount' => $order['executedQty'],
			'live_price' => $order['fills'][0]['price'],
			'margin_call_drops' => $margin_call_drops
		);

		if($order){
			if($margin_call_drops >= 5)
			    $buy_record_next = $this->db->table('api_trade_history')->set('status','1')->where("id",$trade_process_id)->where("type",2)->where("margin_call_drops",$margin_call_drops)->update();
		}

		$this->db->table('api_trade_history')->insert($order_history);

		return true;
	}

	public function marketsell($userid,$trade_process_id,$quantity,$margin_call_drops,$api,$pair){

		$flags['isQuoteOrder'] = true;

		$order = $api->marketQuoteSell($trade_process->pair,$quantity);

		$order_history = array(
			'pair' => $order['symbol'],
			'order_id' => $order['orderId'],
			'trade_process_id' => $trade_process_id,
			'uuserid' => $userid,
			'type' => '2',
			'quantity' => $order['cummulativeQuoteQty'],
			' original_quantity' => $quantity,
			'time' => $order['transactTime'],
			'received_amount' => $order['executedQty'],
			'live_price' => $order['fills'][0]['price'],
			'margin_call_drops' => $margin_call_drops
		);

		$this->db->table('api_trade_history')->insert($order_history);
		return true;

	}


	public function take_profit($userid,$trade_process_id,$quantity,$price,$stopPrice,$api,$pair,$avg_price,$subsell_status,$margin_call,$startPrice=""){
		// $flags['isQuoteOrder'] = true;
 
		// $order = $api->marketQuoteSell($pair,$quantity);
		$order = $api->sell($pair,$quantity,0,"MARKET");

		echo"<pre>";
		print_r($order);
		echo"</pre>";
		

		// $order = $api->sell($pair, $quantity, $price, "TAKE_PROFIT_LIMIT", ["stopPrice"=>$stopPrice]);
		
        if($order) { 
        	$buy_record_update = $this->db->table('trade_process')->set('flag','0')->where("id",$trade_process_id)->update();
		$trade_process = $this->db->table('trade_process')->where('uusersid',$userid)->where('trade_status','1')->where('id',$trade_process_id)->get()->getRow();

$trade_process = $this->db->table('trade_process')->where('uusersid',$userid)->where('trade_status','1')->where('id',$trade_process_id)->get()->getRow();

		$order_history = array(
			'pair' => $pair,
			'order_id' => $order['orderId'],
			'trade_process_id' => $trade_process_id,
			'uuserid' => $userid,
			'type' => '2',
			'quantity' => $quantity,
			' original_quantity' => '',
			'time' => $order['transactTime'],
			'received_amount' => '',
			'live_price' => $stopPrice,
			'margin_call_drops' => $margin_call,
			'avg_price' => $stopPrice - $startPrice,
			'status' => 0,
			'strategy_mode' => $trade_process->strategy_mode,
			'subsell_status' => $subsell_status
		);

		$this->db->table('api_trade_history')->insert($order_history);

		if($order_history['avg_price'] > 0 && $subsell_status == 1){
               $profit_history = array(
			'pair' => $pair,
			'order_id' => $order['orderId'],
			'trade_process_id' => $trade_process_id,
			'uuserid' => $userid,
			'type' => '3',
			'quantity' => $quantity,
			' original_quantity' => '',
			'time' => $order['transactTime'],
			'received_amount' => '',
			'live_price' => $stopPrice,
			'margin_call_drops' => $margin_call,
			'avg_price' => $stopPrice - $startPrice,
			'status' => 0,
			'strategy_mode' => $trade_process->strategy_mode,
			'subsell_status' => $subsell_status
		);
               $this->db->table('api_trade_history')->insert($profit_history);
		$return = true;
	}else{
		$return = false;
	}
}

		return $return;
	}

	// public function take_profit($userid,$trade_process_id,$quantity,$price,$stopPrice,$api,$pair,$subsell_status,$margin_call,$startPrice){

	// 	$order = $api->sell($pair, $quantity, $price, "STOP_LOSS_LIMIT", ["stopPrice"=>$stopPrice]);

	// 	$trade_process = $this->db->table('trade_process')->where('uusersid',$userid)->where('trade_status','1')->where('id',$trade_process_id)->get()->getRow();

	// 	$order_history = array(
	// 		'pair' => $pair,
	// 		'order_id' => $order['orderId'],
	// 		'trade_process_id' => $trade_process_id,
	// 		'uuserid' => $userid,
	// 		'type' => '2',
	// 		'quantity' => $quantity,
	// 		' original_quantity' => '',
	// 		'time' => $order['transactTime'],
	// 		'received_amount' => '',
	// 		'live_price' => $stopPrice,
	// 		'margin_call_drops' => $margin_call,
	// 		'avg_price' => $stopPrice - $startPrice,
	// 		'status' => 0,
	// 		'strategy_mode' => $trade_process->strategy_mode,
	// 		'subsell_status' => $subsell_status
	// 	);

	// 	$this->db->table('api_trade_history')->insert($order_history);

	// 	if($order_history['avg_price'] > 0 && $subsell_status == 1){
 //               $profit_history = array(
	// 		'pair' => $pair,
	// 		'order_id' => $order['orderId'],
	// 		'trade_process_id' => $trade_process_id,
	// 		'uuserid' => $userid,
	// 		'type' => '3',
	// 		'quantity' => $quantity,
	// 		' original_quantity' => '',
	// 		'time' => $order['transactTime'],
	// 		'received_amount' => '',
	// 		'live_price' => $stopPrice,
	// 		'margin_call_drops' => $margin_call,
	// 		'avg_price' => $stopPrice - $startPrice,
	// 		'status' => 0,
	// 		'strategy_mode' => $trade_process->strategy_mode,
	// 		'subsell_status' => $subsell_status
	// 	);
 //               $this->db->table('api_trade_history')->insert($profit_history);

	// 	}
	// 	return true;
	// }

}