CYCLUS
Loading...
Searching...
No Matches
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
14namespace cyclus {
15
16/// @class TradeExecutor::Context
17///
18/// @brief a holding class for information related to a TradeExecutor
19template <class T> struct TradeExecutionContext {
20 std::set<Trader*> suppliers;
21 std::set<Trader*> requesters;
22
23 // the key is the supplier
24 std::map<Trader*, std::vector<Trade<T>>> trades_by_supplier;
25
26 // the key is the requester, values are a vector of the target Trade with the
27 // associated response resource provided by the supplier
28 std::map<Trader*, std::vector<std::pair<Trade<T>, typename T::Ptr>>>
30
31 // by convention, the first trader is the supplier, the second is the
32 // requester
33 std::map<std::pair<Trader*, Trader*>,
34 std::vector<std::pair<Trade<T>, typename T::Ptr>>>
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
46template <class T> class TradeExecutor {
47 public:
48 explicit TradeExecutor(const std::vector<Trade<T>>& trades)
49 : trades_(trades) {}
50
51 /// @brief execute all trades, collecting responders from bidders and sending
52 /// responses to requesters
53 ///
54 /// @deprecated Use ExecuteTrades(Context*) instead. This function just
55 /// calls ExecuteTrades(NULL).
57 Warn<IO_WARNING>("this function does not record trades to the database");
58 ExecuteTrades(NULL);
59 }
60
61 /// @brief execute all trades, collecting responders from bidders and sending
62 /// responses to requesters
64 GroupTradesBySupplier(trade_ctx_, trades_);
65 GetTradeResponses(trade_ctx_);
66 if (ctx != NULL) {
67 RecordTrades(ctx);
68 }
69 SendTradeResources(trade_ctx_);
70 }
71
72 /// @brief Record all trades with the appropriate backends
73 ///
74 /// @param ctx the Context through which communication with backends will
75 /// occur
76 void RecordTrades(Context* ctx) {
77 // record all trades
78 typename std::map<
79 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();
83 ++m_it) {
84 Agent* supplier = m_it->first.first->manager();
85 Agent* requester = m_it->first.second->manager();
86 typename std::vector<std::pair<Trade<T>, typename T::Ptr>>& trades =
87 m_it->second;
88 typename std::vector<std::pair<Trade<T>, typename T::Ptr>>::iterator 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 if (rsrc->quantity() > cyclus::eps_rsrc()) {
93 ctx->NewDatum("Transactions")
94 ->AddVal("TransactionId", ctx->NextTransactionID())
95 ->AddVal("SenderId", supplier->id())
96 ->AddVal("ReceiverId", requester->id())
97 ->AddVal("ResourceId", rsrc->state_id())
98 ->AddVal("Commodity", trade.request->commodity())
99 ->AddVal("Time", ctx->time())
100 ->AddVal("Cost", 1 / trade.bid->preference())
101 ->Record();
102 }
103 }
104 }
105 }
106
107 inline const TradeExecutionContext<T>& trade_ctx() const {
108 return trade_ctx_;
109 }
110 inline TradeExecutionContext<T>& trade_ctx() { return trade_ctx_; }
111
112 private:
113 const std::vector<Trade<T>>& trades_;
114 TradeExecutionContext<T> trade_ctx_;
115};
116
117/// @brief populates suppliers_, requesters_, and trades_by_supplier_
118template <class T>
120 const std::vector<Trade<T>>& trades) {
121 typename std::vector<Trade<T>>::const_iterator it;
122 for (it = trades.begin(); it != trades.end(); ++it) {
123 trade_ctx.trades_by_supplier[it->bid->bidder()].push_back(*it);
124 trade_ctx.suppliers.insert(it->bid->bidder());
125 trade_ctx.requesters.insert(it->request->requester());
126 }
127}
128
129/// @brief queries each supplier for the responses to thier matched trade and
130/// populates trades_by_requester_ and all_trades_ with the results
131template <class T>
133 std::set<Trader*>::iterator it;
134 for (it = trade_ctx.suppliers.begin(); it != trade_ctx.suppliers.end();
135 ++it) {
136 // get responses
137 Trader* supplier = *it;
138 std::vector<std::pair<Trade<T>, typename T::Ptr>> responses;
139 PopulateTradeResponses(supplier, trade_ctx.trades_by_supplier[supplier],
140 responses);
141
142 // populate containers
143 typename std::vector<std::pair<Trade<T>, typename T::Ptr>>::iterator r_it;
144 for (r_it = responses.begin(); r_it != responses.end(); ++r_it) {
145 // @todo unsure if this is needed...
146 // Trade<T>& trade = r_it->first;
147 // typename T::Ptr rsrc= r_it->second;
148 // if (rsrc->quantity() != trade.amt) {
149 // throw ValueError("Trade amt and resource qty must match");
150 // }
151 Trader* requester = r_it->first.request->requester();
152 trade_ctx.trades_by_requester[requester].push_back(*r_it);
153 trade_ctx.all_trades[std::make_pair(supplier, requester)].push_back(
154 *r_it);
155 }
156 }
157}
158
159template <class T>
161 std::set<Trader*>::iterator it;
162 for (it = trade_ctx.requesters.begin(); it != trade_ctx.requesters.end();
163 ++it) {
164 Trader* requester = *it;
165 AcceptTrades(requester, trade_ctx.trades_by_requester[requester]);
166 }
167}
168
169} // namespace cyclus
170
171#endif // CYCLUS_SRC_TRADE_EXECUTOR_H_
The abstract base class used by all types of agents that live and interact in a simulation.
Definition agent.h:50
virtual const int id() const
The agent instance's unique ID within a simulation.
Definition agent.h:349
A simulation context provides access to necessary simulation-global functions and state.
Definition context.h:146
int NextTransactionID()
Definition context.h:321
Datum * NewDatum(std::string title)
See Recorder::NewDatum documentation.
Definition context.cc:351
virtual int time()
Returns the current simulation timestep.
Definition context.cc:314
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:21
void Record()
Record this datum to its Recorder.
Definition datum.cc:34
TradeExecutor(const std::vector< Trade< T > > &trades)
const TradeExecutionContext< T > & trade_ctx() const
TradeExecutionContext< T > & trade_ctx()
void ExecuteTrades(Context *ctx)
execute all trades, collecting responders from bidders and sending responses to requesters
void ExecuteTrades()
execute all trades, collecting responders from bidders and sending responses to requesters
void RecordTrades(Context *ctx)
Record all trades with the appropriate backends.
A simple API for agents that wish to exchange resources in the simulation.
Definition trader.h:24
taken directly from OsiSolverInterface.cpp on 2/17/14 from https://projects.coin-or....
Definition agent.cc:14
double eps_rsrc()
an epsilon value to be used by resources
Definition cyc_limits.h:19
static void PopulateTradeResponses(Trader *trader, const std::vector< Trade< T > > &trades, std::vector< std::pair< Trade< T >, typename T::Ptr > > &responses)
static void SendTradeResources(TradeExecutionContext< T > &trade_ctx)
static void AcceptTrades(Trader *trader, const 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_
static void GetTradeResponses(TradeExecutionContext< T > &trade_ctx)
queries each supplier for the responses to thier matched trade and populates trades_by_requester_ and...
void Warn(const std::string &msg)
Issue a warning with the approriate message, accoring to the current warning settings.
Definition error.h:108
std::map< std::pair< Trader *, Trader * >, std::vector< std::pair< Trade< T >, typename T::Ptr > > > all_trades
std::set< Trader * > requesters
std::map< Trader *, std::vector< std::pair< Trade< T >, typename T::Ptr > > > trades_by_requester
std::set< Trader * > suppliers
std::map< Trader *, std::vector< Trade< T > > > trades_by_supplier
A Trade is a simple container that associates a request for a resource with a bid for that resource.
Definition trade.h:15
Bid< T > * bid
Definition trade.h:17
Request< T > * request
Definition trade.h:16