#include "StockMarket.h" #include "Stock.h" #include "Order.h" #include #include #include class HigherPrice { public: bool operator() ( const Order* o1, const Order* o2 ) const { return ( o1->price() > o2->price() ); } }; class LowerPrice { public: bool operator() ( const Order* o1, const Order* o2 ) const { return ( o1->price() < o2->price() ); } }; void StockMarket::add( Stock* stock ) { stocks_.push_back( stock ); } void StockMarket::addSell( Order* order ) { orders_[ order->stock() ].sell.push_back( order ); } void StockMarket::addBuy( Order* order ) { orders_[ order->stock() ].buy.push_back( order ); } void StockMarket::doTask() { vector< Stock* >::iterator i; for( i = stocks_.begin(); i != stocks_.end(); i++ ) execute( * i ); } list::iterator StockMarket::topSell( Stock* stock ) { list & l = orders_[ stock ].sell; HigherPrice c; return max_element( l.begin(), l.end(), c ); } list::iterator StockMarket::topBuy( Stock* stock ) { list & l = orders_[ stock ].buy; LowerPrice c; return max_element( l.begin(), l.end(), c ); } void StockMarket::execute( Stock* stock ) { // cout << "*** Executing transactions ***" << endl; list::iterator i; // cancel expired orders vector::iterator> expiredBuy, expiredSell; list & buyList = orders_[ stock ].buy; list & sellList = orders_[ stock ].sell; for ( i = buyList.begin(); i != buyList.end(); i++ ) if ( (*i)->expired() ) expiredBuy.push_back( i ); for ( i = sellList.begin(); i != sellList.end(); i++ ) if ( (*i)->expired() ) expiredSell.push_back( i ); vector::iterator>::iterator j; for( j = expiredBuy.begin(); j != expiredBuy.end(); j++ ) { buyList.erase( *j ); delete **j; } for( j = expiredSell.begin(); j != expiredSell.end(); j++ ) { sellList.erase( *j ); delete **j; } // execute active orders double sum = 0; long volume = 0; while ( ! sellList.empty() && ! buyList.empty() ) { list::iterator isell = topSell( stock ); list::iterator ibuy = topBuy( stock ); Order * sell = * isell; Order * buy = * ibuy; if ( buy->price() < sell->price() ) break; long amount = min( buy->amount(), sell->amount() ); double price = sell->price(); if ( buy->execute( price, amount ) ) { sell->execute( price, amount ); sum += price * amount; volume += amount; // cout << "executed transaction: " << amount << " " << stock->symbol() // << " at $" << price << " ($" << buy->price() << ")" << endl; if ( buy->amount() == 0 ) { buyList.erase( ibuy ); delete buy; } if ( sell->amount() == 0 ) { sellList.erase( isell ); delete sell; } } } // update stock price history double price = stock->price(); if ( volume > 0 ) { price = sum / volume; } double gain = ( ( price - stock->price()) / stock->price() ) * 100; cout << stock->symbol() << ": $" << setprecision(7) << setw(8) << price << " (" << setprecision(7) << setw(8) << gain << "%)" << " volume: $" << setprecision(7) << setw(8) << volume*price << endl; stock->setPrice( price ); // notify active orders for ( i = buyList.begin(); i != buyList.end(); i++ ) (*i)->notify(); for ( i = sellList.begin(); i != sellList.end(); i++ ) (*i)->notify(); // cout << "*** End of transactions ***" << endl; }