Location: PHPKode > projects > Uniform Price Markets > UPmarkets-0.1.0/inc.d/f_pricing_commit.inc
<?php
// (C) 2000 LinuxFutures.com, Inc.
// 
// Part of UPmarkets - the software behind the LinuxFutures game site
//                     visit www.LinuxFutures.com to play
//
//  We are making the software available to you under the GNU General Public License,
//  a copy of which should accompany this software in the file LICENSE.
//
// A web-based copy of the LICENSE is located at http://www.gnu.org/copyleft/gpl.txt
//
// While there is no charge for using this software, there are important restrictions.
//
// This LICENSE does not allow, in general, proprietary modifications or proprietary derivative works.
// If you base new commercial products on our work, great, but you have to give them away just as we did.
//
// This software carries ABSOLUTELY NO WARRANTY. It is offered AS-IS, and may not work at all
//  or may have harmful or hazardous side effects.
//
// 
// -------------------- what this file does ---------------------
// provides function pricing_commit($sym, $pricing_array)
// also provides helper functions pricing_settle_* used by pricing_commit
// commits a pricing to the database
//      updates tables pricings, pricings_recent, quotes_filled, and ledgers 
//
// THIS FUNCTION SHOULD BE CALLED WITH _AT LEAST_ the locks mentioned below
//  LOCK TABLES ledgers, partners, pricings, pricings_latest, quotes, quotes_filled WRITE policies READ;
//
// Pricing array is expected to be from f_economy_uniform_pricing_array, or some other
//  function that returns the same data. Fields used: price, quantity, partial, partialQ
//
// Important: usually, after running pricing_commit, you'll probably want to run 
//             users_check_bankruptcy and users_check_panic
//
//

require('inc.d/f_pricing_sanity.inc');

function pricing_settle_all($posted, $buy_sell_none, $price, $com, $where) { 
  global $db_link;
 
  $ins   = "INSERT INTO quotes_filled (pricing_posted,quote_posted,fill_type,fill_quantity) ";

  $bs    = " SELECT ";
  $bs   .= "'".$posted."' as pricing_posted, ";
  $bs   .= "posted as quote_posted, ";
  $bs   .= "'".$buy_sell_none."' as fill_type, ";
  $bs   .= "quantity as fill_quantity ";
  $bs   .= "FROM quotes ";

  $none  = " SELECT ";
  $none .= "'".$posted."' as pricing_posted, ";
  $none .= "posted as quote_posted, ";
  $none .= "'none' as fill_type, ";
  $none .= "0 as fill_quantity ";
  $none .= "FROM quotes ";

  if (strcmp("none",$buy_sell_none) == 0){ 
	$sql = $ins.$none.$where.";"; 
  } else {
	$sql = $ins.$bs.$where.";";
  }

  $r = mysql_query($sql, $db_link);
  mysql_error_sanity("f_pricing_commit pricing_settle_all insert quotes_filled");

  if (strcmp("none", $buy_sell_none) == 0) { return; }  // all done for none's.
  
  $ins = "INSERT INTO ledgers (userid,symbolid,amount,posted,why) ";
  
  $buy =  " SELECT ";
  $buy .= "userid, ";
  $buy .= "symbolid, ";
  $buy .= "quantity as amount, ";
  $buy .= "'".$posted."' as posted, ";
  $buy .= "'your buy executed' as why "; 
  $buy .= "FROM quotes ";

  $sell =  " SELECT ";
  $sell .= "userid, ";
  $sell .= "symbolid, ";
  $sell .= "(-1 * quantity) as amount, ";
  $sell .= "'".$posted."' as posted, ";
  $sell .= "'your sell executed' as why ";
  $sell .= "FROM quotes ";

  if (strcmp("buy", $buy_sell_none) == 0) { 
	$sql = $ins.$buy.$where.";";
  } elseif (strcmp("sell",$buy_sell_none) == 0) { 
	$sql = $ins.$sell.$where.";";
  } else { exit; }

  $r = mysql_query($sql, $db_link);
  mysql_error_sanity("f_pricing_commit pricing_settle_all insert ledgers symbol");


// now move the payment

  $ins = "INSERT INTO ledgers (userid,symbolid,amount,posted,why) ";
  
  $buy =  " SELECT ";
  $buy .= "userid, ";
  $buy .= "1 as symbolid, ";   		// symbolid=1 reserved for money, Tux Nuggets, etc.
  $buy .= "(".(-$price)." * quantity ) as amount, ";
  $buy .= "'".$posted."' as posted, ";
  $buy .= "'your buy executed' as why "; 
  $buy .= "FROM quotes ";

  $sell =  " SELECT ";
  $sell .= "userid, ";
  $sell .= "1 as symbolid, ";		// symbolid=1 reserved for monet, Tux Nuggets, etc.
  $sell .= "(".$price." * quantity) as amount, ";
  $sell .= "'".$posted."' as posted, ";
  $sell .= "'your sell executed' as why ";
  $sell .= "FROM quotes ";

  if (strcmp("buy", $buy_sell_none) == 0) { 
	$sql = $ins.$buy.$where.";";
  } elseif (strcmp("sell",$buy_sell_none) == 0) { 
	$sql = $ins.$sell.$where.";";
  }

  $r = mysql_query($sql, $db_link);
  mysql_error_sanity("f_pricing_commit pricing_settle_all insert ledgers payment");

// now pay the commission

  $acom = $price * $com;

  $pay =  " SELECT ";
  $pay .= "userid, ";
  $pay .= "1 as symbolid, ";   		// symbolid=1 reserved for money, Tux Nuggets, etc.
  $pay .= "-FLOOR( ".$acom." * quantity / 100) as amount, ";
  $pay .= "'".$posted."' as posted, ";
  $pay .= "'commission' as why "; 
  $pay .= "FROM quotes ";

  $r = mysql_query($ins.$pay.$where.";", $db_link);
  mysql_error_sanity("f_pricing_commit pricing_settle_all insert ledgers commission");
 

}


function pricing_settle_one($posted,$buy_sell_none,$price,$com,$quote) {
  global $db_link;


  if (strcmp($buy_sell_none,"buy") == 0) { 
	$cashflowsign = -1; 
   } elseif (strcmp($buy_sell_none,"sell") == 0) { 
	$cashflowsign = 1;
   } else { 
	echo "bad parms f_pricing_commit pricing_settle_one"; exit; 
  }

  $fill_type = $buy_sell_none;

  $ins = "INSERT INTO quotes_filled (pricing_posted,quote_posted,fill_type,fill_quantity) ";
  $ins .= " VALUES ('".$posted."','".$quote["posted"]."','".$fill_type."',".$quote["quantity"].");"; 

  mysql_query($ins, $db_link);
  mysql_error_sanity("f_pricing_commit.inc settle_one quotes ");
  

  $ins = "INSERT INTO ledgers (userid,symbolid,amount,posted,why) ";
  $ins .= " VALUES (";
  $ins  .= $quote["userid"].",";  
  $ins .=  $quote["symbolid"].",";
  $ins .=  (-1 * $cashflowsign * $quote["quantity"]).",";
  $ins .=  "'".$posted."',";
  $ins .= "'".$buy_sell_none." executed'";
  $ins .= ");";

  mysql_query($ins, $db_link);
  mysql_error_sanity("f_pricing_commit.inc settle_one ledgers symbol ");


  $ins = "INSERT INTO ledgers (userid,symbolid,amount,posted,why) ";
  $ins .= " VALUES (";
  $ins  .= $quote["userid"].",";  
  $ins .=  " '1' ,";
  $ins .=  ($cashflowsign * $price * $quote["quantity"]).",";
  $ins .=  "'".$posted."',";
  $ins .= "'".$buy_sell_none." executed'";
  $ins .= ");";

  mysql_query($ins, $db_link);
  mysql_error_sanity("f_pricing_commit.inc settle_one ledgers money ");

// pay the commission

  $ins = "INSERT INTO ledgers (userid,symbolid,amount,posted,why) ";
  $ins .= " VALUES (";
  $ins .=  $quote["userid"].",";  
  $ins .=  " '1' ,";
  $ins .=  -floor(($price.$com.$quote["quantity"])/100).",";
  $ins .=  $posted.",";
  $ins .= "'".$buy_sell_none." executed'";
  $ins .= ");";


}

function pricing_settle_limitQ($posted, $buy_sell, $price, $com, $where, $limitq) {
  global $db_link;


  $sel   = "SELECT posted, symbolid, userid, quantity FROM quotes ";
  $order = " ORDER BY posted ASC;";  

  $r = mysql_query($sel.$where.$order, $db_link);

  $number_of_rows = mysql_num_rows($r);

// find the quote that gets partially filled

  for( $i=0; ( ($i < $number_of_rows) && ($limitq > 0) ); $i++) { 	
	$quote = mysql_fetch_array($r);
	if ($limitq < $quote["quantity"]){ $fillq = $limitq; }  // fillq is the quantity to fill from this quote.
	$limitq -= $quote["quantity"];  	
  }

  mysql_free_result($r);

  $quote["quantity"] = $fillq;
 
  pricing_settle_one($posted,$buy_sell,$price,$com,$quote);  // settle the partial fill

  // the priority rule for partial fills at a constant price is first come, first served.
  // thus everyone earlier than the partially filled quote gets to trade
  // and  no one whose quote was posted later than the partially filled quote.

  $higher = " AND posted < '".$quote["posted"]."' ";
  $lower  = " AND posted > '".$quote["posted"]."' ";

  pricing_settle_all($posted, $buy_sell, $price, $com, $where.$higher);
  pricing_settle_all($posted, "none",    $price, $com, $where.$lower);

}

function pricing_commit($sym="0", $pricing_array, $commentary="-", $commentary_by="0") {
  global $db_link;

  $symbolid = (int) $sym; if ($symbolid <= 0) { exit; }

  if ($pricing_array["quantity"] <= 0) { return(0); }

  $r      = mysql_query("select now() as now;", $db_link);
  mysql_error_sanity("f_pricing_commit now() ");
  $posted = addslashes(mysql_result($r,0,0));
  mysql_free_result($r);

  $policy   = policy_array($symbolid);
  $com      = $policy["commission"];  if ($com > 5){ $com = 5; }

  $price    = $pricing_array["price"];
  $partial  = $pricing_array["partial"];
  $partialQ = $pricing_array["partialQ"];

  $where = " WHERE active=1 AND symbolid=".$symbolid." ";
  $buygt  = " AND buy_price > ".$price." ";
  $buyeq  = " AND buy_price = ".$price." ";
  $buylt  = " AND buy_price < ".$price." ";
  $selllt = " AND sell_price < ".$price." ";
  $selleq = " AND sell_price = ".$price." ";
  $sellgt = " AND sell_price > ".$price." ";

// these always get filled

  pricing_settle_all($posted,"buy",$price,$com,$where.$buygt);
  pricing_settle_all($posted,"sell",$price,$com,$where.$selllt);

// these never get filled
  pricing_settle_all($posted,"none",$price,$com,$where.$buylt.$sellgt); 
// note that this is an AND, not an OR.  we need AND to avoid duplicates

// for the equals cases, we need to check the partial fill indicator
// and if it is present, use limitqs.

  if ($partial) { 
    if (strcmp("D",$partial) == 0) {
	pricing_settle_limitQ($posted,"buy",$price,$com,$where.$buyeq,$partialQ);
	pricing_settle_all($posted,"sell",$price,$com,$where.$selleq);
    } elseif (strcmp("S",$partial) == 0) {
	pricing_settle_all($posted,"buy",$price,$com,$where.$buyeq);
	pricing_settle_limitQ($posted,"sell",$price,$com,$where.$selleq,$partialQ);
    }
  } else {  // matches no partials -- complete fill of the eqs
    $partial = "N"; $partialQ = '0';
    pricing_settle_all($posted,  "buy", $price, $com, $where.$buyeq );
    pricing_settle_all($posted, "sell", $price, $com, $where.$selleq );  
  }

// pay the commission to the market chairperson and partners

partners_transfer_money($symbolid,floor($quantity*$price*$com/100),"commission received market ".$symbolid);

// reset all the quotes that are one shot to inactive status - whether they execute or not

 $sql = "UPDATE quotes SET active=0 WHERE symbolid=".$symbolid." AND repeat=0;";
 mysql_query($sql, $db_link);
 mysql_error_sanity("f_pricing_commit update deactivate nonrepeating quotes");

// ok now we are done with ledgers, fills, and quotes
// so now let's put a record in the pricings database

$sql = "INSERT INTO pricings (posted,symbolid,price,quantity,crossing_type,partial_side,partialQ,p0,p1,q0,q1,commentary,commentary_by) VALUES ";
$sql .= "('".$posted."',";
$sql .= $symbolid.",";
$sql .= $price.",";
$sql .= $pricing_array["quantity"].",";
$sql .= "'".$pricing_array["crossing_type"]."',";
$sql .= "'".$partial."',";
$sql .= $partialQ.",";
$sql .= $pricing_array["p0"].",";
$sql .= $pricing_array["p1"].",";
$sql .= $pricing_array["q0"].",";
$sql .= $pricing_array["q1"].",";
$sql .= "'".addslashes($commentary)."',";
$sql .= "'".addslashes($commentary_by)."'";
$sql .=");";

mysql_query($sql, $db_link);
mysql_error_sanity("f_pricing_commit insert pricings");

pricing_sanity($symbolid);  // update pricings_latest

}








Return current item: Uniform Price Markets