144 #include <irrxml/irrXML.hpp>
155 int32_t nReturnVal = 0;
168 if (!strcmp(
"market", xml->getNodeName())) {
170 SetScale(atol(xml->getAttributeValue(
"marketScale")));
171 m_lLastSalePrice = atol(xml->getAttributeValue(
"lastSalePrice"));
172 m_strLastSaleDate = xml->getAttributeValue(
"lastSaleDate");
174 const OTString strServerID(xml->getAttributeValue(
"serverID")),
175 strAssetTypeID(xml->getAttributeValue(
"assetTypeID")),
176 strCurrencyTypeID(xml->getAttributeValue(
"currencyTypeID"));
179 m_ASSET_TYPE_ID.
SetString(strAssetTypeID);
180 m_CURRENCY_TYPE_ID.
SetString(strCurrencyTypeID);
182 otOut <<
"\n\nMarket. Scale: " << m_lScale <<
"\n";
184 otWarn <<
" assetTypeID: " << strAssetTypeID
186 " currencyTypeID: " << strCurrencyTypeID
188 " ServerID: " << strServerID <<
"\n";
192 else if (!strcmp(
"offer", xml->getNodeName())) {
193 const OTString strDateAdded(xml->getAttributeValue(
"dateAdded"));
194 const int64_t lDateAdded =
195 strDateAdded.
Exists() ? strDateAdded.ToLong() : 0;
202 otErr <<
"Error in OTMarket::" << __FUNCTION__
203 <<
": offer field without value.\n";
208 m_CURRENCY_TYPE_ID, m_lScale);
213 AddOffer(
nullptr, *pOffer,
false, tDateAdded))
218 otWarn <<
"Successfully loaded offer and added to market.\n";
221 otErr <<
"Error adding offer to market while loading market.\n";
241 const OTString SERVER_ID(m_SERVER_ID), ASSET_TYPE_ID(m_ASSET_TYPE_ID),
242 CURRENCY_TYPE_ID(m_CURRENCY_TYPE_ID);
246 " assetTypeID=\"%s\"\n"
247 " currencyTypeID=\"%s\"\n"
248 " marketScale=\"%lld\"\n"
249 " lastSaleDate=\"%s\"\n"
250 " lastSalePrice=\"%lld\""
253 ASSET_TYPE_ID.Get(), CURRENCY_TYPE_ID.
Get(),
254 m_lScale, m_strLastSaleDate.c_str(),
258 for (
auto& it : m_mapAsks) {
266 int64_t lDateAddedToMarket =
270 "\">\n%s</offer>\n\n",
271 lDateAddedToMarket, ascOffer.
Get());
275 for (
auto& it : m_mapBids) {
283 int64_t lDateAddedToMarket =
287 "\">\n%s</offer>\n\n",
288 lDateAddedToMarket, ascOffer.
Get());
298 for (
auto& it : m_mapAsks) {
312 int32_t& nNymOfferCount)
320 for (
auto& it : m_mapOffers) {
335 std::unique_ptr<OTDB::OfferDataNym> pOfferData(
336 dynamic_cast<OTDB::OfferDataNym*>(
344 const int64_t& lScale = pOffer->
GetScale();
352 const OTString strServerID(theServerID);
354 const OTString strAssetID(theAssetID);
356 const OTString strAssetAcctID(theAssetAcctID);
358 const OTString strCurrencyID(theCurrencyID);
360 const OTString strCurrencyAcctID(theCurrencyAcctID);
362 const bool bSelling = pOffer->
IsAsk();
366 pOfferData->stop_sign =
">";
368 pOfferData->stop_sign =
"<";
370 if (!pOfferData->stop_sign.compare(
">") ||
371 !pOfferData->stop_sign.compare(
"<")) {
373 pOfferData->stop_price = to_string<int64_t>(lStopPrice);
377 pOfferData->transaction_id = to_string<int64_t>(lTransactionNum);
378 pOfferData->price_per_scale = to_string<int64_t>(lPriceLimit);
379 pOfferData->total_assets = to_string<int64_t>(lTotalAssets);
380 pOfferData->finished_so_far = to_string<int64_t>(lFinishedSoFar);
381 pOfferData->minimum_increment = to_string<int64_t>(lMinimumIncrement);
382 pOfferData->scale = to_string<int64_t>(lScale);
384 pOfferData->valid_from = to_string<time64_t>(tValidFrom);
385 pOfferData->valid_to = to_string<time64_t>(tValidTo);
387 pOfferData->date = to_string<time64_t>(tDateAddedToMarket);
389 pOfferData->server_id = strServerID.
Get();
390 pOfferData->asset_type_id = strAssetID.
Get();
391 pOfferData->asset_acct_id = strAssetAcctID.
Get();
392 pOfferData->currency_type_id = strCurrencyID.
Get();
393 pOfferData->currency_acct_id = strCurrencyAcctID.
Get();
395 pOfferData->selling = bSelling;
401 theOutputList.AddOfferDataNym(*pOfferData);
413 if (
nullptr == m_pTradeList) {
425 const size_t sizeList = m_pTradeList->GetTradeDataMarketCount();
426 nTradeCount =
static_cast<int32_t
>(sizeList);
428 if (nTradeCount == 0)
433 else if (nTradeCount > 0) {
442 std::unique_ptr<OTDB::PackedBuffer> pBuffer(pPacker->
Pack(
445 if (
nullptr == pBuffer) {
446 otErr <<
"Failed packing pTradeList in OTCron::GetRecentTradeList. "
453 const uint8_t* pUint =
static_cast<const uint8_t*
>(pBuffer->GetData());
454 const size_t theSize = pBuffer->GetSize();
456 if ((
nullptr != pUint) || (theSize < 2)) {
457 OTData theData(pUint, static_cast<uint32_t>(theSize));
466 otErr <<
"Error while getting buffer data in "
467 "OTMarket::GetRecentTradeList.\n";
470 otErr <<
"Error: nTradeCount with negative value in "
471 "OTMarket::GetRecentTradeList: " << nTradeCount <<
".\n";
479 int32_t& nOfferCount)
488 std::unique_ptr<OTDB::OfferListMarket> pOfferList(
489 dynamic_cast<OTDB::OfferListMarket*>(
497 int32_t nTempDepth = 0;
499 for (
auto& it : m_mapBids) {
500 if (nTempDepth++ > lDepth)
break;
507 if (0 == lPriceLimit)
511 std::unique_ptr<OTDB::BidData> pOfferData(dynamic_cast<OTDB::BidData*>(
519 pOfferData->transaction_id = to_string<int64_t>(lTransactionNum);
520 pOfferData->price_per_scale = to_string<int64_t>(lPriceLimit);
521 pOfferData->available_assets = to_string<int64_t>(lAvailableAssets);
522 pOfferData->minimum_increment = to_string<int64_t>(lMinimumIncrement);
523 pOfferData->date = to_string<time64_t>(tDateAddedToMarket);
529 pOfferList->AddBidData(*pOfferData);
535 for (
auto& it : m_mapAsks) {
536 if (nTempDepth++ > lDepth)
break;
542 std::unique_ptr<OTDB::AskData> pOfferData(dynamic_cast<OTDB::AskData*>(
551 pOfferData->transaction_id = to_string<int64_t>(lTransactionNum);
552 pOfferData->price_per_scale = to_string<int64_t>(lPriceLimit);
553 pOfferData->available_assets = to_string<int64_t>(lAvailableAssets);
554 pOfferData->minimum_increment = to_string<int64_t>(lMinimumIncrement);
555 pOfferData->date = to_string<time64_t>(tDateAddedToMarket);
561 pOfferList->AddAskData(*pOfferData);
567 if (nOfferCount == 0)
570 if (nOfferCount > 0) {
579 std::unique_ptr<OTDB::PackedBuffer> pBuffer(
580 pPacker->
Pack(*pOfferList));
582 if (
nullptr == pBuffer) {
583 otErr <<
"Failed packing pOfferList in OTCron::GetOfferList. \n";
589 const uint8_t* pUint =
static_cast<const uint8_t*
>(pBuffer->GetData());
590 const size_t theSize = pBuffer->GetSize();
592 if (
nullptr != pUint) {
593 OTData theData(pUint, static_cast<uint32_t>(theSize));
602 otErr <<
"Error while getting buffer data in "
603 "OTMarket::GetOfferList.\n";
606 otErr <<
"invalid: nOfferCount is < 0 in OTMarket::GetOfferList.\n";
626 auto it = m_mapOffers.find(lTransactionNum);
628 if (it == m_mapOffers.end()) {
641 otErr <<
"Expected Offer with transaction number "
642 << lTransactionNum <<
", but found "
652 bool bReturnValue =
false;
655 auto it = m_mapOffers.find(lTransactionNum);
658 if (it == m_mapOffers.end()) {
659 otErr <<
"Attempt to remove non-existent Offer from Market. "
660 "Transaction #: " << lTransactionNum <<
"\n";
672 m_mapOffers.erase(it);
685 for (mapOfOffers::iterator iii = pMap->begin(); iii != pMap->end();
687 pSameOffer = iii->second;
690 "nullptr offer pointer in OTMarket::RemoveOffer.\n");
701 pSameOffer =
nullptr;
704 if (
nullptr == pSameOffer) {
705 otErr <<
"Removed Offer from offers list, but not found on bid/ask "
724 pSameOffer =
nullptr;
748 otErr <<
"Failed attempt to add invalid offer to market.\n";
760 auto it = m_mapOffers.find(lTransactionNum);
763 if (it == m_mapOffers.end()) {
764 m_mapOffers[lTransactionNum] = &theOffer;
765 otLog4 <<
"Offer added as an offer to the market...\n";
769 otErr <<
"Attempt to add Offer to Market with pre-existing "
770 "transaction number: " << lTransactionNum <<
"\n";
782 if (theOffer.
IsBid()) {
787 m_mapBids.lower_bound(lPriceLimit),
790 std::pair<int64_t, OTOffer*>(lPriceLimit, &theOffer));
791 otLog4 <<
"Offer added as a bid to the market.\n";
795 m_mapAsks.upper_bound(lPriceLimit),
798 std::pair<int64_t, OTOffer*>(lPriceLimit, &theOffer));
799 otLog4 <<
"Offer added as an ask to the market.\n";
833 const char* szFilename = str_MARKET_ID.
Get();
837 if (bSuccess) bSuccess =
LoadContract(szFoldername, szFilename);
844 if (
nullptr != m_pTradeList)
delete m_pTradeList;
846 const char* szSubFolder =
"recent";
866 const char* szFilename = str_MARKET_ID.
Get();
879 otErr <<
"Error saving Market:\n" << szFoldername
886 if (
nullptr != m_pTradeList) {
887 const char* szSubFolder =
"recent";
893 otErr <<
"Error saving recent trades for Market:\n" << szFoldername
911 strTemp.
Format(
"ASSET TYPE:\n%s\nCURRENCY TYPE:\n%s\nMARKET SCALE:\n%lld\n",
912 strAsset.Get(), strCurrency.
Get(), lScale);
923 mapOfOffers::reverse_iterator rr = m_mapBids.rbegin();
925 if (rr != m_mapBids.rend()) {
938 auto it = m_mapAsks.begin();
940 if (it != m_mapAsks.end()) {
951 while (0 == lPrice) {
954 if (it == m_mapAsks.end())
break;
987 OTAccount& p2,
bool b2,
const int64_t& a2,
988 OTAccount& p3,
bool b3,
const int64_t& a3,
989 OTAccount& p4,
bool b4,
const int64_t& a4)
993 if (b3) p3.
Debit(a3);
994 if (b4) p4.
Debit(a4);
1032 "Offer was on the market, but somehow "
1033 "got into processing without a trade "
1042 "Somehow a Market is running even though "
1043 "there is no Server Nym on the Cron "
1044 "object authorizing the trades.");
1049 otOut <<
"Failed to process trades: Out of transaction numbers!\n";
1063 otLog5 <<
"Failed to process trades: they had account IDs in common.\n";
1111 bool bFirstNymIsServerNym =
1112 ((FIRST_NYM_ID == SERVER_NYM_ID) ?
true :
false);
1113 bool bOtherNymIsServerNym =
1114 ((OTHER_NYM_ID == SERVER_NYM_ID) ?
true :
false);
1118 bool bTradersAreSameNym = ((FIRST_NYM_ID == OTHER_NYM_ID) ?
true :
false);
1126 if (bFirstNymIsServerNym)
1129 pFirstNym = pServerNym;
1137 otErr <<
"Failure loading First Nym public key in OTMarket::"
1138 << __FUNCTION__ <<
": " << strNymID <<
"\n";
1150 pFirstNym = &theNym;
1154 otErr <<
"OTMarket::" << __FUNCTION__
1155 <<
": Failure verifying trade, offer, or nym, or loading "
1156 "signed Nymfile: " << strNymID <<
"\n";
1162 if (bOtherNymIsServerNym)
1165 pOtherNym = pServerNym;
1167 else if (bTradersAreSameNym)
1170 pOtherNym = pFirstNym;
1178 otErr <<
"Failure loading Other Nym public key in OTMarket::"
1179 << __FUNCTION__ <<
": " << strNymID <<
"\n";
1188 pOtherNym = &theOtherNym;
1192 otErr <<
"Failure loading or verifying Other Nym public key in "
1193 "OTMarket::" << __FUNCTION__ <<
": " << strNymID <<
"\n";
1237 if ((
nullptr == pFirstAssetAcct) || (
nullptr == pFirstCurrencyAcct)) {
1238 otOut <<
"ERROR verifying existence of one of the first trader's "
1239 "accounts during attempted Market trade.\n";
1241 pOtherAssetAcct, pOtherCurrencyAcct);
1245 else if ((
nullptr == pOtherAssetAcct) ||
1246 (
nullptr == pOtherCurrencyAcct)) {
1247 otOut <<
"ERROR verifying existence of one of the second trader's "
1248 "accounts during attempted Market trade.\n";
1250 pOtherAssetAcct, pOtherCurrencyAcct);
1263 (pFirstCurrencyAcct->GetAssetTypeID() !=
1267 otErr <<
"ERROR - First Trader has accounts of wrong "
1268 "asset types in OTMarket::" << __FUNCTION__ <<
"\n";
1270 pOtherAssetAcct, pOtherCurrencyAcct);
1274 else if ((pOtherAssetAcct->GetAssetTypeID() !=
1277 (pOtherCurrencyAcct->GetAssetTypeID() !=
1281 otErr <<
"ERROR - Other Trader has accounts of wrong "
1282 "asset types in OTMarket::" << __FUNCTION__ <<
"\n";
1284 pOtherAssetAcct, pOtherCurrencyAcct);
1294 else if ((!pFirstAssetAcct->
VerifyOwner(*pFirstNym) ||
1296 (!pFirstCurrencyAcct->VerifyOwner(*pFirstNym) ||
1297 !pFirstCurrencyAcct->VerifySignature(*pServerNym))) {
1298 otErr <<
"ERROR verifying ownership or signature on one of first "
1299 "trader's accounts in OTMarket::" << __FUNCTION__ <<
"\n";
1301 pOtherAssetAcct, pOtherCurrencyAcct);
1305 else if ((!pOtherAssetAcct->VerifyOwner(*pOtherNym) ||
1306 !pOtherAssetAcct->VerifySignature(*pServerNym)) ||
1307 (!pOtherCurrencyAcct->VerifyOwner(*pOtherNym) ||
1308 !pOtherCurrencyAcct->VerifySignature(*pServerNym))) {
1309 otErr <<
"ERROR verifying ownership or signature on one of other "
1310 "trader's accounts in OTMarket::" << __FUNCTION__ <<
"\n";
1312 pOtherAssetAcct, pOtherCurrencyAcct);
1337 theOtherCurrencyInbox(OTHER_NYM_ID,
1342 bool bSuccessLoadingFirstAsset = theFirstAssetInbox.
LoadInbox();
1343 bool bSuccessLoadingFirstCurrency = theFirstCurrencyInbox.LoadInbox();
1344 bool bSuccessLoadingOtherAsset = theOtherAssetInbox.LoadInbox();
1345 bool bSuccessLoadingOtherCurrency = theOtherCurrencyInbox.LoadInbox();
1349 if (
true == bSuccessLoadingFirstAsset)
1350 bSuccessLoadingFirstAsset =
1351 theFirstAssetInbox.VerifyAccount(*pServerNym);
1353 bSuccessLoadingFirstAsset = theFirstAssetInbox.GenerateLedger(
1357 if (
true == bSuccessLoadingFirstCurrency)
1358 bSuccessLoadingFirstCurrency =
1359 theFirstCurrencyInbox.VerifyAccount(*pServerNym);
1361 bSuccessLoadingFirstCurrency = theFirstCurrencyInbox.GenerateLedger(
1365 if (
true == bSuccessLoadingOtherAsset)
1366 bSuccessLoadingOtherAsset =
1367 theOtherAssetInbox.VerifyAccount(*pServerNym);
1369 bSuccessLoadingOtherAsset = theOtherAssetInbox.GenerateLedger(
1373 if (
true == bSuccessLoadingOtherCurrency)
1374 bSuccessLoadingOtherCurrency =
1375 theOtherCurrencyInbox.VerifyAccount(*pServerNym);
1377 bSuccessLoadingOtherCurrency = theOtherCurrencyInbox.GenerateLedger(
1381 if ((
false == bSuccessLoadingFirstAsset) ||
1382 (
false == bSuccessLoadingFirstCurrency)) {
1383 otErr <<
"ERROR loading or generating an inbox for first trader in "
1384 "OTMarket::" << __FUNCTION__ <<
".\n";
1386 pOtherAssetAcct, pOtherCurrencyAcct);
1390 else if ((
false == bSuccessLoadingOtherAsset) ||
1391 (
false == bSuccessLoadingOtherCurrency)) {
1392 otErr <<
"ERROR loading or generating an inbox for other trader in "
1393 "OTMarket::" << __FUNCTION__ <<
".\n";
1395 pOtherAssetAcct, pOtherCurrencyAcct);
1405 if (0 == lNewTransactionNumber) {
1406 otOut <<
"WARNING: Market is unable to process because there "
1407 "are no more transaction numbers available.\n";
1409 pOtherAssetAcct, pOtherCurrencyAcct);
1462 lNewTransactionNumber);
1466 lNewTransactionNumber);
1470 lNewTransactionNumber);
1474 lNewTransactionNumber);
1578 OTAccount* pAssetAccountToDebit =
nullptr;
1579 OTAccount* pAssetAccountToCredit =
nullptr;
1580 OTAccount* pCurrencyAccountToDebit =
nullptr;
1581 OTAccount* pCurrencyAccountToCredit =
nullptr;
1583 if (theOffer.
IsAsk())
1585 pAssetAccountToDebit = pFirstAssetAcct;
1588 pAssetAccountToCredit =
1591 pCurrencyAccountToDebit =
1594 pCurrencyAccountToCredit =
1600 pAssetAccountToDebit =
1603 pAssetAccountToCredit =
1606 pCurrencyAccountToDebit =
1609 pCurrencyAccountToCredit =
1616 int64_t lMinIncrementPerRound =
1622 const int64_t lMultiplier =
1623 (lMinIncrementPerRound /
GetScale());
1663 int64_t lTemp = lMostAvailable %
GetScale();
1667 lMostAvailable -= lTemp;
1682 const int64_t lOverallMultiplier =
1689 const int64_t lMostPrice =
1696 if ((pAssetAccountToDebit->
GetBalance() >= lMostAvailable) &&
1701 lMinIncrementPerRound = lMostAvailable;
1702 lPrice = lMostPrice;
1725 bool bSuccess =
false;
1727 int64_t lOfferFinished = 0,
1728 lOtherOfferFinished = 0,
1736 while ((lMinIncrementPerRound <=
1740 (lMinIncrementPerRound <=
1742 lOtherOfferFinished)) &&
1744 (lMinIncrementPerRound <=
1761 pAssetAccountToDebit->
Debit(lMinIncrementPerRound);
1762 bool bMove2 = pCurrencyAccountToDebit->
Debit(lPrice);
1764 pAssetAccountToCredit->
Credit(lMinIncrementPerRound);
1765 bool bMove4 = pCurrencyAccountToCredit->
Credit(lPrice);
1768 if (!bMove1 || !bMove2 || !bMove3 || !bMove4) {
1769 otErr <<
"Very strange! Funds were available, yet debit or "
1770 "credit failed while performing trade. "
1771 "Attempting rollback!\n";
1775 *pAssetAccountToDebit, bMove1, lMinIncrementPerRound,
1776 *pCurrencyAccountToDebit, bMove2, lPrice,
1777 *pAssetAccountToCredit, bMove3, lMinIncrementPerRound,
1778 *pCurrencyAccountToCredit, bMove4, lPrice);
1793 lOfferFinished += lMinIncrementPerRound;
1794 lOtherOfferFinished += lMinIncrementPerRound;
1796 lTotalPaidOut += lPrice;
1813 if (
true == bSuccess) {
1853 lOtherOfferFinished);
1879 if (
nullptr == m_pTradeList) {
1885 std::unique_ptr<OTDB::TradeDataMarket> pTradeData(
1889 const int64_t& lTransactionNum =
1892 const int64_t& lPriceLimit =
1894 const int64_t& lAmountSold = lOfferFinished;
1896 pTradeData->transaction_id =
1897 to_string<int64_t>(lTransactionNum);
1898 pTradeData->date = to_string<time64_t>(theDate);
1899 pTradeData->price = to_string<int64_t>(lPriceLimit);
1900 pTradeData->amount_sold = to_string<int64_t>(lAmountSold);
1902 m_strLastSaleDate = pTradeData->date;
1909 m_pTradeList->AddTradeDataMarket(*pTradeData);
1914 while (m_pTradeList->GetTradeDataMarketCount() >
1916 m_pTradeList->RemoveTradeDataMarket(0);
1992 "Signature was already verified on Trade when first "
1993 "added to market, but now it fails.\n");
1995 "Signature was already verified on Trade when first "
1996 "added to market, but now it fails.\n");
2005 OTString strOrigTrade(*pOrigTrade),
2006 strOrigOtherTrade(*pOrigOtherTrade);
2023 pOrigTrade =
nullptr;
2024 delete pOrigOtherTrade;
2025 pOrigOtherTrade =
nullptr;
2037 OTString strTrade(theTrade), strOtherTrade(*pOtherTrade),
2038 strOffer(theOffer), strOtherOffer(theOtherOffer);
2044 pItem3->
SetNote(strOtherTrade);
2045 pItem4->
SetNote(strOtherTrade);
2084 if (theOffer.
IsAsk())
2086 pItem1->
SetAmount(lOfferFinished * (-1));
2089 pItem4->
SetAmount(lTotalPaidOut * (-1));
2094 pItem2->
SetAmount(lTotalPaidOut * (-1));
2095 pItem3->
SetAmount(lOtherOfferFinished * (-1));
2099 if (
true == bSuccess) {
2130 theFirstAssetInbox.AddTransaction(*pTrans1);
2131 theFirstCurrencyInbox.AddTransaction(*pTrans2);
2132 theOtherAssetInbox.AddTransaction(*pTrans3);
2133 theOtherCurrencyInbox.AddTransaction(*pTrans4);
2137 theFirstAssetInbox.ReleaseSignatures();
2138 theFirstCurrencyInbox.ReleaseSignatures();
2139 theOtherAssetInbox.ReleaseSignatures();
2140 theOtherCurrencyInbox.ReleaseSignatures();
2143 theFirstAssetInbox.SignContract(*pServerNym);
2144 theFirstCurrencyInbox.SignContract(*pServerNym);
2145 theOtherAssetInbox.SignContract(*pServerNym);
2146 theOtherCurrencyInbox.SignContract(*pServerNym);
2149 theFirstAssetInbox.SaveContract();
2150 theFirstCurrencyInbox.SaveContract();
2151 theOtherAssetInbox.SaveContract();
2152 theOtherCurrencyInbox.SaveContract();
2159 pFirstAssetAcct->
SaveInbox(theFirstAssetInbox);
2160 pFirstCurrencyAcct->SaveInbox(theFirstCurrencyInbox);
2161 pOtherAssetAcct->SaveInbox(theOtherAssetInbox);
2162 pOtherCurrencyAcct->SaveInbox(theOtherCurrencyInbox);
2174 pFirstCurrencyAcct->ReleaseSignatures();
2175 pOtherAssetAcct->ReleaseSignatures();
2176 pOtherCurrencyAcct->ReleaseSignatures();
2178 pFirstCurrencyAcct->SignContract(*pServerNym);
2179 pOtherAssetAcct->SignContract(*pServerNym);
2180 pOtherCurrencyAcct->SignContract(*pServerNym);
2182 pFirstCurrencyAcct->SaveContract();
2183 pOtherAssetAcct->SaveContract();
2184 pOtherCurrencyAcct->SaveContract();
2186 pFirstCurrencyAcct->SaveAccount();
2187 pOtherAssetAcct->SaveAccount();
2188 pOtherCurrencyAcct->SaveAccount();
2195 otWarn <<
"Unable to perform trade in OTMarket::"
2196 << __FUNCTION__ <<
"\n";
2200 bool bFirstTraderIsBroke =
false, bOtherTraderIsBroke =
false;
2219 lMinIncrementPerRound) {
2220 OTItem* pTempItem =
nullptr;
2224 if (pAssetAccountToDebit == pFirstAssetAcct) {
2226 bFirstTraderIsBroke =
true;
2227 pTempTransaction = pTrans1;
2228 pTempInbox = &theFirstAssetInbox;
2238 bOtherTraderIsBroke =
true;
2239 pTempTransaction = pTrans3;
2240 pTempInbox = &theOtherAssetInbox;
2252 pTempTransaction->
AddItem(*pTempItem);
2279 if (pCurrencyAccountToDebit->
GetBalance() < lPrice) {
2280 OTItem* pTempItem =
nullptr;
2284 if (pCurrencyAccountToDebit == pFirstCurrencyAcct) {
2286 bFirstTraderIsBroke =
true;
2287 pTempTransaction = pTrans2;
2288 pTempInbox = &theFirstCurrencyInbox;
2298 bOtherTraderIsBroke =
true;
2299 pTempTransaction = pTrans4;
2300 pTempInbox = &theOtherCurrencyInbox;
2312 pTempTransaction->
AddItem(*pTempItem);
2348 pOtherCurrencyAcct);
2430 otOut <<
"OTMarket::" << __FUNCTION__ <<
": Removing offer from "
2431 "market. (Amount Available is "
2432 "less than Min Increment.)\n";
2436 int64_t lRelevantPrice = 0;
2453 if ((0 == lRelevantPrice) &&
2466 if ((0 == lRelevantPrice) ||
2485 if (theOffer.
IsAsk())
2493 for (mapOfOffers::reverse_iterator rr = m_mapBids.rbegin();
2494 rr != m_mapBids.rend(); ++rr) {
2582 for (
auto& it : m_mapAsks) {
2662 bool bValidOffer =
true;
2666 bValidOffer =
false;
2668 strReason.
Format(
"Wrong Server ID on offer. Expected %s, but found %s",
2669 strID.Get(), strOtherID.Get());
2672 bValidOffer =
false;
2674 strReason.
Format(
"Wrong Asset ID on offer. Expected %s, but found %s",
2675 strID.Get(), strOtherID.Get());
2678 bValidOffer =
false;
2682 "Wrong Currency ID on offer. Expected %s, but found %s",
2683 strID.Get(), strOtherID.Get());
2686 bValidOffer =
false;
2688 "Wrong Market Scale on offer. Expected %lld, but found %lld",
2695 bValidOffer =
false;
2696 strReason.
Format(
"Minimum Increment on offer is <= 0: %lld",
2700 bValidOffer =
false;
2701 strReason.
Format(
"Minimum Increment on offer (%lld) is less than "
2702 "market scale (%lld).",
2706 bValidOffer =
false;
2707 strReason.
Format(
"Minimum Increment on offer (%lld) Mod market scale "
2708 "(%lld) is not equal to zero.",
2712 bValidOffer =
false;
2714 "Minimum Increment on offer (%lld) is more than the amount of "
2715 "assets available for trade on that same offer (%lld).",
2720 otLog4 <<
"Offer is valid for market.\n";
2722 otOut << __FUNCTION__
2723 <<
": Offer is invalid for this market: " << strReason <<
"\n";
2725 if (
nullptr != pReason) *pReason = strReason;
2734 , m_pTradeList(nullptr)
2736 , m_lLastSalePrice(0)
2750 , m_pTradeList(nullptr)
2752 , m_lLastSalePrice(0)
2760 const OTIdentifier& CURRENCY_TYPE_ID,
const int64_t& lScale)
2763 , m_pTradeList(nullptr)
2765 , m_lLastSalePrice(0)
2770 m_ASSET_TYPE_ID = ASSET_TYPE_ID;
2771 m_CURRENCY_TYPE_ID = CURRENCY_TYPE_ID;
2773 m_SERVER_ID = SERVER_ID;
2798 if (
nullptr != m_pTradeList) {
2799 delete m_pTradeList;
2800 m_pTradeList =
nullptr;
2804 while (!m_mapBids.empty()) {
2805 OTOffer* pOffer = m_mapBids.begin()->second;
2806 m_mapBids.erase(m_mapBids.begin());
2810 while (!m_mapAsks.empty()) {
2811 OTOffer* pOffer = m_mapAsks.begin()->second;
2812 m_mapAsks.erase(m_mapAsks.begin());
const int64_t & GetMinimumIncrement()
EXPORT Storage * GetDefaultStorage()
OTLOG_IMPORT OTLogStream otLog4
int64_t GetNextTransactionNumber()
void SetAmount(int64_t lAmount)
EXPORT Storable * CreateObject(StoredObjectType eType)
EXPORT time64_t GetDateAddedToMarket() const
static EXPORT OTTransaction * GenerateTransaction(const OTIdentifier &theUserID, const OTIdentifier &theAccountID, const OTIdentifier &theServerID, transactionType theType, int64_t lTransactionNum=0)
bool AddOffer(OTTrade *pTrade, OTOffer &theOffer, bool bSaveFile=true, time64_t tDateAddedToMarket=OT_TIME_ZERO)
OTOffer * GetOffer(const int64_t &lTransactionNum)
EXPORT bool CalculateDigest(const OTData &dataInput)
const OTIdentifier & GetSenderUserID() const
int64_t GetAmountAvailable() const
time64_t GetValidTo() const
bool IsMarketOrder() const
PackedBuffer * Pack(Storable &inObj)
bool IsGreaterThan() const
EXPORT const OTIdentifier & GetAssetTypeID() const
int64_t GetTransactionNum() const
const int64_t & GetScale() const
bool GetNym_OfferList(const OTIdentifier &NYM_ID, OTDB::OfferListNym &theOutputList, int32_t &nNymOfferCount)
EXPORT int64_t GetBalance() const
EXPORT bool SaveContract()
static EXPORT const char * PathSeparator()
const OTIdentifier & GetAssetID() const
bool IsLimitOrder() const
const OTIdentifier & GetCurrencyID() const
static EXPORT OTCronItem * LoadCronReceipt(const int64_t &lTransactionNum)
bool IsFlaggedForRemoval() const
EXPORT bool AddTransaction(OTTransaction &theTransaction)
OTLOG_IMPORT OTLogStream otOut
const OTIdentifier & GetCurrencyID() const
const OTIdentifier & GetServerID() const
EXPORT void SetAttachment(const OTString &theStr)
int64_t GetLowestAskPrice()
const OTIdentifier & GetCurrencyAcctID() const
const int64_t & GetStopPrice() const
time64_t OTTimeGetTimeFromSeconds(int64_t seconds)
EXPORT bool LoadSignedNymfile(OTPseudonym &SIGNER_NYM)
const OTIdentifier & GetServerID() const
EXPORT void Concatenate(const char *arg,...)
void IncrementTradesAlreadyDone()
EXPORT Storable * QueryObject(StoredObjectType theObjectType, std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
const OTIdentifier & GetAssetID() const
EXPORT bool VerifyPseudonym() const
static EXPORT OTItem * CreateItemFromTransaction(const OTTransaction &theOwner, OTItem::itemType theType, const OTIdentifier *pDestinationAcctID=nullptr)
EXPORT void ReleaseSignatures()
EXPORT bool Exists() const
virtual void UpdateContents()
EXPORT void SetString(const char *szString)
EXPORT void SetIdentifier(const OTIdentifier &theIdentifier)
const int64_t & GetTotalAssetsOnOffer() const
const OTIdentifier & GetServerID() const
EXPORT void Format(const char *fmt,...)
void SetStatus(const OTItem::itemStatus &theVal)
time64_t GetValidFrom() const
EXPORT bool LoadPublicKey()
EXPORT void SetReferenceString(const OTString &theStr)
EXPORT bool VerifyOwner(const OTPseudonym &candidate) const
std::multimap< int64_t, OTOffer * > mapOfOffers
const int64_t & GetFinishedSoFar() const
EXPORT void Set(const char *data, uint32_t enforcedMaxLength=0)
time64_t OTTimeGetCurrentTime()
static EXPORT bool LoadEncodedTextField(irr::io::IrrXMLReader *&xml, OTASCIIArmor &ascOutput)
virtual void GetIdentifier(OTIdentifier &theIdentifier) const
EXPORT void SetDateAddedToMarket(time64_t tDate)
virtual int32_t ProcessXMLNode(irr::io::IrrXMLReader *&xml)
OTString m_strContractType
#define OT_ASSERT_MSG(x, s)
void cleanup_four_accounts(OTAccount *p1, OTAccount *p2, OTAccount *p3, OTAccount *p4)
const int64_t & GetTransactionNum() const
virtual EXPORT bool LoadContract()
void rollback_four_accounts(OTAccount &p1, bool b1, const int64_t &a1, OTAccount &p2, bool b2, const int64_t &a2, OTAccount &p3, bool b3, const int64_t &a3, OTAccount &p4, bool b4, const int64_t &a4)
bool ValidateOfferForMarket(OTOffer &theOffer, OTString *pReason=nullptr)
static EXPORT const OTString & Market()
OTStringXML m_xmlUnsigned
virtual bool SaveContractWallet(std::ofstream &ofs) const
EXPORT void SetNote(const OTString &theStr)
EXPORT bool SaveBoxReceipt(int64_t lLedgerType)
OTLOG_IMPORT OTLogStream otWarn
EXPORT const char * Get() const
virtual EXPORT bool SignContract(const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr)
EXPORT bool SaveInbox(OTLedger &box, OTIdentifier *hash=nullptr)
const int64_t & GetScale() const
OTLOG_IMPORT OTLogStream otErr
EXPORT bool GetRecentTradeList(OTASCIIArmor &ascOutput, int32_t &nTradeCount)
EXPORT OTPacker * GetPacker(PackType ePackType=OTDB_DEFAULT_PACKER)
EXPORT void SetReferenceToNum(int64_t lTransactionNum)
void ProcessTrade(OTTrade &theTrade, OTOffer &theOffer, OTOffer &theOtherOffer)
virtual EXPORT void Release()
EXPORT int32_t GetTransactionCount() const
OTPseudonym * GetServerNym() const
int64_t GetHighestBidPrice()
virtual EXPORT bool VerifySignature(const OTPseudonym &theNym, const OTPasswordData *pPWData=nullptr) const
const OTIdentifier & GetSenderAcctID() const
EXPORT bool Exists(std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
EXPORT bool SetData(const OTData &theData, bool bLineBreaks=true)
void SetScale(const int64_t &lScale)
EXPORT bool GetOfferList(OTASCIIArmor &ascOutput, int64_t lDepth, int32_t &nOfferCount)
int64_t OTTimeGetSecondsFromTime(time64_t time)
int64_t GetTotalAvailableAssets()
EXPORT bool LoadContractFromString(const OTString &theStr)
EXPORT bool StoreObject(Storable &theContents, std::string strFolder, std::string oneStr="", std::string twoStr="", std::string threeStr="")
virtual EXPORT void Release()
EXPORT bool SaveAccount()
void IncrementFinishedSoFar(const int64_t &lFinishedSoFar)
#define MAX_MARKET_QUERY_DEPTH
EXPORT bool Credit(const int64_t &amount)
static EXPORT OTAccount * LoadExistingAccount(const OTIdentifier &accountId, const OTIdentifier &serverId)
bool RemoveOffer(const int64_t &lTransactionNum)
EXPORT bool Debit(const int64_t &amount)
virtual EXPORT void Release()
EXPORT void AddItem(OTItem &theItem)
OTLOG_IMPORT OTLogStream otLog5
const int64_t & GetPriceLimit() const
EXPORT bool SaveInbox(OTIdentifier *pInboxHash=nullptr)