CYCLUS
trade_executor.h
Go to the documentation of this file.
1 #ifndef CYCLUS_SRC_TRADE_EXECUTOR_H_
2 #define CYCLUS_SRC_TRADE_EXECUTOR_H_
3 
4 #include <map>
5 #include <set>
6 #include <utility>
7 #include <vector>
8 
9 #include "context.h"
10 #include "trade.h"
11 #include "trader.h"
12 #include "trader_management.h"
13 
14 namespace cyclus {
15 
16 /// @class TradeExecutor::Context
17 ///
18 /// @brief a holding class for information related to a TradeExecutor
19 template <class T>
21  std::set<Trader*> suppliers;
22  std::set<Trader*> requesters;
23 
24  // the key is the supplier
25  std::map<Trader*, std::vector< Trade<T> > > trades_by_supplier;
26 
27  // the key is the requester, values are a vector of the target Trade with the
28  // associated response resource provided by the supplier
29  std::map<Trader*, std::vector< std::pair<Trade<T>, typename T::Ptr> > >
31 
32  // by convention, the first trader is the supplier, the second is the
33  // requester
34  std::map<std::pair<Trader*, Trader*>,
35  std::vector< std::pair<Trade<T>, typename T::Ptr> > > all_trades;
36 };
37 
38 /// @class TradeExecutor
39 ///
40 /// @brief The TradeExecutor is an object whose task is to execute a collection
41 /// of Trades. Trade Execution takes nominally three steps:
42 /// #. Grouping all trades by supplier (sender)
43 /// #. Collecting responses for the group of trades from each supplier
44 /// #. Grouping all responses by requester (receiver)
45 /// #. Sending all grouped responses to their respective requester
46 template <class T>
48  public:
49  explicit TradeExecutor(const std::vector< Trade<T> >& trades)
50  : trades_(trades) {}
51 
52  /// @brief execute all trades, collecting responders from bidders and sending
53  /// responses to requesters
54  ///
55  /// @deprecated Use ExecuteTrades(Context*) instead. This function just
56  /// calls ExecuteTrades(NULL).
57  void ExecuteTrades() {
58  Warn<IO_WARNING>("this function does not record trades to the database");
59  ExecuteTrades(NULL);
60  }
61 
62  /// @brief execute all trades, collecting responders from bidders and sending
63  /// responses to requesters
64  void ExecuteTrades(Context* ctx) {
65  GroupTradesBySupplier(trade_ctx_, trades_);
66  GetTradeResponses(trade_ctx_);
67  if (ctx != NULL) {
68  RecordTrades(ctx);
69  }
70  SendTradeResources(trade_ctx_);
71  }
72 
73  /// @brief Record all trades with the appropriate backends
74  ///
75  /// @param ctx the Context through which communication with backends will
76  /// occur
77  void RecordTrades(Context* ctx) {
78  // record all trades
79  typename std::map<std::pair<Trader*, Trader*>,
80  std::vector< std::pair<Trade<T>, typename T::Ptr> > >::iterator m_it;
81  for (m_it = trade_ctx_.all_trades.begin();
82  m_it != trade_ctx_.all_trades.end(); ++m_it) {
83  Agent* supplier = m_it->first.first->manager();
84  Agent* requester = m_it->first.second->manager();
85  typename std::vector< std::pair<Trade<T>, typename T::Ptr> >&
86  trades = m_it->second;
87  typename std::vector< std::pair<Trade<T>, typename T::Ptr> >::iterator
88  v_it;
89  for (v_it = trades.begin(); v_it != trades.end(); ++v_it) {
90  Trade<T>& trade = v_it->first;
91  typename T::Ptr rsrc = v_it->second;
92  ctx->NewDatum("Transactions")
93  ->AddVal("TransactionId", ctx->NextTransactionID())
94  ->AddVal("SenderId", supplier->id())
95  ->AddVal("ReceiverId", requester->id())
96  ->AddVal("ResourceId", rsrc->state_id())
97  ->AddVal("Commodity", trade.request->commodity())
98  ->AddVal("Time", ctx->time())
99  ->Record();
100  }
101  }
102  }
103 
104  inline const TradeExecutionContext<T>& trade_ctx() const {
105  return trade_ctx_;
106  }
108  return trade_ctx_;
109  }
110 
111  private:
112  const std::vector< Trade<T> >& trades_;
113  TradeExecutionContext<T> trade_ctx_;
114 };
115 
116 /// @brief populates suppliers_, requesters_, and trades_by_supplier_
117 template<class T>
119  const std::vector< Trade<T> >& trades) {
120  typename std::vector< Trade<T> >::const_iterator it;
121  for (it = trades.begin(); it != trades.end(); ++it) {
122  trade_ctx.trades_by_supplier[it->bid->bidder()].push_back(*it);
123  trade_ctx.suppliers.insert(it->bid->bidder());
124  trade_ctx.requesters.insert(it->request->requester());
125  }
126 }
127 
128 /// @brief queries each supplier for the responses to thier matched trade and
129 /// populates trades_by_requester_ and all_trades_ with the results
130 template<class T>
132  std::set<Trader*>::iterator it;
133  for (it = trade_ctx.suppliers.begin(); it != trade_ctx.suppliers.end();
134  ++it) {
135  // get responses
136  Trader* supplier = *it;
137  std::vector< std::pair<Trade<T>, typename T::Ptr> > responses;
138  PopulateTradeResponses(supplier, trade_ctx.trades_by_supplier[supplier],
139  responses);
140 
141  // populate containers
142  typename std::vector< std::pair<Trade<T>, typename T::Ptr> >::iterator r_it;
143  for (r_it = responses.begin(); r_it != responses.end(); ++r_it) {
144  // @todo unsure if this is needed...
145  // Trade<T>& trade = r_it->first;
146  // typename T::Ptr rsrc= r_it->second;
147  // if (rsrc->quantity() != trade.amt) {
148  // throw ValueError("Trade amt and resource qty must match");
149  // }
150  Trader* requester = r_it->first.request->requester();
151  trade_ctx.trades_by_requester[requester].push_back(*r_it);
152  trade_ctx.all_trades[std::make_pair(supplier, requester)].push_back(*r_it);
153  }
154  }
155 }
156 
157 template <class T>
159  std::set<Trader*>::iterator it;
160  for (it = trade_ctx.requesters.begin(); it != trade_ctx.requesters.end();
161  ++it) {
162  Trader* requester = *it;
163  AcceptTrades(requester, trade_ctx.trades_by_requester[requester]);
164  }
165 }
166 
167 } // namespace cyclus
168 
169 #endif // CYCLUS_SRC_TRADE_EXECUTOR_H_
static void GetTradeResponses(TradeExecutionContext< T > &trade_ctx)
queries each supplier for the responses to thier matched trade and populates trades_by_requester_ and...
Request< T > * request
Definition: trade.h:17
void RecordTrades(Context *ctx)
Record all trades with the appropriate backends.
void ExecuteTrades(Context *ctx)
execute all trades, collecting responders from bidders and sending responses to requesters ...
A simple API for agents that wish to exchange resources in the simulation.
Definition: trader.h:24
void ExecuteTrades()
execute all trades, collecting responders from bidders and sending responses to requesters ...
std::map< Trader *, std::vector< std::pair< Trade< T >, typename T::Ptr > > > trades_by_requester
std::set< Trader * > requesters
static void SendTradeResources(TradeExecutionContext< T > &trade_ctx)
std::map< Trader *, std::vector< Trade< T > > > trades_by_supplier
virtual int time()
Returns the current simulation timestep.
Definition: context.cc:225
const TradeExecutionContext< T > & trade_ctx() const
static void PopulateTradeResponses(Trader *trader, const std::vector< Trade< T > > &trades, std::vector< std::pair< Trade< T >, typename T::Ptr > > &responses)
void GroupTradesBySupplier(TradeExecutionContext< T > &trade_ctx, const std::vector< Trade< T > > &trades)
populates suppliers_, requesters_, and trades_by_supplier_
Datum * AddVal(const char *field, boost::spirit::hold_any val, std::vector< int > *shape=NULL)
Add an arbitrary field-value pair to the datum.
Definition: datum.cc:12
TradeExecutionContext< T > & trade_ctx()
int NextTransactionID()
Definition: context.h:253
static void AcceptTrades(Trader *trader, const std::vector< std::pair< Trade< T >, typename T::Ptr > > &responses)
A simulation context provides access to necessary simulation-global functions and state...
Definition: context.h:128
The abstract base class used by all types of agents that live and interact in a simulation.
Definition: agent.h:51
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or.org/Osi/browser/trunk.
Definition: agent.cc:14
A Trade is a simple container that associates a request for a resource with a bid for that resource...
Definition: trade.h:16
std::map< std::pair< Trader *, Trader * >, std::vector< std::pair< Trade< T >, typename T::Ptr > > > all_trades
std::set< Trader * > suppliers
virtual const int id() const
The agent instance&#39;s unique ID within a simulation.
Definition: agent.h:354
TradeExecutor(const std::vector< Trade< T > > &trades)
Datum * NewDatum(std::string title)
See Recorder::NewDatum documentation.
Definition: context.cc:237