<s> import sys <EOL> import math <EOL> import random <EOL> bse_sys_minprice = <NUM_LIT:1> <EOL> bse_sys_maxprice = <NUM_LIT:1000> <EOL> ticksize = <NUM_LIT:1> <EOL> class Order : <EOL> def __init__ ( self , tid , otype , price , qty , time ) : <EOL> self . tid = tid <EOL> self . otype = otype <EOL> self . price = price <EOL> self . qty = qty <EOL> self . time = time <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' % ( self . tid , self . otype , self . price , self . qty , self . time ) <EOL> class Orderbook_half : <EOL> def __init__ ( self , booktype , worstprice ) : <EOL> self . booktype = booktype <EOL> self . orders = { } <EOL> self . lob = { } <EOL> self . lob_anon = [ ] <EOL> self . best_price = None <EOL> self . best_tid = None <EOL> self . worstprice = worstprice <EOL> self . n_orders = <NUM_LIT:0> <EOL> self . lob_depth = <NUM_LIT:0> <EOL> def anonymize_lob ( self ) : <EOL> self . lob_anon = [ ] <EOL> for price in sorted ( self . lob ) : <EOL> qty = self . lob [ price ] [ <NUM_LIT:0> ] <EOL> self . lob_anon . append ( [ price , qty ] ) <EOL> def build_lob ( self ) : <EOL> self . lob = { } <EOL> for tid in self . orders : <EOL> order = self . orders . get ( tid ) <EOL> price = order . price <EOL> if price in self . lob : <EOL> qty = self . lob [ price ] [ <NUM_LIT:0> ] <EOL> orderlist = self . lob [ price ] [ <NUM_LIT:1> ] <EOL> orderlist . append ( [ order . time , order . qty , order . tid ] ) <EOL> self . lob [ price ] = [ qty + order . qty , orderlist ] <EOL> else : <EOL> self . lob [ price ] = [ order . qty , [ [ order . time , order . qty , order . tid ] ] ] <EOL> self . anonymize_lob ( ) <EOL> if len ( self . lob ) > <NUM_LIT:0> : <EOL> if self . booktype == '<STR_LIT>' : <EOL> self . best_price = self . lob_anon [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] <EOL> else : <EOL> self . best_price = self . lob_anon [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] <EOL> self . best_tid = self . lob [ self . best_price ] [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] [ <NUM_LIT:2> ] <EOL> else : <EOL> self . best_price = None <EOL> self . best_tid = None <EOL> def book_add ( self , order ) : <EOL> self . orders [ order . tid ] = order <EOL> self . n_orders = len ( self . orders ) <EOL> self . build_lob ( ) <EOL> def book_del ( self , order ) : <EOL> if self . orders . get ( order . tid ) != None : <EOL> del ( self . orders [ order . tid ] ) <EOL> self . n_orders = len ( self . orders ) <EOL> self . build_lob ( ) <EOL> def delete_best ( self ) : <EOL> best_price_orders = self . lob [ self . best_price ] <EOL> best_price_qty = best_price_orders [ <NUM_LIT:0> ] <EOL> best_price_counterparty = best_price_orders [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] [ <NUM_LIT:2> ] <EOL> if best_price_qty == <NUM_LIT:1> : <EOL> del ( self . lob [ self . best_price ] ) <EOL> del ( self . orders [ best_price_counterparty ] ) <EOL> self . n_orders = self . n_orders - <NUM_LIT:1> <EOL> if self . n_orders > <NUM_LIT:0> : <EOL> self . best_price = min ( self . lob . keys ( ) ) <EOL> self . lob_depth = len ( self . lob . keys ( ) ) <EOL> else : <EOL> self . best_price = self . worstprice <EOL> self . lob_depth = <NUM_LIT:0> <EOL> else : <EOL> self . lob [ self . best_price ] = [ best_price_qty - <NUM_LIT:1> , best_price_orders [ <NUM_LIT:1> ] [ <NUM_LIT:1> : ] ] <EOL> del ( self . orders [ best_price_counterparty ] ) <EOL> self . n_orders = self . n_orders - <NUM_LIT:1> <EOL> self . build_lob ( ) <EOL> return best_price_counterparty <EOL> class Orderbook ( Orderbook_half ) : <EOL> def __init__ ( self ) : <EOL> self . bids = Orderbook_half ( '<STR_LIT>' , bse_sys_minprice ) <EOL> self . asks = Orderbook_half ( '<STR_LIT>' , bse_sys_maxprice ) <EOL> self . tape = [ ] <EOL> class Exchange ( Orderbook ) : <EOL> def add_order ( self , order ) : <EOL> tid = order . tid <EOL> if order . otype == '<STR_LIT>' : <EOL> self . bids . book_add ( order ) <EOL> best_price = self . bids . lob_anon [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] <EOL> self . bids . best_price = best_price <EOL> self . bids . best_tid = self . bids . lob [ best_price ] [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] [ <NUM_LIT:2> ] <EOL> else : <EOL> self . asks . book_add ( order ) <EOL> best_price = self . asks . lob_anon [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] <EOL> self . asks . best_price = best_price <EOL> self . asks . best_tid = self . asks . lob [ best_price ] [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] [ <NUM_LIT:2> ] <EOL> def del_order ( self , order ) : <EOL> tid = order . tid <EOL> if order . otype == '<STR_LIT>' : <EOL> self . bids . book_del ( order ) <EOL> best_price = self . bids . lob_anon [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] <EOL> self . bids . best_price = best_price <EOL> self . bids . best_tid = self . bids . lob [ best_price ] [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] [ <NUM_LIT:2> ] <EOL> else : <EOL> self . asks . book_del ( order ) <EOL> best_price = self . asks . lob_anon [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] <EOL> self . asks . best_price = best_price <EOL> self . asks . best_tid = self . asks . lob [ best_price ] [ <NUM_LIT:1> ] [ <NUM_LIT:0> ] [ <NUM_LIT:2> ] <EOL> def process_order2 ( self , time , order , verbose ) : <EOL> oprice = order . price <EOL> counterparty = None <EOL> self . add_order ( order ) <EOL> best_ask = self . asks . best_price <EOL> best_ask_tid = self . asks . best_tid <EOL> best_bid = self . bids . best_price <EOL> best_bid_tid = self . bids . best_tid <EOL> if order . otype == '<STR_LIT>' : <EOL> if self . asks . n_orders > <NUM_LIT:0> and best_bid >= best_ask : <EOL> if verbose : print ( "<STR_LIT>" ) <EOL> counterparty = best_ask_tid <EOL> price = best_ask <EOL> if verbose : print ( '<STR_LIT>' , counterparty , price ) <EOL> self . asks . delete_best ( ) <EOL> self . bids . delete_best ( ) <EOL> elif order . otype == '<STR_LIT>' : <EOL> if self . bids . n_orders > <NUM_LIT:0> and best_ask <= best_bid : <EOL> if verbose : print ( "<STR_LIT>" ) <EOL> counterparty = best_bid_tid <EOL> price = best_bid <EOL> if verbose : print ( '<STR_LIT>' , counterparty , price ) <EOL> self . bids . delete_best ( ) <EOL> self . asks . delete_best ( ) <EOL> else : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> if counterparty != None : <EOL> if verbose : print ( '<STR_LIT>' % ( time , price , counterparty , order . tid ) ) <EOL> transaction_record = { '<STR_LIT:time>' : time , <EOL> '<STR_LIT>' : price , <EOL> '<STR_LIT>' : counterparty , <EOL> '<STR_LIT>' : order . tid , <EOL> '<STR_LIT>' : order . qty } <EOL> self . tape . append ( transaction_record ) <EOL> return transaction_record <EOL> else : <EOL> return None <EOL> def tape_dump ( self , fname , fmode , tmode ) : <EOL> dumpfile = open ( fname , fmode ) <EOL> for tapeitem in self . tape : <EOL> dumpfile . write ( '<STR_LIT>' % ( tapeitem [ '<STR_LIT:time>' ] , tapeitem [ '<STR_LIT>' ] ) ) <EOL> dumpfile . close ( ) <EOL> if tmode == '<STR_LIT>' : <EOL> self . tape = [ ] <EOL> def publish_lob ( self , time , verbose ) : <EOL> public_data = { } <EOL> public_data [ '<STR_LIT:time>' ] = time <EOL> public_data [ '<STR_LIT>' ] = { '<STR_LIT>' : self . bids . best_price , <EOL> '<STR_LIT>' : self . bids . worstprice , <EOL> '<STR_LIT:n>' : self . bids . n_orders , <EOL> '<STR_LIT>' : self . bids . lob_anon } <EOL> public_data [ '<STR_LIT>' ] = { '<STR_LIT>' : self . asks . best_price , <EOL> '<STR_LIT>' : self . asks . worstprice , <EOL> '<STR_LIT:n>' : self . asks . n_orders , <EOL> '<STR_LIT>' : self . asks . lob_anon } <EOL> if verbose : <EOL> print ( '<STR_LIT>' % time ) <EOL> print ( '<STR_LIT>' % public_data [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> print ( '<STR_LIT>' % public_data [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> return public_data <EOL> class Trader : <EOL> def __init__ ( self , ttype , tid , balance ) : <EOL> self . ttype = ttype <EOL> self . tid = tid <EOL> self . balance = balance <EOL> self . blotter = [ ] <EOL> self . orders = [ ] <EOL> self . willing = <NUM_LIT:1> <EOL> self . able = <NUM_LIT:1> <EOL> self . lastquote = None <EOL> def __str__ ( self ) : <EOL> return '<STR_LIT>' % ( self . tid , self . ttype , self . balance , self . blotter , self . orders ) <EOL> def add_order ( self , order ) : <EOL> self . orders = [ order ] <EOL> def del_order ( self , order ) : <EOL> self . orders = [ ] <EOL> def bookkeep ( self , trade , order , verbose ) : <EOL> outstr = '<STR_LIT>' % ( self . tid , self . ttype ) <EOL> for order in self . orders : outstr = outstr + str ( order ) <EOL> self . blotter . append ( trade ) <EOL> transactionprice = trade [ '<STR_LIT>' ] <EOL> if self . orders [ <NUM_LIT:0> ] . otype == '<STR_LIT>' : <EOL> profit = self . orders [ <NUM_LIT:0> ] . price - transactionprice <EOL> else : <EOL> profit = transactionprice - self . orders [ <NUM_LIT:0> ] . price <EOL> self . balance += profit <EOL> if verbose : print ( '<STR_LIT>' % ( outstr , profit , self . balance ) ) <EOL> self . del_order ( order ) <EOL> def respond ( self , time , lob , trade , verbose ) : <EOL> return None <EOL> class Trader_Giveaway ( Trader ) : <EOL> def getorder ( self , time , countdown , lob ) : <EOL> if len ( self . orders ) < <NUM_LIT:1> : <EOL> order = None <EOL> else : <EOL> quoteprice = self . orders [ <NUM_LIT:0> ] . price <EOL> self . lastquote = quoteprice <EOL> order = Order ( self . tid , <EOL> self . orders [ <NUM_LIT:0> ] . otype , <EOL> quoteprice , <EOL> self . orders [ <NUM_LIT:0> ] . qty , <EOL> time ) <EOL> return order <EOL> class Trader_ZIC ( Trader ) : <EOL> def getorder ( self , time , countdown , lob ) : <EOL> if len ( self . orders ) < <NUM_LIT:1> : <EOL> order = None <EOL> else : <EOL> minprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> maxprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> limit = self . orders [ <NUM_LIT:0> ] . price <EOL> otype = self . orders [ <NUM_LIT:0> ] . otype <EOL> if otype == '<STR_LIT>' : <EOL> quoteprice = random . randint ( minprice , limit ) <EOL> else : <EOL> quoteprice = random . randint ( limit , maxprice ) <EOL> order = Order ( self . tid , otype , quoteprice , self . orders [ <NUM_LIT:0> ] . qty , time ) <EOL> return order <EOL> class Trader_Shaver ( Trader ) : <EOL> def getorder ( self , time , countdown , lob ) : <EOL> if len ( self . orders ) < <NUM_LIT:1> : <EOL> order = None <EOL> else : <EOL> limitprice = self . orders [ <NUM_LIT:0> ] . price <EOL> otype = self . orders [ <NUM_LIT:0> ] . otype <EOL> if otype == '<STR_LIT>' : <EOL> if lob [ '<STR_LIT>' ] [ '<STR_LIT:n>' ] > <NUM_LIT:0> : <EOL> quoteprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] + <NUM_LIT:1> <EOL> if quoteprice > limitprice : <EOL> quoteprice = limitprice <EOL> else : <EOL> quoteprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> else : <EOL> if lob [ '<STR_LIT>' ] [ '<STR_LIT:n>' ] > <NUM_LIT:0> : <EOL> quoteprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] - <NUM_LIT:1> <EOL> if quoteprice < limitprice : <EOL> quoteprice = limitprice <EOL> else : <EOL> quoteprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> self . lastquote = quoteprice <EOL> order = Order ( self . tid , otype , quoteprice , self . orders [ <NUM_LIT:0> ] . qty , time ) <EOL> return order <EOL> class Trader_Sniper ( Trader ) : <EOL> def getorder ( self , time , countdown , lob ) : <EOL> lurk_threshold = <NUM_LIT> <EOL> shavegrowthrate = <NUM_LIT:3> <EOL> shave = int ( <NUM_LIT:1.0> / ( <NUM_LIT> + countdown / ( shavegrowthrate * lurk_threshold ) ) ) <EOL> if ( len ( self . orders ) < <NUM_LIT:1> ) or ( countdown > lurk_threshold ) : <EOL> order = None <EOL> else : <EOL> limitprice = self . orders [ <NUM_LIT:0> ] . price <EOL> otype = self . orders [ <NUM_LIT:0> ] . otype <EOL> if otype == '<STR_LIT>' : <EOL> if lob [ '<STR_LIT>' ] [ '<STR_LIT:n>' ] > <NUM_LIT:0> : <EOL> quoteprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] + shave <EOL> if quoteprice > limitprice : <EOL> quoteprice = limitprice <EOL> else : <EOL> quoteprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> else : <EOL> if lob [ '<STR_LIT>' ] [ '<STR_LIT:n>' ] > <NUM_LIT:0> : <EOL> quoteprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] - shave <EOL> if quoteprice < limitprice : <EOL> quoteprice = limitprice <EOL> else : <EOL> quoteprice = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> self . lastquote = quoteprice <EOL> order = Order ( self . tid , otype , quoteprice , self . orders [ <NUM_LIT:0> ] . qty , time ) <EOL> return order <EOL> class Trader_ZIP ( Trader ) : <EOL> def __init__ ( self , ttype , tid , balance ) : <EOL> self . ttype = ttype <EOL> self . tid = tid <EOL> self . balance = balance <EOL> self . blotter = [ ] <EOL> self . orders = [ ] <EOL> self . job = None <EOL> self . active = False <EOL> self . prev_change = <NUM_LIT:0> <EOL> self . beta = <NUM_LIT:0.1> + <NUM_LIT> * random . random ( ) <EOL> self . momntm = <NUM_LIT:0.1> * random . random ( ) <EOL> self . ca = <NUM_LIT> <EOL> self . cr = <NUM_LIT> <EOL> self . margin = None <EOL> self . margin_buy = - <NUM_LIT:1.0> * ( <NUM_LIT> + <NUM_LIT> * random . random ( ) ) <EOL> self . margin_sell = <NUM_LIT> + <NUM_LIT> * random . random ( ) <EOL> self . price = None <EOL> self . limit = None <EOL> self . prev_best_bid_p = None <EOL> self . prev_best_bid_q = None <EOL> self . prev_best_ask_p = None <EOL> self . prev_best_ask_q = None <EOL> def getorder ( self , time , countdown , lob ) : <EOL> if len ( self . orders ) < <NUM_LIT:1> : <EOL> self . active = False <EOL> order = None <EOL> else : <EOL> self . active = True <EOL> self . limit = self . orders [ <NUM_LIT:0> ] . price <EOL> self . job = self . orders [ <NUM_LIT:0> ] . otype <EOL> if self . job == '<STR_LIT>' : <EOL> self . margin = self . margin_buy <EOL> else : <EOL> self . margin = self . margin_sell <EOL> quoteprice = int ( self . limit * ( <NUM_LIT:1> + self . margin ) ) <EOL> self . price = quoteprice <EOL> order = Order ( self . tid , self . job , quoteprice , self . orders [ <NUM_LIT:0> ] . qty , time ) <EOL> return order <EOL> def respond ( self , time , lob , trade , verbose ) : <EOL> def target_up ( price ) : <EOL> ptrb_abs = self . ca * random . random ( ) <EOL> ptrb_rel = price * ( <NUM_LIT:1.0> + ( self . cr * random . random ( ) ) ) <EOL> target = int ( round ( ptrb_rel + ptrb_abs , <NUM_LIT:0> ) ) <EOL> return ( target ) <EOL> def target_down ( price ) : <EOL> ptrb_abs = self . ca * random . random ( ) <EOL> ptrb_rel = price * ( <NUM_LIT:1.0> - ( self . cr * random . random ( ) ) ) <EOL> target = int ( round ( ptrb_rel - ptrb_abs , <NUM_LIT:0> ) ) <EOL> return ( target ) <EOL> def willing_to_trade ( price ) : <EOL> willing = False <EOL> if self . job == '<STR_LIT>' and self . active and self . price >= price : <EOL> willing = True <EOL> if self . job == '<STR_LIT>' and self . active and self . price <= price : <EOL> willing = True <EOL> return willing <EOL> def profit_alter ( price ) : <EOL> oldprice = self . price <EOL> diff = price - oldprice <EOL> change = ( ( <NUM_LIT:1.0> - self . momntm ) * ( self . beta * diff ) ) + ( self . momntm * self . prev_change ) <EOL> self . prev_change = change <EOL> newmargin = ( ( self . price + change ) / self . limit ) - <NUM_LIT:1.0> <EOL> if self . job == '<STR_LIT>' : <EOL> if newmargin < <NUM_LIT:0.0> : <EOL> self . margin_buy = newmargin <EOL> self . margin = newmargin <EOL> else : <EOL> if newmargin > <NUM_LIT:0.0> : <EOL> self . margin_sell = newmargin <EOL> self . margin = newmargin <EOL> self . price = int ( round ( self . limit * ( <NUM_LIT:1.0> + self . margin ) , <NUM_LIT:0> ) ) <EOL> bid_improved = False <EOL> bid_hit = False <EOL> lob_best_bid_p = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> lob_best_bid_q = None <EOL> if lob_best_bid_p != None : <EOL> lob_best_bid_q = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] [ - <NUM_LIT:1> ] [ <NUM_LIT:1> ] <EOL> if self . prev_best_bid_p < lob_best_bid_p : <EOL> bid_improved = True <EOL> elif trade != None and ( ( self . prev_best_bid_p > lob_best_bid_p ) or ( ( self . prev_best_bid_p == lob_best_bid_p ) and ( self . prev_best_bid_q > lob_best_bid_q ) ) ) : <EOL> bid_hit = True <EOL> elif self . prev_best_bid_p != None : <EOL> bid_hit = True <EOL> ask_improved = False <EOL> ask_lifted = False <EOL> lob_best_ask_p = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> lob_best_ask_q = None <EOL> if lob_best_ask_p != None : <EOL> lob_best_ask_q = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] <EOL> if self . prev_best_ask_p > lob_best_ask_p : <EOL> ask_improved = True <EOL> elif trade != None and ( ( self . prev_best_ask_p < lob_best_ask_p ) or ( ( self . prev_best_ask_p == lob_best_ask_p ) and ( self . prev_best_ask_q > lob_best_ask_q ) ) ) : <EOL> ask_lifted = True <EOL> elif self . prev_best_ask_p != None : <EOL> ask_lifted = True <EOL> if verbose and ( bid_improved or bid_hit or ask_improved or ask_lifted ) : <EOL> print ( '<STR_LIT>' , bid_improved , '<STR_LIT>' , bid_hit , '<STR_LIT>' , ask_improved , '<STR_LIT>' , ask_lifted ) <EOL> deal = bid_hit or ask_lifted <EOL> if self . job == '<STR_LIT>' : <EOL> if deal : <EOL> tradeprice = trade [ '<STR_LIT>' ] <EOL> if self . price <= tradeprice : <EOL> target_price = target_up ( tradeprice ) <EOL> profit_alter ( target_price ) <EOL> elif ask_lifted and self . active and not willing_to_trade ( tradeprice ) : <EOL> target_price = target_down ( tradeprice ) <EOL> profit_alter ( target_price ) <EOL> else : <EOL> if ask_improved and self . price > lob_best_ask_p : <EOL> if lob_best_bid_p != None : <EOL> target_price = target_up ( lob_best_bid_p ) <EOL> else : <EOL> target_price = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> profit_alter ( target_price ) <EOL> if self . job == '<STR_LIT>' : <EOL> if deal : <EOL> tradeprice = trade [ '<STR_LIT>' ] <EOL> if self . price >= tradeprice : <EOL> target_price = target_down ( tradeprice ) <EOL> profit_alter ( target_price ) <EOL> elif bid_hit and self . active and not willing_to_trade ( tradeprice ) : <EOL> target_price = target_up ( tradeprice ) <EOL> profit_alter ( target_price ) <EOL> else : <EOL> if bid_improved and self . price < lob_best_bid_p : <EOL> if lob_best_ask_p != None : <EOL> target_price = target_down ( lob_best_ask_p ) <EOL> else : <EOL> target_price = lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> profit_alter ( target_price ) <EOL> self . prev_best_bid_p = lob_best_bid_p <EOL> self . prev_best_bid_q = lob_best_bid_q <EOL> self . prev_best_ask_p = lob_best_ask_p <EOL> self . prev_best_ask_q = lob_best_ask_q <EOL> def trade_stats ( expid , traders , dumpfile , time , lob ) : <EOL> trader_types = { } <EOL> n_traders = len ( traders ) <EOL> for t in traders : <EOL> ttype = traders [ t ] . ttype <EOL> if ttype in trader_types . keys ( ) : <EOL> t_balance = trader_types [ ttype ] [ '<STR_LIT>' ] + traders [ t ] . balance <EOL> n = trader_types [ ttype ] [ '<STR_LIT:n>' ] + <NUM_LIT:1> <EOL> else : <EOL> t_balance = traders [ t ] . balance <EOL> n = <NUM_LIT:1> <EOL> trader_types [ ttype ] = { '<STR_LIT:n>' : n , '<STR_LIT>' : t_balance } <EOL> dumpfile . write ( '<STR_LIT>' % ( expid , time ) ) <EOL> for ttype in sorted ( list ( trader_types . keys ( ) ) ) : <EOL> n = trader_types [ ttype ] [ '<STR_LIT:n>' ] <EOL> s = trader_types [ ttype ] [ '<STR_LIT>' ] <EOL> dumpfile . write ( '<STR_LIT>' % ( ttype , s , n , s / float ( n ) ) ) <EOL> if lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] != None : <EOL> dumpfile . write ( '<STR_LIT>' % ( lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) ) <EOL> else : <EOL> dumpfile . write ( '<STR_LIT>' ) <EOL> if lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] != None : <EOL> dumpfile . write ( '<STR_LIT>' % ( lob [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) ) <EOL> else : <EOL> dumpfile . write ( '<STR_LIT>' ) <EOL> dumpfile . write ( '<STR_LIT:\n>' ) ; <EOL> def populate_market ( traders_spec , traders , shuffle , verbose ) : <EOL> def trader_type ( robottype , name ) : <EOL> if robottype == '<STR_LIT>' : <EOL> return Trader_Giveaway ( '<STR_LIT>' , name , <NUM_LIT> ) <EOL> elif robottype == '<STR_LIT>' : <EOL> return Trader_ZIC ( '<STR_LIT>' , name , <NUM_LIT> ) <EOL> elif robottype == '<STR_LIT>' : <EOL> return Trader_Shaver ( '<STR_LIT>' , name , <NUM_LIT> ) <EOL> elif robottype == '<STR_LIT>' : <EOL> return Trader_Sniper ( '<STR_LIT>' , name , <NUM_LIT> ) <EOL> elif robottype == '<STR_LIT>' : <EOL> return Trader_ZIP ( '<STR_LIT>' , name , <NUM_LIT> ) <EOL> else : <EOL> sys . exit ( '<STR_LIT>' % robottype ) <EOL> def shuffle_traders ( ttype_char , n , traders ) : <EOL> for swap in range ( n ) : <EOL> t1 = ( n - <NUM_LIT:1> ) - swap <EOL> t2 = random . randint ( <NUM_LIT:0> , t1 ) <EOL> t1name = '<STR_LIT>' % ( ttype_char , t1 ) <EOL> t2name = '<STR_LIT>' % ( ttype_char , t2 ) <EOL> traders [ t1name ] . tid = t2name <EOL> traders [ t2name ] . tid = t1name <EOL> temp = traders [ t1name ] <EOL> traders [ t1name ] = traders [ t2name ] <EOL> traders [ t2name ] = temp <EOL> n_buyers = <NUM_LIT:0> <EOL> for bs in traders_spec [ '<STR_LIT>' ] : <EOL> ttype = bs [ <NUM_LIT:0> ] <EOL> for b in range ( bs [ <NUM_LIT:1> ] ) : <EOL> tname = '<STR_LIT>' % n_buyers <EOL> traders [ tname ] = trader_type ( ttype , tname ) <EOL> n_buyers = n_buyers + <NUM_LIT:1> <EOL> if n_buyers < <NUM_LIT:1> : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> if shuffle : shuffle_traders ( '<STR_LIT:B>' , n_buyers , traders ) <EOL> n_sellers = <NUM_LIT:0> <EOL> for ss in traders_spec [ '<STR_LIT>' ] : <EOL> ttype = ss [ <NUM_LIT:0> ] <EOL> for s in range ( ss [ <NUM_LIT:1> ] ) : <EOL> tname = '<STR_LIT>' % n_sellers <EOL> traders [ tname ] = trader_type ( ttype , tname ) <EOL> n_sellers = n_sellers + <NUM_LIT:1> <EOL> if n_sellers < <NUM_LIT:1> : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> if shuffle : shuffle_traders ( '<STR_LIT:S>' , n_sellers , traders ) <EOL> if verbose : <EOL> for t in range ( n_buyers ) : <EOL> bname = '<STR_LIT>' % t <EOL> print ( traders [ bname ] ) <EOL> for t in range ( n_sellers ) : <EOL> bname = '<STR_LIT>' % t <EOL> print ( traders [ bname ] ) <EOL> return { '<STR_LIT>' : n_buyers , '<STR_LIT>' : n_sellers } <EOL> def customer_orders ( time , last_update , traders , trader_stats , os , pending , verbose ) : <EOL> def sysmin_check ( price ) : <EOL> if price < bse_sys_minprice : <EOL> print ( '<STR_LIT>' ) <EOL> price = bse_sys_minprice <EOL> return price <EOL> def sysmax_check ( price ) : <EOL> if price > bse_sys_maxprice : <EOL> print ( '<STR_LIT>' ) <EOL> price = bse_sys_maxprice <EOL> return price <EOL> def getorderprice ( i , sched , n , mode , issuetime ) : <EOL> if len ( sched [ <NUM_LIT:0> ] ) > <NUM_LIT:2> : <EOL> offsetfn = sched [ <NUM_LIT:0> ] [ <NUM_LIT:2> ] <EOL> if callable ( offsetfn ) : <EOL> offset_min = offsetfn ( issuetime ) <EOL> offset_max = offset_min <EOL> else : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> if len ( sched [ <NUM_LIT:0> ] ) > <NUM_LIT:3> : <EOL> offsetfn = sched [ <NUM_LIT:0> ] [ <NUM_LIT:3> ] <EOL> if callable ( offsetfn ) : <EOL> offset_max = offsetfn ( issuetime ) <EOL> else : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> else : <EOL> offset_min = <NUM_LIT:0.0> <EOL> offset_max = <NUM_LIT:0.0> <EOL> pmin = sysmin_check ( offset_min + min ( sched [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] , sched [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] ) ) <EOL> pmax = sysmax_check ( offset_max + max ( sched [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] , sched [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] ) ) <EOL> prange = pmax - pmin <EOL> stepsize = prange / ( n - <NUM_LIT:1> ) <EOL> halfstep = round ( stepsize / <NUM_LIT> ) <EOL> if mode == '<STR_LIT>' : <EOL> orderprice = pmin + int ( i * stepsize ) <EOL> elif mode == '<STR_LIT>' : <EOL> orderprice = pmin + int ( i * stepsize ) + random . randint ( - halfstep , halfstep ) <EOL> elif mode == '<STR_LIT>' : <EOL> if len ( sched ) > <NUM_LIT:1> : <EOL> s = random . randint ( <NUM_LIT:0> , len ( sched ) - <NUM_LIT:1> ) <EOL> pmin = sysmin_check ( min ( sched [ s ] [ <NUM_LIT:0> ] , sched [ s ] [ <NUM_LIT:1> ] ) ) <EOL> pmax = sysmax_check ( max ( sched [ s ] [ <NUM_LIT:0> ] , sched [ s ] [ <NUM_LIT:1> ] ) ) <EOL> orderprice = random . randint ( pmin , pmax ) <EOL> else : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> orderprice = sysmin_check ( sysmax_check ( orderprice ) ) <EOL> return orderprice <EOL> def getissuetimes ( n_traders , mode , interval , shuffle , fittointerval ) : <EOL> interval = float ( interval ) <EOL> if n_traders < <NUM_LIT:1> : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> elif n_traders == <NUM_LIT:1> : <EOL> tstep = interval <EOL> else : <EOL> tstep = interval / ( n_traders - <NUM_LIT:1> ) <EOL> arrtime = <NUM_LIT:0> <EOL> issuetimes = [ ] <EOL> for t in range ( n_traders ) : <EOL> if mode == '<STR_LIT>' : <EOL> arrtime = interval <EOL> elif mode == '<STR_LIT>' : <EOL> arrtime = t * tstep <EOL> elif mode == '<STR_LIT>' : <EOL> arrtime = t * tstep + tstep * random . random ( ) <EOL> elif mode == '<STR_LIT>' : <EOL> interarrivaltime = random . expovariate ( n_traders / interval ) <EOL> arrtime += interarrivaltime <EOL> else : <EOL> sys . exit ( '<STR_LIT>' ) <EOL> issuetimes . append ( arrtime ) <EOL> if fittointerval and ( ( arrtime > interval ) or ( arrtime < interval ) ) : <EOL> for t in range ( n_traders ) : <EOL> issuetimes [ t ] = interval * ( issuetimes [ t ] / arrtime ) <EOL> if shuffle : <EOL> for t in range ( n_traders ) : <EOL> i = ( n_traders - <NUM_LIT:1> ) - t <EOL> j = random . randint ( <NUM_LIT:0> , i ) <EOL> tmp = issuetimes [ i ] <EOL> issuetimes [ i ] = issuetimes [ j ] <EOL> issuetimes [ j ] = tmp <EOL> return issuetimes <EOL> def getschedmode ( time , os ) : <EOL> got_one = False <EOL> for sched in os : <EOL> if ( sched [ '<STR_LIT>' ] <= time ) and ( time < sched [ '<STR_LIT:to>' ] ) : <EOL> schedrange = sched [ '<STR_LIT>' ] <EOL> mode = sched [ '<STR_LIT>' ] <EOL> got_one = True <EOL> exit <EOL> if not got_one : <EOL> sys . exit ( '<STR_LIT>' % ( time , os ) ) <EOL> return ( schedrange , mode ) <EOL> n_buyers = trader_stats [ '<STR_LIT>' ] <EOL> n_sellers = trader_stats [ '<STR_LIT>' ] <EOL> n_traders = n_buyers + n_sellers <EOL> shuffle_times = True <EOL> if len ( pending ) < <NUM_LIT:1> : <EOL> new_pending = [ ] <EOL> issuetimes = getissuetimes ( n_buyers , os [ '<STR_LIT>' ] , os [ '<STR_LIT>' ] , shuffle_times , True ) <EOL> ordertype = '<STR_LIT>' <EOL> ( sched , mode ) = getschedmode ( time , os [ '<STR_LIT>' ] ) <EOL> for t in range ( n_buyers ) : <EOL> issuetime = time + issuetimes [ t ] <EOL> tname = '<STR_LIT>' % t <EOL> orderprice = getorderprice ( t , sched , n_buyers , mode , issuetime ) <EOL> order = Order ( tname , ordertype , orderprice , <NUM_LIT:1> , issuetime ) <EOL> new_pending . append ( order ) <EOL> issuetimes = getissuetimes ( n_sellers , os [ '<STR_LIT>' ] , os [ '<STR_LIT>' ] , shuffle_times , True ) <EOL> ordertype = '<STR_LIT>' <EOL> ( sched , mode ) = getschedmode ( time , os [ '<STR_LIT>' ] ) <EOL> for t in range ( n_sellers ) : <EOL> issuetime = time + issuetimes [ t ] <EOL> tname = '<STR_LIT>' % t <EOL> orderprice = getorderprice ( t , sched , n_sellers , mode , issuetime ) <EOL> order = Order ( tname , ordertype , orderprice , <NUM_LIT:1> , issuetime ) <EOL> new_pending . append ( order ) <EOL> else : <EOL> new_pending = [ ] <EOL> for order in pending : <EOL> if order . time < time : <EOL> tname = order . tid <EOL> traders [ tname ] . add_order ( order ) <EOL> if verbose : print ( '<STR_LIT>' % order ) <EOL> else : <EOL> new_pending . append ( order ) <EOL> return new_pending <EOL> def market_session ( sess_id , starttime , endtime , trader_spec , order_schedule , dumpfile , dump_each_trade ) : <EOL> exchange = Exchange ( ) <EOL> traders = { } <EOL> trader_stats = populate_market ( trader_spec , traders , True , True ) <EOL> timestep = <NUM_LIT:1.0> / float ( trader_stats [ '<STR_LIT>' ] + trader_stats [ '<STR_LIT>' ] ) <EOL> duration = float ( endtime - starttime ) <EOL> last_update = - <NUM_LIT:1.0> <EOL> time = starttime <EOL> orders_verbose = False <EOL> lob_verbose = False <EOL> process_verbose = False <EOL> respond_verbose = False <EOL> bookkeep_verbose = False <EOL> pending_orders = [ ] <EOL> while time < endtime : <EOL> time_left = ( endtime - time ) / duration <EOL> trade = None <EOL> pending_orders = customer_orders ( time , last_update , traders , trader_stats , <EOL> order_schedule , pending_orders , orders_verbose ) <EOL> tid = list ( traders . keys ( ) ) [ random . randint ( <NUM_LIT:0> , len ( traders ) - <NUM_LIT:1> ) ] <EOL> order = traders [ tid ] . getorder ( time , time_left , exchange . publish_lob ( time , lob_verbose ) ) <EOL> if order != None : <EOL> trade = exchange . process_order2 ( time , order , process_verbose ) <EOL> if trade != None : <EOL> traders [ trade [ '<STR_LIT>' ] ] . bookkeep ( trade , order , bookkeep_verbose ) <EOL> traders [ trade [ '<STR_LIT>' ] ] . bookkeep ( trade , order , bookkeep_verbose ) <EOL> if dump_each_trade : trade_stats ( sess_id , traders , tdump , time , exchange . publish_lob ( time , lob_verbose ) ) <EOL> lob = exchange . publish_lob ( time , lob_verbose ) <EOL> for t in traders : <EOL> traders [ t ] . respond ( time , lob , trade , respond_verbose ) <EOL> time = time + timestep <EOL> exchange . tape_dump ( '<STR_LIT>' , '<STR_LIT:w>' , '<STR_LIT>' ) <EOL> trade_stats ( sess_id , traders , tdump , time , exchange . publish_lob ( time , lob_verbose ) ) <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> start_time = <NUM_LIT:0.0> <EOL> end_time = <NUM_LIT> <EOL> duration = end_time - start_time <EOL> def schedule_offsetfn ( t ) : <EOL> pi2 = math . pi * <NUM_LIT:2> <EOL> c = math . pi * <NUM_LIT> <EOL> wavelength = t / c <EOL> gradient = <NUM_LIT:100> * t / ( c / pi2 ) <EOL> amplitude = <NUM_LIT:100> * t / ( c / pi2 ) <EOL> offset = gradient + amplitude * math . sin ( wavelength * t ) <EOL> return int ( round ( offset , <NUM_LIT:0> ) ) <EOL> range1 = ( <NUM_LIT> , <NUM_LIT> , schedule_offsetfn ) <EOL> supply_schedule = [ { '<STR_LIT>' : start_time , '<STR_LIT:to>' : end_time , '<STR_LIT>' : [ range1 ] , '<STR_LIT>' : '<STR_LIT>' } <EOL> ] <EOL> range1 = ( <NUM_LIT> , <NUM_LIT> , schedule_offsetfn ) <EOL> demand_schedule = [ { '<STR_LIT>' : start_time , '<STR_LIT:to>' : end_time , '<STR_LIT>' : [ range1 ] , '<STR_LIT>' : '<STR_LIT>' } <EOL> ] <EOL> order_sched = { '<STR_LIT>' : supply_schedule , '<STR_LIT>' : demand_schedule , <EOL> '<STR_LIT>' : <NUM_LIT:30> , '<STR_LIT>' : '<STR_LIT>' } <EOL> n_trader_types = <NUM_LIT:4> <EOL> equal_ratio_n = <NUM_LIT:4> <EOL> n_trials_per_ratio = <NUM_LIT:50> <EOL> n_traders = n_trader_types * equal_ratio_n <EOL> fname = '<STR_LIT>' % equal_ratio_n <EOL> tdump = open ( fname , '<STR_LIT:w>' ) <EOL> min_n = <NUM_LIT:1> <EOL> trialnumber = <NUM_LIT:1> <EOL> trdr_1_n = min_n <EOL> while trdr_1_n <= n_traders : <EOL> trdr_2_n = min_n <EOL> while trdr_2_n <= n_traders - trdr_1_n : <EOL> trdr_3_n = min_n <EOL> while trdr_3_n <= n_traders - ( trdr_1_n + trdr_2_n ) : <EOL> trdr_4_n = n_traders - ( trdr_1_n + trdr_2_n + trdr_3_n ) <EOL> if trdr_4_n >= min_n : <EOL> buyers_spec = [ ( '<STR_LIT>' , trdr_1_n ) , ( '<STR_LIT>' , trdr_2_n ) , <EOL> ( '<STR_LIT>' , trdr_3_n ) , ( '<STR_LIT>' , trdr_4_n ) ] <EOL> sellers_spec = buyers_spec <EOL> traders_spec = { '<STR_LIT>' : sellers_spec , '<STR_LIT>' : buyers_spec } <EOL> print buyers_spec <EOL> trial = <NUM_LIT:1> <EOL> while trial <= n_trials_per_ratio : <EOL> trial_id = '<STR_LIT>' % trialnumber <EOL> market_session ( trial_id , start_time , end_time , traders_spec , <EOL> order_sched , tdump , False ) <EOL> tdump . flush ( ) <EOL> trial = trial + <NUM_LIT:1> <EOL> trialnumber = trialnumber + <NUM_LIT:1> <EOL> trdr_3_n += <NUM_LIT:1> <EOL> trdr_2_n += <NUM_LIT:1> <EOL> trdr_1_n += <NUM_LIT:1> <EOL> tdump . close ( ) <EOL> print trialnumber </s>
