Module: broker/compare_positions.py

"""
Module containing a procedure for the broker to compare negotiating positions and arrive
at a basis for agreement.
"""

basepath = "/Users/pbaker/Documents/Office Projects/Software Dev/demo1/broker"

import sys
sys.path.append(basepath)
import broker_model as broker

def _compare_statements(f, g1, g2, ask, offer):

    #print "compare %d with %d" % (ask["ref_id"], offer["ref_id"])
    
    # first the intervals must match and the stocks must match
    if ask["interval"] != offer["interval"]:           
        return
        
    if ask["swap_stock"] != offer["accept"] or ask["for_stock"] != offer["for"]:
        return
        
    # the number of shares requested must be in the offerer's range
    if ask["number"] < offer["number"][0] or ask["number"] > offer["number"][1]:
        return
    # let us assemble what works so far
    accept_stock = offer["accept"]
    for_stock = offer["for"]
    # next let us look for an agreement on price
    ask_cash = ask["cash_per_share"]
    offer_cash = offer["cash_per_share"]
    if ask_cash[1] < offer_cash[0]:
        # maximum asker will pay is less than offerer will accept
        return
    # broker defines agreement as splitting the difference between payer's maximum
    # and offerer's minimum
    agreed_cash = (ask_cash[1] + offer_cash[0]) / 2.0

    # write agreement statement

    f.write("\nagreement:\n")
    f.write("   shares: %s\n" % ask["number"])
    f.write("   swap: %s\n" % ask["swap_stock"])
    f.write("   for: %s\n" % ask["for_stock"])
    f.write("   plus: %s\n" % agreed_cash)
    f.write("   interval: %s\n" % ask["interval"])
    f.write("   ask_ref_id: %d\n" % ask["ref_id"])
    f.write("   offer_ref_id: %d\n" % offer["ref_id"])
    f.write("end\n")

    s = "{ \"action\" : \"agreement\", \"accept\" : \"%s\", " % ask["swap_stock"]
    g1.write(s)
    g2.write(s)
    
    s = "\"for\" : \"%s\", \"cash_per_share\" : %s, \"number\" : %s, " % (ask["for_stock"], agreed_cash, ask["number"])
    g1.write(s)
    g2.write(s)
    
    s = "\"interval\" : \"%s\", \"ask_ref_id\" : %d, \"offer_ref_id\" : %d} \n" % (ask["interval"], ask["ref_id"], offer["ref_id"])
    g1.write(s)
    g2.write(s)
    

    g1.write("\n")
    g2.write("\n")
           
               
    
           
           

def _compare_positions(f, g1, g2, X, Y, ask):
    """
Scan the negotiation position of X and for each 'ask' statement found there
scan the negotiation position of Y and for each 'offer' found there
compare the ask and the offer. Write a basis of agreement statement if
there is one to write.
"""
    yin = open("%s/player%s/x_player%s_position.py" % (basepath, Y, X) )
    #yin = open("%s/player%s/player%s_position.py" % (basepath, Y, X) )
    line = yin.readline()
    while line:
        try:
            statement = eval(line)
            if statement.has_key("action"):
                if statement["action"] == "offer":
                    _compare_statements(f, g1, g2, ask, statement)
        except:
            pass
        finally:
            line = yin.readline()
            

    yin.close()
    

def find_basis(f, g1, g2, X, Y):
    """
Compare negotiation positions to find a basis for agreement.
The position belonging to X is used only as a source of ask statements
which are matched against offer statements in the position of Y.
The agreement is written as text on file f and as Python on file g.
A complete comparison requires two calls: for for X vs. Y and the other for
Y vs. X.
"""
    
    xin = open("%s/player%s/x_player%s_position.py" % (basepath, X, Y) )
    #xin = open("%s/player%s/player%s_position.py" % (basepath, X, Y) )

    line = xin.readline()
    while line:
        try:
            statement = eval(line)
            if statement.has_key("action"):
                if statement["action"] == "ask":
                    _compare_positions(f, g1, g2, X, Y, statement)
                    
        except:
            pass
        finally:
            line = xin.readline()

    xin.close()
            



if __name__ == '__main__':
    """ This module employs a decision that the broker makes to store results. The players have positions on a list.
They negotiate in pairs and the player first on the list starts the negotiation and the basis for agreement is kept in the
broker's file directory for the first player under the name agreement_player1_player2"""
    
    nplayers = len(broker.players)
    i = 0
    while i < nplayers:
        j = i + 1
        while j < nplayers:
            print " find agreement for players %s and %s" % (broker.players[i], broker.players[j])
            
            f = open("%s/player%s/x_agreement_player%s_player%s.txt" % (basepath, broker.players[i], broker.players[i], broker.players[j]), "w")

            g1name = "%s/player%s/x_agreement_player%s_player%s.py" % (basepath, broker.players[i], broker.players[i], broker.players[j])
            g1 = open(g1name, "w")

            g2name = "%s/player%s/x_agreement_player%s_player%s.py" % (basepath, broker.players[j], broker.players[j], broker.players[i])
            g2 = open(g2name, "w")

            #print "gfiles: %s and %s " % (g1name, g2name)
            find_basis(f, g1, g2, broker.players[i], broker.players[j])
            find_basis(f, g1, g2, broker.players[j], broker.players[i])
            f.write("\n")
            g1.write("\n")
            g2.write("\n")
            f.close()
            g1.close()
            g2.close()
            j += 1
        i += 1