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

		public function __construct() {
			$this->db = \Config\Database::connect();
            $this->session = session();
			$this->common_model = model('CommonModel');
		}

		public function index(){

		}


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

			// $userid[0] = 150;

			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')->where('strategy_mode','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
    					
    					$data_binance = json_decode(@file_get_contents('https://revotechbot.com/trading_pairs.json'), true);
    					$live_price='';
                        foreach ($data_binance as $datas) 
                        {
                                if ($datas['symbol'] == $trade_process->pair) 
                                {
                                    $live_price=$datas['lastPrice'];
                                   break;   
                                }
                                
                        }
					
    					$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;

					$this->session->set('cron_pair',strtolower($trade_process->pair));

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

					$dummy_update = array(
                       "pair" => $trade_process->pair,
                       "price" => $live_price,
                       "updated_time" => time()
					);

					$this->db->table('live_price')->insert($dummy_update);


                        echo '<script type="text/javascript">acted()</script>';
                        echo '<script type="text/javascript">acted1()</script>';
                        
                    $ticks = $api->candlesticks($trade_process->pair, "5m");
                    $res = end($ticks);
                    $previous_high_price = $res['high'];
					print_r("Last Buy Price ".$last_buy_live_price);
					echo "<br>";
					print_r("cron_pair ".$_SESSION['cron_pair']);
					echo "<br>";
					
					print_r("previous_high_price ".$previous_high_price);
					echo "<br>";
					print_r("Live Price ".$live_price);
					
					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 = $this->db->table('api_trade_history')->where($call_drop_where)->get()->getRow();
                 			    if(!$call_drop) 
                 			    {
                                    $check_percentage = ($old_price - $live_price) / $old_price * 100 ;
                                    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' ) 
    									{
    										$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)->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)->get()->getRow();
    
    								$old_price = $call_drop->live_price;
							}
						}
							
	
					}
				    else if($last_buy->type == 2)
				    {
			            if($previous_high_price < $live_price)
			            {
                  		    $sell_record_update = $this->db->table('trade_process')->set('flag_buy','1')->where("id",$trade_process->id)->update();
                  	    }
                        $trade = $this->db->table('trade_process')->where("id",$trade_process->id)->get()->getRow();
                        if($trade->flag_buy == 1) 
                        {
        
                          	$buy_in_callback_temp = $live_price * $trade_process->buyin_callback / 100;
					        $buy_in_callback_temp = $buy_in_callback_temp + $live_price;
                            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 =''; // Make sure you have an updated ticker object for this to work
								$balances = $api->balances($ticker);
								$total_asset = $balances['USDT']['available'];
                                $total_asset=str_replace(',','',$total_asset);
                                
								if ($trade_process->margin_call == '1' ) 
								{
									  if($total_asset >= $quantity)
									  {
									    	//$buy_result = $this->marketbuy($userid[$i],$trade_process->id,$quantity,$k,$api,$trade_process->pair);
										    $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)->get()->getRow();
                                        $old_price = $call_drop->live_price;
									    }
									    else
									    {
									        #notify
									    }
					                }
                               }
                  	}
				}
			}
			else
			{
                if($last_buy->type == 2)
                {
                    $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;

					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 = ''; // Make sure you have an updated ticker object for this to work
								$balances = $api->balances($ticker);
								$total_asset = $balances['USDT']['available'];
								$total_asset=str_replace(',','',$total_asset);
								

									if ($trade_process->margin_call == '1' ) 
									{
										if($total_asset >= $quantity)
										{
										    $buy_result = $this->marketbuy($userid[$i],$trade_process->id,$quantity,$k,$api,$trade_process->pair);
										    //$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)->get()->getRow();
        
        								$old_price = $call_drop->live_price;
									    }
									    else
									    {
									        #notifu
									    }
									    
					                }
					            }           

				}
				else { 

                        $trade_where = array(
							'uuserid' => $userid[$i],
							'type' => '1',
							'status' => 0,
							'trade_process_id' => $trade_process->id,
						);
                        $buy_records = $this->db->table('api_trade_history')->selectAvg('live_price')->where($trade_where)->orderBy('id','DESC')->get()->getRow();
                        if($buy_records->live_price > 0 && $buy_records != '') 
                        {

							$avg_price = round($buy_records->live_price,8) * $trade_process->whole_profit_ratio / 100;
                        	$max_increase_price = $buy_records->live_price + $avg_price ;
							$max_increase_price = round($max_increase_price,8);
                        	$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,8);
                            echo"<pre>";
							print_r("MAX ".$max_increase_price);
							print_r("LIVE PRICE ".$live_price);
							print_r("MAX DOWN  ".$max_down_price);
							echo"</pre>";
							// exit();
                            // $max_increase_price = 417.5;
							// $max_down_price = 417.5;
                            
                            if ($live_price >= $max_increase_price) {
                            	$sell_record_update = $this->db->table('trade_process')->set('flag','1')->where("id",$trade_process->id)->update();
                            }

                            $trade = $this->db->table('trade_process')->where("id",$trade_process->id)->get()->getRow();
							if ($trade->flag == 1) {

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


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

								
								
								$quantity = number_format($buyed_quantity->received_amount,1);
								$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
								// $quantity = 0.07;

								echo"<pre>";
								print_r("MAX ".$max_increase_price);
								print_r("LIVE PRICE ".$live_price);
								print_r("MAX DOWN  ".$max_down_price);
								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[substr($trade->pair,0,-4)]['available'];

								
							
								
								if($max_down_price == $live_price){
									if(!empty($quantity) && $total_asset >= $quantity)
								           $result = $this->take_profit($userid[$i],$trade_process->id,$quantity,$price,$live_price,$api,$trade_process->pair,$buy_records->live_price);
								    else
								    	$result = 0;
								} else if($live_price > $avg_price && $max_down_price >= $live_price){
									if(!empty($quantity) && $total_asset >= $quantity)
                                        $result = $this->take_profit($userid[$i],$trade_process->id,$quantity,$price,$live_price,$api,$trade_process->pair,$buy_records->live_price);
                                    else
                                    	$result = 0;
								}

							
							

							if($result)
									$buy_record_update = $this->db->table('api_trade_history')->set('status','1')->where($trade_where)->update();

							if ($trade_process->strategy_type != 'Cycle Strategy' && $result) {
									$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 != '') {
									if($result)
									$this->db->table('trade_process')->set('trade_status','2')->where('id',$trade_process->id)->update();
								}
								

								// return true;
							}
						}
					}
				}

				}
				$this->session->remove('live_price');
				$this->session->remove('cron_pair');
					$this->session->remove('high_price');
					$this->session->remove('previous_high_price');
			}
		}

	}




	public function marketbuy($userid,$trade_process_id,$quantity,$margin_call_drops,$api,$pair){
        print_r("buy pair".$pair);
		print_r("buy amount".$quantity);
		// print_r($api);
		// exit();
		$flags['isQuoteOrder'] = true;

		if($quantity < 11){
			$quantity = 11;
		}
				// $order = $api->buy("BNBUSDT", "10",0,"MARKET",$flags);
				// $order = $api->marketQuoteSell("BNBUSDT", "100",$flags);
		$order = $api->marketQuoteBuy($pair, $quantity,$flags);
		echo"<pre>";
		print_r($order);
		echo"</pre>";

		if($order) { 
        $buy_record_update = $this->db->table('trade_process')->set('flag','0')->where("id",$trade_process_id)->update();
         $buy_record_update1 = $this->db->table('trade_process')->set('flag_buy','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();

		$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,
			'strategy_mode' => $trade_process->strategy_mode,
			'status' => 0,
		);

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

		return true;
	}else
	   return false;
	}

	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);
		$buy_record_update = $this->db->table('trade_process')->set('flag','0')->where("id",$trade_process_id)->update();
		return true;

	}

	public function take_profit($userid,$trade_process_id,$quantity,$price,$stopPrice,$api,$pair,$avg_price){

		print_r("sell pair".$pair);
		print_r("sell amount".$quantity);
		// die;

		// $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();
         $buy_record_update1 = $this->db->table('trade_process')->set('flag_buy','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();

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

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

		$this->db->table('api_trade_history')->insert($order_history);
		$return = true;
	}else{
		$return = false;
	}

		return $return;
	}

}
?>
<script type="text/javascript" src="<?php echo base_url();?>/assets/js/bundle.js"></script>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>


<script type="text/javascript">

  function acted(){ 
  const ws = new WebSocket('wss://stream.binance.com:9443/ws/<?php echo $_SESSION['cron_pair'];?>@miniTicker');

  console.log(ws);
ws.onmessage = function (event) {
    var data = JSON.parse(event.data);
    console.log("live price "+data['c']);
    console.log("high price "+data['h']);
     $.ajax({
      'method': 'POST',
      'url': '<?php echo base_url("/update_live_price");?>',
      data:{'price':data['c'],'high_price':data['h']},
      success:function(msg)
      {
        console.log(msg);
      }
      });
}

}

 function acted1(){
  const ws = new WebSocket('wss://stream.binance.com:9443/ws/<?php echo $_SESSION['cron_pair'];?>@kline_5m');

  console.log(ws);
ws.onmessage = function (event) {
    var data = JSON.parse(event.data);
    console.log("previous_high_price "+data['k']['h']);
    // console.log(data['c']);
     $.ajax({
      'method': 'POST',
      'url': '<?php echo base_url("/update_live_price");?>',
      data:{'previous_high_price':data['k']['h']},
      success:function(msg)
      {
      	console.log(msg);
      }
      });
}

}
setInterval(acted,120000);
setInterval(acted1,120000);
</script>

