private double suggestBuyPrice(Market market) { const int decPlaces = 14; double increment = Math.Pow(10.0, -1.0 * decPlaces); // 0.00000000000001; const double MIN_WALL_VOLUME = 100.0; double sumVolume = 0.0; foreach (var bid in market.Bids) { //Don't count self if (_config.AccessKey == bid.Account && bid.Sequence == _buyOrderId) { continue; } //Skip BUY orders with tiny amount sumVolume += bid.Amount; if (sumVolume < MIN_WALL_VOLUME) { continue; } if (bid.Price < _executedSellPrice - _minDifference) { return bid.Price.eq(_buyOrderPrice, increment) ? _buyOrderPrice : Math.Round(bid.Price + increment, decPlaces); } } //All BUY orders are too high (probably some wild race). Suggest BUY order with minimum profit and hope return _executedSellPrice - _minDifference; }
private double suggestSellPrice(Market market) { const int DEC_PLACES = 14; double increment = Math.Pow(10.0, -1.0 * DEC_PLACES); // 0.00000000000001; double sum = 0; var highestBid = market.Bids.First().Price; foreach (var ask in market.Asks) { if (sum + _operativeAmount > _volumeWall && ask.Price - _minDifference > highestBid) { double sellPrice = Math.Round(ask.Price - increment, DEC_PLACES); //The difference is too small and we'd be not the first SELL order. Leave previous price to avoid server call if (-1 != _sellOrderId && sellPrice > market.Asks[0].Price && Math.Abs(sellPrice - _sellOrderPrice) < _minPriceUpdate) { log(String.Format("DEBUG: SELL price {0} too similar, using previous", sellPrice)); return _sellOrderPrice; } return sellPrice; } sum += ask.Amount; //Don't consider volume of own order if (_config.AccessKey == ask.Account && ask.Sequence == _sellOrderId) { sum -= _sellOrderAmount; } } //Market too dry, use SELL order before last, so we see it in chart var price = market.Asks.Last().Price - increment; if (-1 != _sellOrderId && Math.Abs(price - _sellOrderPrice) < _minPriceUpdate) { return _sellOrderPrice; } return Math.Round(price, DEC_PLACES); }
private double suggestBuyPrice(Market market) { const double MIN_WALL_VOLUME = 100.0; var maxPrice = _executedSellPrice - MIN_DIFFERENCE; var highestBid = market.Bids.First().Price; double sumVolume = 0.0; foreach (var bid in market.Bids) { //Don't count self if (bid.Price.eq(_buyOrderPrice) && bid.Amount.eq(_buyOrderAmount)) continue; //Skip BUY orders with tiny amount sumVolume += bid.Amount; if (sumVolume < MIN_WALL_VOLUME) continue; highestBid = bid.Price; break; } //Somebody offers higher price than we can if (highestBid > maxPrice) return maxPrice; //Sugest buy price as middle between our threshold and highest bid var buyPrice = maxPrice - ((maxPrice - highestBid) / 2.0); return Math.Round(buyPrice, 7); }
private double suggestSellPrice(Market market) { var lowestAsk = getLowestAsk(market); var highestBid = market.Bids.First().Price; var spread = lowestAsk - highestBid; //Suggest price as 1/3 between lowest ask and highest bid price, closer to ask var sellPrice = Math.Round(lowestAsk - (spread/3.0), 7); //The difference is too small and we'd be not the first SELL order. Leave previous price to avoid server call if (-1 != _sellOrderId && Math.Abs(sellPrice - _sellOrderPrice) < MIN_PRICE_DELTA) { log(String.Format("DEBUG: SELL price {0} too similar, using previous", sellPrice)); return _sellOrderPrice; } return sellPrice; }
private double getLowestAsk(Market market) { var lowestAsk = market.Asks.First().Price; if (-1 != _sellOrderId) { //Don't count own order if it's the lowest ask var ask = market.Asks.First(); if (ask.Amount.eq(_operativeAmount) && ask.Price.eq(_sellOrderPrice)) lowestAsk = market.Asks[1].Price; } return lowestAsk; }
/// <summary>Get highest relevant bid price. Ignores bids with very small volume.</summary> private double getHighestBid(Market market) { const double MIN_WALL_VOLUME = 100.0; var bidVolume = 0.0; foreach (var bid in market.Bids) { bidVolume += bid.Amount; if (bidVolume > MIN_WALL_VOLUME) return bid.Price; } return market.Bids.Last().Price; }
private double suggestSellPrice(Market market) { const int decPlaces = 14; double increment = Math.Pow(10.0, -1.0 * decPlaces); // 0.00000000000001; //Ignore offers with tiny XRP volume (<100 XRP) const double MIN_WALL_VOLUME = 100.0; double sumVolume = 0.0; foreach (var ask in market.Asks) { //Don't count self if (ask.Price.eq(_sellOrderPrice) && ask.Amount.eq(_sellOrderAmount)) continue; //Skip SELL orders with tiny amount sumVolume += ask.Amount; if (sumVolume < MIN_WALL_VOLUME) continue; if (ask.Price > _executedBuyPrice + _minDifference) { return ask.Price.eq(_sellOrderPrice) ? _sellOrderPrice : Math.Round(ask.Price - increment, decPlaces); } } //All SELL orders are too low (probably some terrible fall). Suggest SELL order with minimum profit and hope :-( TODO: maybe some stop-loss strategy return _executedBuyPrice + _minDifference; }
private double suggestBuyPrice(Market market) { const int decPlaces = 14; double increment = Math.Pow(10.0, -1.0*decPlaces); // 0.00000000000001; double sum = 0; var lowestAsk = market.Asks.First().Price; foreach (var bid in market.Bids) { if (sum + _operativeAmount > _volumeWall && bid.Price + 2.0 * _minDifference < lowestAsk) { double buyPrice = Math.Round(bid.Price + increment, decPlaces); //The difference is too small and we'd be not first in BUY orders. Leave previous price to avoid server call if (-1 != _buyOrderId && buyPrice < market.Bids[0].Price && Math.Abs(buyPrice - _buyOrderPrice) < _minPriceUpdate) { log(String.Format("DEBUG: BUY price {0} too similar, using previous", buyPrice)); return _buyOrderPrice; } return buyPrice; } sum += bid.Amount; //Don't consider volume of own order if (bid.Price.eq(_buyOrderPrice)) sum -= _buyOrderAmount; } //Market too dry, use BUY order before last, so we see it in chart var price = market.Bids.Last().Price + increment; if (-1 != _buyOrderId && Math.Abs(price - _buyOrderPrice) < _minPriceUpdate) return _buyOrderPrice; return Math.Round(price, 7); }
internal Market GetMarketDepth() { //BIDs var command = new MarketDepthRequest { id = 2, taker_pays = new Take { currency = Const.NATIVE_ASSET }, taker_gets = new Take { currency = _fiatCurreny, issuer = _issuerAddress } }; string bidData = sendToRippleNet(Helpers.SerializeJson(command)); if (null == bidData) { return null; } if (!checkError("GetMarketDepth", bidData)) { return null; } var bids = Helpers.DeserializeJSON<MarketDepthBidsResponse>(bidData); if (null == bids.result || null == bids.result.offers) { _logger.Error("bidData JSON is " + Environment.NewLine + bidData); return null; } //ASKs command = new MarketDepthRequest { id = 3, taker_pays = new Take { currency = _fiatCurreny, issuer = _issuerAddress }, taker_gets = new Take { currency = Const.NATIVE_ASSET } }; string askData = sendToRippleNet(Helpers.SerializeJson(command)); if (null == askData) { return null; } if (!checkError("GetMarketDepth", askData)) { return null; } var asks = Helpers.DeserializeJSON<MarketDepthAsksResponse>(askData); if (null == asks.result || null == asks.result.offers) { _logger.Error("askData JSON is " + Environment.NewLine + askData); return null; } var market = new Market { Bids = bids.result.offers, Asks = asks.result.offers }; return market; }