public MarketBase(MetaDaemonApi daemon, MarketRow market, BitsharesWallet bitshares, BitcoinWallet bitcoin, string bitsharesAccount) { m_daemon = daemon; m_market = market; m_bitshares = bitshares; m_bitcoin = bitcoin; m_bitsharesAccount = bitsharesAccount; }
/// <summary> Updates the market in database described by market. </summary> /// /// <remarks> Paul, 05/02/2015. </remarks> /// /// <param name="market"> The market. </param> public bool UpdateMarketInDatabase(MarketRow market) { return m_database.Statement( "UPDATE markets SET ask=@a, bid=@b, ask_max=@c, bid_max=@d, ask_fee_percent=@e, bid_fee_percent=@f WHERE symbol_pair=@g;", market.ask, market.bid, market.ask_max, market.bid_max, market.ask_fee_percent, market.bid_fee_percent, market.symbol_pair) > 0; }
/// <summary> Updates the market in database described by market. </summary> /// /// <remarks> Paul, 05/02/2015. </remarks> /// /// <param name="market"> The market. </param> protected void UpdateMarketInDatabase(MarketRow market) { bool updated = m_dataAccess.UpdateMarketInDatabase(market); Debug.Assert(updated); }
/// <summary> Handles the command. </summary> /// /// <remarks> Paul, 26/02/2015. </remarks> /// /// <param name="l"> The BitsharesLedgerEntry to process. </param> /// <param name="handler"> The handler. </param> /// <param name="market"> The market. </param> /// /// <returns> true if it succeeds, false if it fails. </returns> public bool HandleCommand(BitsharesLedgerEntry l, MarketBase handler, MarketRow market, string trxid) { if (m_adminUsernames.Contains(l.from_account)) { try { string[] parts = l.memo.Split(' '); if (l.memo.StartsWith(kSetPricesMemoStart)) { HandlePriceSetting(parts, l, handler, market); return true; } else if (l.memo.StartsWith(kWithdrawMemo)) { // process withdrawal if (parts[0] == kWithdrawMemo) { // make sure we didn't already process this transaction! if (!m_dataAccess.IsWithdrawalProcessed(trxid)) { decimal amount = decimal.Parse(parts[1]); CurrenciesRow type = CurrencyHelpers.FromSymbol(parts[2], m_allCurrencies); string to; string txid; if ( !CurrencyHelpers.IsBitsharesAsset(type) ) { to = m_dataAccess.GetStats().bitcoin_withdraw_address; Debug.Assert(to != null); txid = m_bitcoin.SendToAddress(to, amount); } else { to = l.from_account; BitsharesTransactionResponse response = m_bitshares.WalletTransfer(amount, CurrencyHelpers.ToBitsharesSymbol(type), m_bitsharesAccount, to); txid = response.record_id; } // log in DB m_dataAccess.InsertWithdrawal(trxid, txid, type.ToString(), amount, to, DateTime.UtcNow); } return true; } } } catch (Exception e) { LogGeneralException(e.ToString()); } } return false; }
/// <summary> Handles the price setting. </summary> /// /// <remarks> Paul, 14/02/2015. </remarks> /// /// <param name="l"> The BitsharesLedgerEntry to process. </param> /// <param name="handler"> The handler. </param> /// <param name="market"> The market. </param> void HandlePriceSetting(string[] parts, BitsharesLedgerEntry l, MarketBase handler, MarketRow market) { // parse if (parts[0] == kSetPricesMemoStart) { if (parts[1] == market.symbol_pair) { // setting is for this market! decimal basePrice = decimal.Parse(parts[2]); decimal quotePrice = decimal.Parse(parts[3]); // go do it! handler.SetPricesFromSingleUnitQuantities(basePrice, quotePrice, market.flipped, market); } } }
/// <summary> Creates handler for market. </summary> /// /// <remarks> Paul, 05/02/2015. </remarks> /// /// <exception cref="UnexpectedCaseException"> Thrown when an Unexpected Case error condition /// occurs. </exception> /// /// <param name="market"> The market. </param> /// /// <returns> The new handler for market. </returns> MarketBase CreateHandlerForMarket(MarketRow market) { CurrenciesRow @base, quote; CurrencyHelpers.GetBaseAndQuoteFromSymbolPair(market.symbol_pair, m_allCurrencies, out @base, out quote); if ( CurrencyHelpers.IsBitsharesAsset(@base) && !CurrencyHelpers.IsBitsharesAsset(quote)) { return new InternalMarket(this, market, m_bitshares, m_bitcoin, m_bitsharesAccount, @base); } else if (!CurrencyHelpers.IsBitsharesAsset(@base) && CurrencyHelpers.IsBitsharesAsset(quote)) { return new InternalMarket(this, market, m_bitshares, m_bitcoin, m_bitsharesAccount, @quote); } else { throw new UnexpectedCaseException(); } }
/// <summary> Sets prices from single unit quantities. </summary> /// /// <remarks> Paul, 14/02/2015. </remarks> /// /// <exception cref="Exception"> Thrown when an exception error condition occurs. </exception> /// /// <param name="baseQuantity"> The base quantity. </param> /// <param name="quoteQuantity"> The quote quantity. </param> public virtual void SetPricesFromSingleUnitQuantities(decimal baseQuantity, decimal quoteQuantity, bool flipped, MarketRow market) { decimal bid, ask; decimal buyFee = baseQuantity * market.bid_fee_percent/100; decimal sellFee = quoteQuantity * market.ask_fee_percent/100; baseQuantity -= buyFee; quoteQuantity += sellFee; if (flipped) { bid = baseQuantity; ask = quoteQuantity; } else { bid = 1 / baseQuantity; ask = 1 / quoteQuantity; } if (Math.Abs(bid - m_market.bid) > m_market.bid / 10 || Math.Abs(ask - m_market.ask) > m_market.ask / 10) { throw new Exception("New prices are too different!"); } int updated = m_daemon.UpdateMarketPrices(m_market.symbol_pair, bid, ask); if (updated == 0) { throw new Exception("No market row updated!"); } else { m_market.ask = ask; m_market.bid = bid; } m_isDirty = true; }
/// <summary> Calculates the market prices and limits./ </summary> /// /// <remarks> Paul, 19/02/2015. </remarks> /// /// <param name="market"> [in,out] The market. </param> /// <param name="bitsharesBalances"> The bitshares balances. </param> /// <param name="bitcoinBalances"> The bitcoin balances. </param> /// /// <returns> Whether the prices were updated </returns> public virtual void ComputeMarketPricesAndLimits(ref MarketRow market, Dictionary<int, ulong> bitsharesBalances, decimal bitcoinBalances) { m_market = market; }