void MarketLady::_centerTile() { ServiceWalker::_centerTile(); if( market().isValid() && market()->goodStore().empty() && !pathway().isReverse() ) { return2Base(); } }
void MarketLady::_updateThoughts() { if( pathway().isReverse() ) { if( market().isValid() && market()->goodStore().empty() ) { setThinks( "##marketLady_no_food_on_market##" ); return; } } ServiceWalker::_updateThoughts(); }
int main () { int j = 10; MultiMarket market(1); market.MarketCreateOrder(1, j); std::cout << j << std::endl; }
double MUPD::calc_mu_per_d( const SharedMember<Consumer::Differentiable> &con, Member::Lock &lock, id_t mkt_id, const allocation &alloc, const Bundle &b) const { if (mkt_id == 0) return con->d(b, money); auto sim = simulation(); auto mkt = sim->market(mkt_id); lock.add(mkt); double mu = 0.0; // Add together all of the marginal utilities weighted by the output level, since the market may // produce more than one good, and quantities may not equal 1. for (auto g : mkt->output_unit) mu += g.second * con->d(b, g.first); double q = alloc.quantity.count(mkt_id) ? alloc.quantity.at(mkt_id) : 0; auto pricing = mkt->price(q); lock.remove(mkt); if (!pricing.feasible) { throw market_exhausted_error(mkt_id); } return mu / pricing.marginal * price_ratio(mkt); }
MUPD::allocation MUPD::spending_allocation(const unordered_map<id_t, double> &spending) const { allocation a = {}; auto sim = simulation(); for (auto &m : spending) { if (m.second > 0) { if (m.first == 0) { // Holding cash a.bundle += money_unit * m.second; a.quantity[m.first] += m.second; } else { // Otherwise query the market for the resulting quantity auto mkt = sim->market(m.first); auto q = mkt->quantity(m.second * price_ratio(mkt)); a.quantity[m.first] = q.quantity; a.bundle += mkt->output_unit * q.quantity; if (q.constrained) { // The market is constrained, so add any leftover (unspent) money back into the // bundle a.constrained.insert(mkt->id()); a.bundle += mkt->price_unit * q.unspent; a.quantity[0] += q.unspent / price_ratio(mkt); } } } } return a; }
KRecord Stock ::getKRecord(size_t pos, KQuery::KType kType) const { //if (!m_data) // return KRecord(); if (m_data->pKData[kType]) return m_data->pKData[kType]->at(pos); return m_kdataDriver->getKRecord(market(), code(), pos, kType); }
size_t Stock::getCount(KQuery::KType kType) const { if (!m_data || kType >= KQuery::INVALID_KTYPE) return 0; if (m_data->pKData[kType]) return m_data->pKData[kType]->size(); return m_kdataDriver->getCount(market(), code(), kType); }
string Stock::toString() const { std::stringstream os; string strip(", "); StockManager& sm = StockManager::instance(); StockTypeInfo typeInfo(sm.getStockTypeInfo(type())); os << "Stock(" << market() << strip << code() << strip << name() << strip << typeInfo.description() << strip << valid() << strip << startDatetime() << strip << lastDatetime() << ")"; return os.str(); }
void Game:: turn () { char str [10] = "turn"; q.sendstr (str); waitendturn (); // new month readqueue (); getinfo (); if ( active_players () >= 2 ) { market (); } }
HKU_API std::ostream & operator<<(std::ostream& os, const PositionRecord& record) { Stock stock = record.stock; int precision = 2; std::string market(""), code(""), name(""); if(!stock.isNull()){ market = stock.market(); code = stock.code(); #if defined(BOOST_WINDOWS) && (PY_VERSION_HEX >= 0x03000000) name = utf8_to_gb(stock.name()); #else name = stock.name(); #endif } else { precision = stock.precision(); } price_t costPrice = 0.0; if (record.number != 0.0) { costPrice = roundEx((record.buyMoney - record.sellMoney) / record.number, precision); } string strip(", "); os << std::fixed; os.precision(precision); os << "Position(" << market << strip << code << strip << name << strip << record.takeDatetime << strip << record.cleanDatetime << strip << record.number << strip << costPrice << strip << record.stoploss << strip << record.goalPrice << strip << record.totalNumber << strip << record.buyMoney << strip << record.totalCost << strip << record.totalRisk << strip << record.sellMoney << ")"; os.unsetf(std::ostream::floatfield); os.precision(); return os; }
void Game:: login (char * nick, char * mode, int num) { setnick (nick); if ( strcmp (mode, "create") == 0) { create (); waitplayers (num); } else if ( strcmp (mode, "join") == 0) { joinroom (num); waitstart (); } else { printf ("Error in check mode. [ %s ].\n", mode ); exit (EXIT_FAILURE); } startinfo (); market (); }
string PositionRecord::toString() const { int precision = 2; std::string market(""), code(""), name(""); if(!stock.isNull()){ market = stock.market(); code = stock.code(); name = stock.name(); } else { precision = stock.precision(); } price_t costPrice = 0.0; if (number != 0.0) { costPrice = roundEx((buyMoney - sellMoney) / number, precision); } string strip(", "); std::stringstream os; os << std::fixed; os.precision(precision); os << "Position(" << market << strip << code << strip << name << strip << takeDatetime << strip << cleanDatetime << strip << number << strip << costPrice << strip << stoploss << strip << goalPrice << strip << totalNumber << strip << buyMoney << strip << totalCost << strip << totalRisk << strip << sellMoney << ")"; os.unsetf(std::ostream::floatfield); os.precision(); return os.str(); }
int main() { std::cout << "----------------------------------------------" << std::endl; std::cout << "- Algorithmic Asset Allocation -" << std::endl; std::cout << "----------------------------------------------" << std::endl; std::cout << std::endl; // Get algorithm std::string algorithm = "PGPE"; // Get file with parameter values std::string parametersFilepath = "/home/pierpaolo/Documents/University/6_Anno_Poli/7_Thesis/Data/Parameters/Single_Synth_RN_P0_F0_S0_N5.pot"; // Read input file path const std::string inputFile = "/home/pierpaolo/Documents/University/6_Anno_Poli/7_Thesis/Data/Input/synthetic.csv"; // Read output directory path const std::string outputDir = "/home/pierpaolo/Documents/University/6_Anno_Poli/7_Thesis/Data/Output/Default/"; // Read debug directory path const std::string debugDir = "/home/pierpaolo/Documents/University/6_Anno_Poli/7_Thesis/Data/Debug/Default/"; //---------------| // 1) Parameters | //---------------| // 1) Read parameters std::cout << "1) Read parameters" << std::endl; const ExperimentParameters params(parametersFilepath, true); // Copy parameters double riskFreeRate = params.riskFreeRate; double deltaP = params.deltaP; double deltaF = params.deltaF; double deltaS = params.deltaS; size_t numDaysObserved = params.numDaysObserved; double lambda = params.lambda; double alphaConstActor = params.alphaConstActor; double alphaExpActor = params.alphaExpActor; double alphaConstCritic = params.alphaConstCritic; double alphaExpCritic = params.alphaExpCritic; double alphaConstBaseline = params.alphaConstBaseline; double alphaExpBaseline = params.alphaExpBaseline; size_t numExperiments = params.numExperiments; size_t numEpochs = params.numEpochs; size_t numTrainingSteps = params.numTrainingSteps; size_t numTestSteps = params.numTestSteps; //-------------------| // 2) Initialization | //-------------------| std::cout << std::endl << "2) Initialization" << std::endl; //----------------------| // 2.1) Market and Task | //----------------------| // Market std::cout << ".. Market environment - "; MarketEnvironment market(inputFile); size_t startDate = 0; size_t endDate = numDaysObserved + numTrainingSteps + numTestSteps - 1; market.setEvaluationInterval(startDate, endDate); std::cout << "done" << std::endl; // Asset allocation task std::cout << ".. Asset allocation task - "; AssetAllocationTask task(market, riskFreeRate, deltaP, deltaF, deltaS, numDaysObserved); std::cout << "done" << std::endl; //------------| // 2.2) Agent | //------------| // Learning Rates std::cout << ".. Learning Rates - "; DecayingLearningRate baselineLearningRate(alphaConstBaseline, alphaExpBaseline); DecayingLearningRate criticLearningRate(alphaConstCritic, alphaExpCritic); DecayingLearningRate actorLearningRate(alphaConstActor, alphaExpActor); std::cout << "done" << std::endl; // Initialize Agent factory auto & factory(FactoryOfAgents::instance(task.getDimObservation(), baselineLearningRate, criticLearningRate, actorLearningRate, lambda)); // Pointer to Agent for poymorphic object handling std::unique_ptr<Agent> agentPtr = factory.make(algorithm); //----------------------------------| // 2.3) Asset Allocation Experiment | //----------------------------------| std::cout << ".. Asset allocation experiment - "; AssetAllocationExperiment experiment(task, *agentPtr, numExperiments, numEpochs, numTrainingSteps, numTestSteps, outputDir, debugDir); std::cout << "done" << std::endl; //-------------------| // 3) Run experiment | //-------------------| std::cout << std::endl << "2) Experiment" << std::endl; experiment.run(); return 0; }
void MUPD::intraOptimize() { auto sim = simulation(); // Before bothering with anything else, make sure the consumer actually has some money to spend { auto lock = con->readLock(); if (con->assets[money] <= 0) return; } unordered_map<id_t, double> spending; spending[0] = 0.0; // 0 is the "don't spend"/"hold cash" option for (auto &market : sim->markets()) { auto mlock = market->readLock(); if (not(market->price_unit.covers(money_unit) and money_unit.covers(market->price_unit))) { // price_unit is not (or not just) money; we can't handle that, so ignore this market continue; } if (market->output_unit[money] > 0) { // Something screwy about this market: it costs money, but also produces money. Ignore. continue; } if (not market->price(0).feasible) { // The market cannot produce any output (i.e. it is exhausted/constrained), so don't // consider it. continue; } // We assign an exact value later, once we know how many eligible markets there are. spending[market->id()] = 0.0; } unsigned int markets = spending.size()-1; // -1 to account for the cash non-market (id=0) // If there are no viable markets, there's nothing to do. if (markets == 0) return; // Now hold a write lock on this optimizer and the consumer. We'll add and remove market locks to this as needed. auto big_lock = writeLock(con); markets = spending.size()-1; // -1 for the id=0 cash pseudo-market if (markets == 0) return; Bundle &a = con->assets; Bundle a_no_money = a; double cash = a_no_money.remove(money); if (cash <= 0) { // No money (there was before, so something external changed), nothing to do. return; } // Start out with equal spending in every market, no spending in the 0 (don't spend) // pseudo-market for (auto &m : spending) { if (m.first != 0) m.second = cash / markets; } unordered_map <id_t, double> mu_per_d; allocation final_alloc = {}; while (true) { while (true) { try { allocation alloc = spending_allocation(spending); Bundle tryout = a_no_money + alloc.bundle; for (auto m : spending) { mu_per_d[m.first] = calc_mu_per_d(con, big_lock, m.first, alloc, tryout); } id_t highest = 0, lowest = 0; double highest_u = mu_per_d[0], lowest_u = std::numeric_limits<double>::infinity(); for (auto m : mu_per_d) { // Consider all markets (even eligible ones that we aren't currently spending in) for // best return, but exclude markets that are constrained (since we can't spend any more // in them). // FIXME: do this last bit? if (m.second > highest_u) { highest = m.first; highest_u = m.second; } // Only count markets where we are actually spending positive amounts as "lowest", since // we can't transfer away from a market without any expenditure. if (spending[m.first] > 0 and m.second < lowest_u) { lowest = m.first; lowest_u = m.second; } } if (highest_u <= lowest_u or (highest_u - lowest_u) / highest_u < tolerance) { final_alloc = alloc; break; // Nothing more to optimize } double baseU = con->utility(tryout); // Attempt to transfer all of the low utility spending to the high-utility market. If MU/$ // are equal, we're done; if the lower utility is still lower, transfer 3/4, otherwise // transfer 1/4. Repeat. // // We do have to be careful, however: transferring everything might screw things up (e.g. // consider u = xyz^2: setting z=0 will result in MU=0 for all three goods. So we need to // check not just the marginal utilities, but that this reallocation actually increases // overall utility. unordered_map<id_t, double> try_spending = spending; try_spending[highest] = spending[highest] + spending[lowest]; try_spending[lowest] = 0; alloc = spending_allocation(try_spending); tryout = a_no_money + alloc.bundle; if (con->utility(tryout) < baseU or calc_mu_per_d(con, big_lock, highest, alloc, tryout) < calc_mu_per_d(con, big_lock, lowest, alloc, tryout)) { // Transferring *everything* from lowest to highest is too much (MU/$ for the highest // good would end up lower than the lowest good, post-transfer, or else overall utility // goes down entirely). // // We need to transfer less than everything, so use a binary search to figure out the // optimum transfer. // // Take 10 binary steps (which means we get granularity of 1/1024). However, since // we'll probably come in here again (comparing this good to other goods) before // optimize() finishes, this gets amplified. // // FIXME: this is a very good target for optimization; typically this loop will run // around 53 times (which makes perfect sense, as that's about where step_size runs off // the end of the least precise double bit--sometimes a bit more, if the transfer ratio // is a very small number). double step_size = 0.25; double last_transfer = 1.0; double transfer = 0.5; for (int i = 0; transfer != last_transfer and i < 100; ++i) { last_transfer = transfer; double pre_try_h = try_spending[highest], pre_try_l = try_spending[lowest]; try_spending[highest] = spending[highest] + transfer * spending[lowest]; try_spending[lowest] = (1-transfer) * spending[lowest]; if (try_spending[highest] == pre_try_h and try_spending[lowest] == pre_try_l) { // The transfer is too small to numerically affect things, so we're done. break; } alloc = spending_allocation(try_spending); tryout = a_no_money + alloc.bundle; double delta = calc_mu_per_d(con, big_lock, highest, alloc, tryout) - calc_mu_per_d(con, big_lock, lowest, alloc, tryout); if (delta == 0) // We equalized MU/$. Done. break; else if (delta > 0) // MU/$ is still higher for `highest', so transfer more transfer += step_size; else // Otherwise transfer less transfer -= step_size; // Eventually this step_size will become too small to change transfer step_size /= 2; } } final_alloc = alloc; if (spending[highest] == try_spending[highest] or spending[lowest] == try_spending[lowest]) { // What we just identified isn't actually a change, probably because we're hitting the // boundaries of storable double values, so end. break; } spending[highest] = try_spending[highest]; spending[lowest] = try_spending[lowest]; } catch (market_exhausted_error &e) { // One of the markets has become exhausted. If it's completely exhausted, take it out // of the spending set; otherwise just restart the whole thing (the new limit will be // taken care of in the initial spending_allocation() call). if (not sim->market(e.market)->price(0).feasible) { // Completely exhausted market: transfer its spending to cash spending[0] += spending[e.market]; spending.erase(e.market); markets = spending.size() - 1; if (markets == 0) return; } } } // Safety check: make sure we're actually increasing utility; if not, don't do anything. if (con->utility(a_no_money + final_alloc.bundle) <= con->currUtility()) { return; } // If we haven't held back on any spending, add a tiny fraction of the amount of cash we are // spending to assets (to prevent numerical errors causing insufficient assets exceptions), then // subtract it off (if possible) after reserving. double extra = 0; if (spending[0] == 0.0) { extra = cash * 1e-13; a += extra * money_unit; } bool restart = false; // Will become true if a reservation fails for (auto &m : final_alloc.quantity) { if (m.first != 0 and m.second > 0) { auto market = sim->market(m.first); big_lock.add(market); try { reservations.push_front(market->reserve(con, m.second)); } catch (Market::output_infeasible &e) { restart = true; } catch (Market::insufficient_assets &e) { restart = true; } big_lock.remove(market); if (restart) break; } } if (extra > 0) { // Subtract up to 2 times the tiny extra amount. Thus for [0,extra) we're handling // numerical imprecision that resulted in the reservations taking slightly more than was // available; for (extra,2*extra] we're correcting for reservations taking not quite // enough. In either case, extra is a very small number (1e-13 times the money we // started with--i.e. 10 cents for a trillionaire); this is mainly just cleaning up to // have nice 0 values in assets instead of stupidly small values. if (2*extra >= a[money]) a.set(money, 0); else a -= extra * money_unit; } if (not restart) break; // Else abort any established reservations and repeat the entire loop reservations.clear(); } }
double Book::price() const { return hasAnyMarket() ? market()->price() : std::numeric_limits<double>::quiet_NaN(); }