/** Adds or updates an element in stock history */ int Model_CurrencyHistory::addUpdate(const int& currencyID, const wxDate& date, double price, UPDTYPE type) { Data *currHist = this->get(currencyID, date); if (!currHist) currHist = this->create(); currHist->CURRENCYID = currencyID; currHist->CURRDATE = date.FormatISODate(); currHist->CURRVALUE = price; currHist->CURRUPDTYPE = type; return save(currHist); }
int DB_Init_Model::Add_Asset(const wxString& name, const wxDate& date, double value, Model_Asset::TYPE asset_type, Model_Asset::RATE value_change, double value_change_rate, const wxString& notes) { Model_Asset::Data* entry = Model_Asset::instance().create(); entry->ASSETNAME = name; entry->STARTDATE = date.FormatISODate(); entry->VALUE = value; entry->VALUECHANGE = Model_Asset::all_rate()[value_change]; entry->VALUECHANGERATE = value_change_rate; entry->ASSETTYPE = Model_Asset::all_type()[asset_type]; entry->NOTES = notes; return Model_Asset::instance().save(entry); }
int DB_Init_Model::Add_Stock_Entry(int account_id, const wxDate& purchase_date, double num_shares, double purchase_price, double commission, double current_price, double value, const wxString& stock_name, const wxString& stock_symbol, const wxString& notes) { Model_Stock::Data* entry = Model_Stock::instance().create(); entry->HELDAT = account_id; entry->PURCHASEDATE = purchase_date.FormatISODate(); entry->NUMSHARES = num_shares; entry->PURCHASEPRICE = purchase_price; entry->STOCKNAME = stock_name; entry->SYMBOL = stock_symbol; entry->NOTES = notes; entry->COMMISSION = commission; entry->CURRENTPRICE = current_price == 0 ? purchase_price : current_price; entry->VALUE = value == 0 ? purchase_price * num_shares : value; return Model_Stock::instance().save(entry); }
double Model_Asset::value(const Data* r) { double sum = r->VALUE; wxDate start_date = STARTDATE(r); const wxDate today = wxDate::Today(); double diff_time_in_years = 0; if (today.GetYear() == start_date.GetYear()) { wxDate::wxDateTime_t diff_days = today.GetDayOfYear() - start_date.GetDayOfYear(); diff_time_in_years = static_cast<double>(diff_days) / static_cast<double>(today.GetNumberOfDays(today.GetYear())); } else { int diff_years = today.GetYear() - start_date.GetYear(); if (today.GetDayOfYear() < start_date.GetDayOfYear()) { diff_years--; wxDate::wxDateTime_t diff_days = (wxDate::GetNumberOfDays(start_date.GetYear()) - start_date.GetDayOfYear()) + today.GetDayOfYear(); diff_time_in_years = static_cast<double>(diff_days) / static_cast<double>(today.GetNumberOfDays(today.GetYear())); } else { wxDate::wxDateTime_t diff_days = today.GetDayOfYear() - start_date.GetDayOfYear(); diff_time_in_years = static_cast<double>(diff_days) / static_cast<double>(wxDate::GetNumberOfDays(today.GetYear())); } diff_time_in_years += static_cast<double>(diff_years); } switch (rate(r)) { case RATE_NONE: break; case RATE_APPRECIATE: sum *= pow(1.0 + (r->VALUECHANGERATE / 100), diff_time_in_years); break; case RATE_DEPRECIATE: sum *= pow(1.0 - (r->VALUECHANGERATE / 100), diff_time_in_years); break; default: break; } return sum; }
DB_Table_CHECKINGACCOUNT_V1::TRANSDATE Model_Checking::TRANSDATE(const wxDate& date, OP op) { return DB_Table_CHECKINGACCOUNT_V1::TRANSDATE(date.FormatISODate(), op); }
DB_Table_CURRENCYHISTORY_V1::CURRDATE Model_CurrencyHistory::CURRDATE(const wxDate& date, OP op) { return DB_Table_CURRENCYHISTORY_V1::CURRDATE(date.FormatISODate(), op); }
double mmHistoryData::getDailyBalanceAt(const Model_Account::Data *account, const wxDate& date) { wxString strDate = date.FormatISODate(); std::map<int, double> totBalance; for (const auto & stock : *this) { if (stock.acctId != account->id()) continue; wxString precValueDate, nextValueDate; double valueAtDate = 0.0, precValue = 0.0, nextValue = 0.0; for (const auto & hist : stock.stockHist) { // test for the date requested if (hist.DATE == strDate) { valueAtDate = hist.VALUE; break; } // if not found, search for previous and next date if (precValue == 0.0 && hist.DATE < strDate) { precValue = hist.VALUE; precValueDate = hist.DATE; } if (hist.DATE > strDate) { nextValue = hist.VALUE; nextValueDate = hist.DATE; } // end conditions: prec value assigned and price date < requested date if (precValue != 0.0 && hist.DATE < strDate) break; } if (valueAtDate == 0.0) { // if previous not found but if the given date is after purchase date, takes purchase price if (precValue == 0.0 && date >= stock.purchaseDate) { precValue = stock.purchasePrice; precValueDate = stock.purchaseDateStr; } // if next not found and the accoung is open, takes previous date if (nextValue == 0.0 && Model_Account::status(account) == Model_Account::OPEN) { nextValue = precValue; nextValueDate = precValueDate; } if (precValue > 0.0 && nextValue > 0.0 && precValueDate >= stock.purchaseDateStr && nextValueDate >= stock.purchaseDateStr) valueAtDate = precValue; } totBalance[stock.stockId] += stock.numShares * valueAtDate; } double balance = 0.0; for (const auto& it : totBalance) balance += it.second; return balance; }
/** Returns the total stock balance at a given date */ double Model_Stock::getDailyBalanceAt(const Model_Account::Data *account, const wxDate& date) { wxString strDate = date.FormatISODate(); std::map<int, double> totBalance; Data_Set stocks = this->instance().find(HELDAT(account->id())); for (const auto & stock : stocks) { wxString precValueDate, nextValueDate; Model_StockHistory::Data_Set stock_hist = Model_StockHistory::instance().find(SYMBOL(stock.SYMBOL)); std::stable_sort(stock_hist.begin(), stock_hist.end(), SorterByDATE()); std::reverse(stock_hist.begin(), stock_hist.end()); double valueAtDate = 0.0, precValue = 0.0, nextValue = 0.0; for (const auto & hist : stock_hist) { // test for the date requested if (hist.DATE == strDate) { valueAtDate = hist.VALUE; break; } // if not found, search for previous and next date if (precValue == 0.0 && hist.DATE < strDate) { precValue = hist.VALUE; precValueDate = hist.DATE; } if (hist.DATE > strDate) { nextValue = hist.VALUE; nextValueDate = hist.DATE; } // end conditions: prec value assigned and price date < requested date if (precValue != 0.0 && hist.DATE < strDate) break; } if (valueAtDate == 0.0) { // if previous not found but if the given date is after purchase date, takes purchase price if (precValue == 0.0 && date >= PURCHASEDATE(stock)) { precValue = stock.PURCHASEPRICE; precValueDate = stock.PURCHASEDATE; } // if next not found and the accoung is open, takes previous date if (nextValue == 0.0 && Model_Account::status(account) == Model_Account::OPEN) { nextValue = precValue; nextValueDate = precValueDate; } if (precValue > 0.0 && nextValue > 0.0 && precValueDate >= stock.PURCHASEDATE && nextValueDate >= stock.PURCHASEDATE) valueAtDate = precValue; } totBalance[stock.id()] += stock.NUMSHARES * valueAtDate; } double balance = 0.0; for (const auto& it : totBalance) balance += it.second; return balance; }
DB_Table_ASSETS_V1::STARTDATE Model_Asset::STARTDATE(const wxDate& date, OP op) { return DB_Table_ASSETS_V1::STARTDATE(date.FormatISODate(), op); }
wxString mmReportChartStocks::getHTMLText() { mmHTMLBuilder hb; hb.init(); hb.addDivContainer(); hb.addHeader(2, title()); wxTimeSpan dtDiff = m_date_range->end_date() - m_date_range->start_date(); if (m_date_range->is_with_date() && dtDiff.GetDays() <= 366) hb.DisplayDateHeading(m_date_range->start_date(), m_date_range->end_date(), true); hb.addHorizontalLine(); int count = 0, heldAt = -1; bool pointDot = false, showGridLines = false; wxTimeSpan dist; wxDate precDateDt = wxInvalidDateTime; for (const auto& stock : Model_Stock::instance().all(Model_Stock::COL_HELDAT)) { int dataCount = 0, freq = 1; Model_StockHistory::Data_Set histData = Model_StockHistory::instance().find(Model_StockHistory::SYMBOL(stock.SYMBOL), Model_StockHistory::DATE(m_date_range->start_date(), GREATER_OR_EQUAL), Model_StockHistory::DATE(m_date_range->end_date(), LESS_OR_EQUAL)); std::stable_sort(histData.begin(), histData.end(), SorterByDATE()); if (histData.size() <= 30) showGridLines = pointDot = true; else if (histData.size() <= 366) showGridLines = true; else freq = histData.size() / 366; std::vector<ValueTrio> aData; for (const auto& hist : histData) { if (dataCount % freq == 0) { ValueTrio val; const wxDate dateDt = Model_StockHistory::DATE(hist); if (histData.size() <= 30) val.label = mmGetDateForDisplay(hist.DATE); else if (precDateDt.IsValid() && dateDt.GetMonth() != precDateDt.GetMonth()) val.label = dateDt.GetMonthName(dateDt.GetMonth()); else val.label = ""; val.amount = hist.VALUE; aData.push_back(val); precDateDt = dateDt; } dataCount++; } if (!aData.empty()) { hb.addDivRow(); Model_Account::Data* account = Model_Account::instance().get(stock.HELDAT); hb.addHeader(1, wxString::Format("%s - (%s)", stock.STOCKNAME, account->ACCOUNTNAME)); hb.addDivCol17_67(); hb.addLineChart(aData, stock.STOCKNAME, count, 1000, 400, pointDot, showGridLines, true); hb.endDiv(); hb.endDiv(); } heldAt = stock.HELDAT; count++; } hb.endDiv(); hb.end(); Model_Report::outputReportFile(hb.getHTMLText()); return ""; }