summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2012-03-04 05:22:30 -0600
committerJohn Wiegley <johnw@newartisans.com>2012-03-05 05:03:52 -0600
commit5d8cb30774cf630cddd26407202c1cad8568bbef (patch)
treec97ae3166261d9a0feb78144d380d8cc78f743dd /src
parente9108783122ae4d775046ced646b14552f1e184d (diff)
downloadfork-ledger-5d8cb30774cf630cddd26407202c1cad8568bbef.tar.gz
fork-ledger-5d8cb30774cf630cddd26407202c1cad8568bbef.tar.bz2
fork-ledger-5d8cb30774cf630cddd26407202c1cad8568bbef.zip
Implemented first cut at price conversion logic
Diffstat (limited to 'src')
-rw-r--r--src/commodity.cc4
-rw-r--r--src/history.cc152
-rw-r--r--src/history.h26
-rw-r--r--src/report.cc7
-rw-r--r--src/system.hh.in2
5 files changed, 118 insertions, 73 deletions
diff --git a/src/commodity.cc b/src/commodity.cc
index a01847c5..5e55db31 100644
--- a/src/commodity.cc
+++ b/src/commodity.cc
@@ -96,7 +96,9 @@ commodity_t::find_price(const optional<commodity_t&>& commodity,
target = *pool().default_commodity;
optional<price_point_t> point =
- pool().commodity_price_history.find_price(*this, when, oldest, target);
+ target ?
+ pool().commodity_price_history.find_price(*this, *target, when, oldest) :
+ pool().commodity_price_history.find_price(*this, when, oldest);
if (pair) {
if (base->price_map.size() > base_t::max_price_map_size) {
diff --git a/src/history.cc b/src/history.cc
index c92a0102..a3d9139b 100644
--- a/src/history.cc
+++ b/src/history.cc
@@ -85,19 +85,50 @@ void commodity_history_t::remove_price(const commodity_t& source,
}
optional<price_point_t>
-commodity_history_t::find_price(const commodity_t& source,
- const datetime_t& moment,
- const optional<datetime_t>& oldest,
- const optional<commodity_t&>& target)
+commodity_history_t::find_price(const commodity_t& source,
+ const datetime_t& moment,
+ const optional<datetime_t>& oldest)
{
vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
- // jww (2012-03-04): What to do when target is null? In that case,
- // should we just return whatever is the most recent price for that
- // commodity?
- vertex_descriptor tv = vertex(*target->graph_index(), price_graph);
// Filter out edges which came into being after the reference time
+ FGraph fg(price_graph,
+ recent_edge_weight<EdgeWeightMap, PricePointMap, PriceRatioMap>
+ (get(edge_weight, price_graph), pricemap, ratiomap,
+ moment, oldest));
+
+ datetime_t most_recent = moment;
+ amount_t price;
+
+ graph_traits<FGraph>::adjacency_iterator f_vi, f_vend;
+ for (tie(f_vi, f_vend) = adjacent_vertices(sv, fg); f_vi != f_vend; ++f_vi) {
+ std::pair<Graph::edge_descriptor, bool> edgePair = edge(sv, *f_vi, fg);
+ Graph::edge_descriptor edge = edgePair.first;
+
+ const price_point_t& point(get(pricemap, edge));
+
+ if (price.is_null() || point.when > most_recent) {
+ most_recent = point.when;
+ price = point.price;
+ }
+ }
+
+ if (price.is_null())
+ return none;
+ else
+ return price_point_t(most_recent, price);
+}
+
+optional<price_point_t>
+commodity_history_t::find_price(const commodity_t& source,
+ const commodity_t& target,
+ const datetime_t& moment,
+ const optional<datetime_t>& oldest)
+{
+ vertex_descriptor sv = vertex(*source.graph_index(), price_graph);
+ vertex_descriptor tv = vertex(*target.graph_index(), price_graph);
+ // Filter out edges which came into being after the reference time
FGraph fg(price_graph,
recent_edge_weight<EdgeWeightMap, PricePointMap, PriceRatioMap>
(get(edge_weight, price_graph), pricemap, ratiomap,
@@ -118,6 +149,8 @@ commodity_history_t::find_price(const commodity_t& source,
datetime_t least_recent = moment;
amount_t price;
+ FNameMap ptrs = get(vertex_name, fg);
+
vertex_descriptor v = tv;
for (vertex_descriptor u = predecessorMap[v];
u != v;
@@ -128,70 +161,73 @@ commodity_history_t::find_price(const commodity_t& source,
const price_point_t& point(get(pricemap, edge));
+ const commodity_t * last_source = &source;
+
+ bool first_run = false;
if (price.is_null()) {
least_recent = point.when;
price = point.price;
+ first_run = true;
}
- else if (point.when < least_recent)
+ else if (point.when < least_recent) {
least_recent = point.when;
+ }
- // jww (2012-03-04): TODO
- //price *= point.price;
- }
-
- return price_point_t(least_recent, price);
-}
+ DEBUG("history.find", "u commodity = " << get(ptrs, u)->symbol());
+ DEBUG("history.find", "v commodity = " << get(ptrs, v)->symbol());
+ DEBUG("history.find", "last source = " << last_source->symbol());
-#if 0
- print_vertices(fg, f_commmap);
- print_edges(fg, f_commmap);
- print_graph(fg, f_commmap);
-
- graph_traits<FGraph>::vertex_iterator f_vi, f_vend;
- for(tie(f_vi, f_vend) = vertices(fg); f_vi != f_vend; ++f_vi)
- std::cerr << get(f_commmap, *f_vi) << " is in the filtered graph"
- << std::endl;
-
- for (tie(f_vi, f_vend) = vertices(fg); f_vi != f_vend; ++f_vi) {
- std::cerr << "distance(" << get(f_commmap, *f_vi) << ") = "
- << distanceMap[*f_vi] << ", ";
- std::cerr << "parent(" << get(f_commmap, *f_vi) << ") = "
- << get(f_commmap, predecessorMap[*f_vi])
- << std::endl;
- }
+ // Determine which direction we are converting in
+ amount_t pprice(point.price);
+ DEBUG("history.find", "pprice = " << pprice);
- // Write shortest path
- FCommMap f_commmap = get(vertex_comm, fg);
+ DEBUG("history.find", "price was = " << price);
+ if (! first_run) {
+ if (pprice.commodity() == *last_source)
+ price *= pprice.inverted();
+ else
+ price *= pprice;
+ }
+ else if (price.commodity() == *last_source) {
+ price = price.inverted();
+ }
+ DEBUG("history.find", "price is = " << price);
- std::cerr << "Shortest path from CAD to EUR:" << std::endl;
- for (PathType::reverse_iterator pathIterator = path.rbegin();
- pathIterator != path.rend();
- ++pathIterator)
- {
- std::cerr << get(f_commmap, source(*pathIterator, fg))
- << " -> " << get(f_commmap, target(*pathIterator, fg))
- << " = " << get(edge_weight, fg, *pathIterator)
- << std::endl;
+ if (*last_source == *get(ptrs, v))
+ last_source = get(ptrs, u);
+ else
+ last_source = get(ptrs, v);
}
- std::cerr << std::endl;
- std::cerr << "Distance: " << distanceMap[vd4] << std::endl;
-#endif
+ price.set_commodity(const_cast<commodity_t&>(target));
+ DEBUG("history.find", "final price is = " << price);
-#if 0
- #include <boost/graph/graphviz.hpp>
+ if (price.is_null())
+ return none;
+ else
+ return price_point_t(least_recent, price);
+}
- // Writing graph to file
- {
- std::ofstream f("test.dot");
-
- dynamic_properties p;
- p.property("label", get(edge_weight, g));
- p.property("weight", get(edge_weight, g));
- p.property("node_id", get(vertex_comm, g));
- write_graphviz(f,g,p);
- f.close();
+void commodity_history_t::print_map(std::ostream& out,
+ const optional<datetime_t>& moment)
+{
+#if 0
+ dynamic_properties p;
+ p.property("label", get(edge_weight, price_graph));
+ p.property("weight", get(edge_weight, price_graph));
+ p.property("node_id", get(vertex_index, price_graph));
+
+ if (moment) {
+ // Filter out edges which came into being after the reference time
+ FGraph fg(price_graph,
+ recent_edge_weight<EdgeWeightMap, PricePointMap, PriceRatioMap>
+ (get(edge_weight, price_graph), pricemap, ratiomap,
+ *moment));
+ write_graphviz(out, fg, p);
+ } else {
+ write_graphviz(out, price_graph, p);
}
#endif
+}
} // namespace ledger
diff --git a/src/history.h b/src/history.h
index f94d12c3..70831445 100644
--- a/src/history.h
+++ b/src/history.h
@@ -83,18 +83,20 @@ public:
reftime(_reftime), oldest(_oldest) { }
template <typename Edge>
- bool operator()(const Edge& e) const {
+ bool operator()(const Edge& e) const
+ {
const price_map_t& prices(get(ratios, e));
+ if (prices.empty())
+ return false;
+
price_map_t::const_iterator low = prices.upper_bound(reftime);
- if (prices.empty() ||
- (low != prices.end() && low == prices.begin())) {
+ if (low != prices.end() && low == prices.begin()) {
return false;
} else {
- if (low == prices.end())
- --low;
+ --low;
assert(((*low).first <= reftime));
- if (oldest && (*low).first <= *oldest)
+ if (oldest && (*low).first < *oldest)
return false;
long secs = (reftime - (*low).first).total_seconds();
@@ -175,8 +177,16 @@ public:
optional<price_point_t>
find_price(const commodity_t& source,
const datetime_t& moment,
- const optional<datetime_t>& oldest = none,
- const optional<commodity_t&>& commodity = none);
+ const optional<datetime_t>& oldest = none);
+
+ optional<price_point_t>
+ find_price(const commodity_t& source,
+ const commodity_t& target,
+ const datetime_t& moment,
+ const optional<datetime_t>& oldest = none);
+
+ void print_map(std::ostream& out,
+ const optional<datetime_t>& moment = none);
};
} // namespace ledger
diff --git a/src/report.cc b/src/report.cc
index 689028d0..2d825751 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -878,12 +878,9 @@ value_t report_t::echo_command(call_scope_t& args)
value_t report_t::pricemap_command(call_scope_t& args)
{
std::ostream& out(output_stream);
-#if 0
- // jww (2012-03-04): TODO
- commodity_pool_t::current_pool->print_pricemap
- (out, what_to_keep(), args.has<string>(0) ?
+ commodity_pool_t::current_pool->commodity_price_history.print_map
+ (out, args.has<string>(0) ?
optional<datetime_t>(datetime_t(parse_date(args.get<string>(0)))) : none);
-#endif
return true;
}
diff --git a/src/system.hh.in b/src/system.hh.in
index 8f684486..5e5a0c1d 100644
--- a/src/system.hh.in
+++ b/src/system.hh.in
@@ -157,7 +157,7 @@ typedef std::ostream::pos_type ostream_pos_type;
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
-#include <boost/graph/graph_utility.hpp>
+#include <boost/graph/graphviz.hpp>
#include <boost/intrusive_ptr.hpp>