Esempio n. 1
0
        public TransactionFee EstimateTransactionFee(ExchangeOrderType orderType, decimal orderAmount, Currency orderAmountCurrency, ExchangeTradePair tradePair)
        {
#warning watch out ... this was copied and pasted
            // Check what's the preferred currency (BTC) and take 0.25% of it.
            var fee = (orderAmountCurrency == SystemSetting.PreferredCyptoCurrency ? 1.0m : tradePair.LatestPrice) * orderAmount * tradePair.FeePercent / 100m;
            return(new TransactionFee()
            {
                Amount = fee, Currency = SystemSetting.PreferredCyptoCurrency
            });
        }
Esempio n. 2
0
        /// <summary>
        /// If we have a trade pair of for instance ETH - BTC then to exhange x-ETH to y-BTC we're doing a sell order.
        /// In other words the from currency is the one that dictates.
        /// </summary>
        public ExchangeOrderAction(ExchangeTradePair tradePair, ExchangeOrderType orderType, decimal txAmountInPreferredCurrency, Currency txCurrency)
        {
            this.TradePair              = tradePair;
            this.OrderType              = orderType;
            this.BaseCurrency           = txCurrency;                            // The base currency is the to currency
            this.EstimatedCost          = this.TradePair.FeePercent / 100m * txAmountInPreferredCurrency;
            this.MaxExposureCost        = 0m;                                    // We set this to zero as order actions are instantaneous.
            this.EstimatedTimeToExecute = new TimeSpan(0, 0, 10);                // We arbitrarly set the estimated time to execute to 10seconds. Generally, buying or selling at market price will be executed immediately.
            this.TradingIntegration     = tradePair.Exchange.TradingIntegration; // It's good to assume that if this point is reached then the exchange trading was integrated.
            this.TransactionAmount      = txAmountInPreferredCurrency;

            // In a trade pair of ETH -> BTC we always consider the from as the ETH
            this.FromAccount = this.TradePair.Exchange.TradeAccounts.Where(x => x.Currency == this.TradePair.TradePair.FromCurrency).Single();
            this.ToAccount   = this.TradePair.Exchange.TradeAccounts.Where(x => x.Currency == this.TradePair.TradePair.ToCurrency).Single();
        }
        public ExchangeOrder(ExchangeOrder order, BigInteger newPrice, BigInteger newOrderSize)
        {
            Uid       = order.Uid;
            Timestamp = order.Timestamp;
            Creator   = order.Creator;

            Amount     = newOrderSize;
            BaseSymbol = order.BaseSymbol;

            Price       = newOrderSize;
            QuoteSymbol = order.QuoteSymbol;

            Side = order.Side;
            Type = order.Type;
        }
        public ExchangeOrder(BigInteger uid, Timestamp timestamp, Address creator, BigInteger amount, string baseSymbol, BigInteger price, string quoteSymbol, ExchangeOrderSide side, ExchangeOrderType type)
        {
            Uid       = uid;
            Timestamp = timestamp;
            Creator   = creator;

            Amount     = amount;
            BaseSymbol = baseSymbol;

            Price       = price;
            QuoteSymbol = quoteSymbol;

            Side = side;
            Type = type;
        }
Esempio n. 5
0
 protected OrderEventArgs(DateTime timeStamp,
                          ClientOrderId clientOrderId,
                          Instrument instrument,
                          ExchangeOrderType orderType,
                          Side side,
                          decimal?price,
                          decimal workingSize)
 {
     TimeStamp     = timeStamp;
     ClientOrderId = clientOrderId;
     Instrument    = instrument;
     OrderType     = orderType;
     Side          = side;
     Price         = price;
     WorkingSize   = workingSize;
 }
 public ExchangeOrderCancelledEventArgs(DateTime timeStamp,
                                        ClientOrderId clientOrderId,
                                        Instrument instrument,
                                        ExchangeOrderType orderType,
                                        Side side,
                                        decimal?price,
                                        decimal workingSize)
     : base(timeStamp,
            clientOrderId,
            instrument,
            orderType,
            side,
            price,
            workingSize)
 {
 }
Esempio n. 7
0
 public ExchangeOrderRejectedEventArgs(DateTime timeStamp,
                                       ClientOrderId clientOrderId,
                                       Instrument instrument,
                                       ExchangeOrderType orderType,
                                       Side side,
                                       decimal?price,
                                       decimal size,
                                       string rejectReason) : base(timeStamp,
                                                                   clientOrderId,
                                                                   instrument,
                                                                   orderType,
                                                                   side,
                                                                   price,
                                                                   size)
 {
     RejectReason = rejectReason;
 }
Esempio n. 8
0
 public ExchangeOrderFilledEventArgs(DateTime timeStamp,
                                     ClientOrderId clientOrderId,
                                     Instrument instrument,
                                     ExchangeOrderType exchangeOrderType,
                                     Side side,
                                     decimal?price,
                                     decimal workingSize,
                                     decimal filledSize)
     : base(timeStamp,
            clientOrderId,
            instrument,
            exchangeOrderType,
            side,
            price,
            workingSize)
 {
     FilledSize = filledSize;
 }
 public ExchangeOrderAcknowledgedEventArgs(DateTime timeStamp,
                                           ExchangeOrderId exchangeOrderId,
                                           ClientOrderId clientOrderId,
                                           Instrument instrument,
                                           ExchangeOrderType exchangeOrderType,
                                           Side side,
                                           decimal?price,
                                           decimal workingSize)
     : base(timeStamp,
            clientOrderId,
            instrument,
            exchangeOrderType,
            side,
            price,
            workingSize)
 {
     ExchangeOrderId = exchangeOrderId;
 }
Esempio n. 10
0
        public ExchangeOrder(IOrderManager orderManager,
                             ExchangeOrderType orderType,
                             Instrument instrument,
                             Side side)
        {
            _self = Self;

            _orderManager = orderManager;
            _orderManager.ExchangeOrderAcknowledged += ForwardEvent;
            _orderManager.ExchangeOrderCancelled    += ForwardEvent;
            _orderManager.ExchangeOrderFilled       += ForwardEvent;
            _orderManager.ExchangeOrderRejected     += ForwardEvent;

            OrderType  = orderType;
            Instrument = instrument;
            Side       = side;

            Become(StateNotInMarket);
        }
        public static Task <JObject> SendOrder(
            this RestClient client,
            ClientOrderId clientOrderId,
            Instrument instrument,
            Side side,
            ExchangeOrderType orderType,
            decimal?price,
            decimal size,
            bool postOnly = true
            )
        {
            // TODO: Add Time-in-Force

            var     jobj = new JObject();
            dynamic o    = jobj;

            o.client_oid = clientOrderId.Id;
            o.product_id = instrument.Symbol;
            o.type       = orderType.ToString().ToLowerInvariant();
            o.side       = side.ToString().ToLowerInvariant();


            o.size = size;

            switch (orderType)
            {
            case ExchangeOrderType.Limit:
                o.stp       = "cn"; // Self trading prevention -> cancel newest
                o.post_only = postOnly;
                goto case ExchangeOrderType.Stop;

            case ExchangeOrderType.Stop:
                o.price = price;
                break;

            case ExchangeOrderType.Market:
                break;
            }

            return(DoPost(client, jobj));
        }
Esempio n. 12
0
        private void OpenOrder(Address from, Address provider, string baseSymbol, string quoteSymbol, ExchangeOrderSide side, ExchangeOrderType orderType, BigInteger orderSize, BigInteger price)
        {
            Runtime.Expect(Runtime.IsWitness(from), "invalid witness");

            Runtime.Expect(Runtime.GasTarget == provider, "invalid gas target");

            Runtime.Expect(baseSymbol != quoteSymbol, "invalid base/quote pair");

            Runtime.Expect(Runtime.TokenExists(baseSymbol), "invalid base token");
            var baseToken = Runtime.GetToken(baseSymbol);

            Runtime.Expect(baseToken.Flags.HasFlag(TokenFlags.Fungible), "token must be fungible");

            Runtime.Expect(Runtime.TokenExists(quoteSymbol), "invalid quote token");
            var quoteToken = Runtime.GetToken(quoteSymbol);

            Runtime.Expect(quoteToken.Flags.HasFlag(TokenFlags.Fungible), "token must be fungible");

            if (orderType != Market)
            {
                Runtime.Expect(orderSize >= GetMinimumTokenQuantity(baseToken), "order size is not sufficient");
                Runtime.Expect(price >= GetMinimumTokenQuantity(quoteToken), "order price is not sufficient");
            }

            var uid = Runtime.GenerateUID();

            //--------------
            //perform escrow for non-market orders
            string     orderEscrowSymbol = CalculateEscrowSymbol(baseToken, quoteToken, side);
            IToken     orderEscrowToken  = orderEscrowSymbol == baseSymbol ? baseToken : quoteToken;
            BigInteger orderEscrowAmount;
            BigInteger orderEscrowUsage = 0;

            if (orderType == Market)
            {
                orderEscrowAmount = orderSize;
                Runtime.Expect(orderEscrowAmount >= GetMinimumTokenQuantity(orderEscrowToken), "market order size is not sufficient");
            }
            else
            {
                orderEscrowAmount = CalculateEscrowAmount(orderSize, price, baseToken, quoteToken, side);
            }

            //BigInteger baseTokensUnfilled = orderSize;

            var balance = Runtime.GetBalance(orderEscrowSymbol, from);

            Runtime.Expect(balance >= orderEscrowAmount, "not enough balance");

            Runtime.TransferTokens(orderEscrowSymbol, from, this.Address, orderEscrowAmount);
            //------------

            var         thisOrder = new ExchangeOrder();
            StorageList orderList;
            BigInteger  orderIndex = 0;

            thisOrder = new ExchangeOrder(uid, Runtime.Time, from, provider, orderSize, baseSymbol, price, quoteSymbol, side, orderType);
            Runtime.Notify(EventKind.OrderCreated, from, uid);

            var key = BuildOrderKey(side, quoteSymbol, baseSymbol);

            orderList  = _orders.Get <string, StorageList>(key);
            orderIndex = orderList.Add <ExchangeOrder>(thisOrder);
            _orderMap.Set <BigInteger, string>(uid, key);

            var makerSide   = side == Buy ? Sell : Buy;
            var makerKey    = BuildOrderKey(makerSide, quoteSymbol, baseSymbol);
            var makerOrders = _orders.Get <string, StorageList>(makerKey);

            do
            {
                int        bestIndex          = -1;
                BigInteger bestPrice          = 0;
                Timestamp  bestPriceTimestamp = 0;

                ExchangeOrder takerOrder = thisOrder;

                var makerOrdersCount = makerOrders.Count();
                for (int i = 0; i < makerOrdersCount; i++)
                {
                    var makerOrder = makerOrders.Get <ExchangeOrder>(i);

                    if (side == Buy)
                    {
                        if (makerOrder.Price > takerOrder.Price && orderType != Market) // too expensive, we wont buy at this price
                        {
                            continue;
                        }

                        if (bestIndex == -1 || makerOrder.Price < bestPrice || (makerOrder.Price == bestPrice && makerOrder.Timestamp < bestPriceTimestamp))
                        {
                            bestIndex          = i;
                            bestPrice          = makerOrder.Price;
                            bestPriceTimestamp = makerOrder.Timestamp;
                        }
                    }
                    else
                    {
                        if (makerOrder.Price < takerOrder.Price && orderType != Market) // too cheap, we wont sell at this price
                        {
                            continue;
                        }

                        if (bestIndex == -1 || makerOrder.Price > bestPrice || (makerOrder.Price == bestPrice && makerOrder.Timestamp < bestPriceTimestamp))
                        {
                            bestIndex          = i;
                            bestPrice          = makerOrder.Price;
                            bestPriceTimestamp = makerOrder.Timestamp;
                        }
                    }
                }

                if (bestIndex >= 0)
                {
                    //since order "uid" has found a match, the creator of this order will be a taker as he will remove liquidity from the market
                    //and the creator of the "bestIndex" order is the maker as he is providing liquidity to the taker
                    var takerAvailableEscrow = orderEscrowAmount - orderEscrowUsage;
                    var takerEscrowUsage     = BigInteger.Zero;
                    var takerEscrowSymbol    = orderEscrowSymbol;

                    var makerOrder        = makerOrders.Get <ExchangeOrder>(bestIndex);
                    var makerEscrow       = _escrows.Get <BigInteger, BigInteger>(makerOrder.Uid);
                    var makerEscrowUsage  = BigInteger.Zero;;
                    var makerEscrowSymbol = orderEscrowSymbol == baseSymbol ? quoteSymbol : baseSymbol;

                    //Get fulfilled order size in base tokens
                    //and then calculate the corresponding fulfilled order size in quote tokens
                    if (takerEscrowSymbol == baseSymbol)
                    {
                        var makerEscrowBaseEquivalent = Runtime.ConvertQuoteToBase(makerEscrow, makerOrder.Price, baseToken, quoteToken);
                        takerEscrowUsage = takerAvailableEscrow < makerEscrowBaseEquivalent ? takerAvailableEscrow : makerEscrowBaseEquivalent;

                        makerEscrowUsage = CalculateEscrowAmount(takerEscrowUsage, makerOrder.Price, baseToken, quoteToken, Buy);
                    }
                    else
                    {
                        var takerEscrowBaseEquivalent = Runtime.ConvertQuoteToBase(takerAvailableEscrow, makerOrder.Price, baseToken, quoteToken);
                        makerEscrowUsage = makerEscrow < takerEscrowBaseEquivalent ? makerEscrow : takerEscrowBaseEquivalent;

                        takerEscrowUsage = CalculateEscrowAmount(makerEscrowUsage, makerOrder.Price, baseToken, quoteToken, Buy);
                    }

                    Runtime.Expect(takerEscrowUsage <= takerAvailableEscrow, "Taker tried to use more escrow than available");
                    Runtime.Expect(makerEscrowUsage <= makerEscrow, "Maker tried to use more escrow than available");

                    if (takerEscrowUsage < GetMinimumSymbolQuantity(takerEscrowSymbol) ||
                        makerEscrowUsage < GetMinimumSymbolQuantity(makerEscrowSymbol))
                    {
                        break;
                    }

                    Runtime.TransferTokens(takerEscrowSymbol, this.Address, makerOrder.Creator, takerEscrowUsage);
                    Runtime.TransferTokens(makerEscrowSymbol, this.Address, takerOrder.Creator, makerEscrowUsage);

                    orderEscrowUsage += takerEscrowUsage;

                    Runtime.Notify(EventKind.OrderFilled, takerOrder.Creator, takerOrder.Uid);
                    Runtime.Notify(EventKind.OrderFilled, makerOrder.Creator, makerOrder.Uid);

                    if (makerEscrowUsage == makerEscrow)
                    {
                        makerOrders.RemoveAt <ExchangeOrder>(bestIndex);
                        _orderMap.Remove(makerOrder.Uid);

                        Runtime.Expect(_escrows.ContainsKey(makerOrder.Uid), "An orderbook entry must have registered escrow");
                        _escrows.Remove(makerOrder.Uid);

                        Runtime.Notify(EventKind.OrderClosed, makerOrder.Creator, makerOrder.Uid);
                    }
                    else
                    {
                        _escrows.Set(makerOrder.Uid, makerEscrow - makerEscrowUsage);
                    }
                }
                else
                {
                    break;
                }
            } while (orderEscrowUsage < orderEscrowAmount);

            var leftoverEscrow = orderEscrowAmount - orderEscrowUsage;

            if (leftoverEscrow == 0 || orderType != Limit)
            {
                orderList.RemoveAt <ExchangeOrder>(orderIndex);
                _orderMap.Remove(thisOrder.Uid);
                _escrows.Remove(thisOrder.Uid);

                if (leftoverEscrow > 0)
                {
                    Runtime.TransferTokens(orderEscrowSymbol, this.Address, thisOrder.Creator, leftoverEscrow);
                    Runtime.Notify(EventKind.OrderCancelled, thisOrder.Creator, thisOrder.Uid);
                }
                else
                {
                    Runtime.Notify(EventKind.OrderClosed, thisOrder.Creator, thisOrder.Uid);
                }
            }
            else
            {
                _escrows.Set(uid, leftoverEscrow);
            }

            //TODO: ADD FEES, SEND THEM TO this.Address FOR NOW
        }
Esempio n. 13
0
 public Task <ExchangeOrderResponse> PlaceOrder(ExchangeOrderType orderType, decimal orderAmount, Currency orderAmountCurrency, ExchangeTradePair tradePair)
 {
     throw new NotImplementedException();
 }
Esempio n. 14
0
 /// <summary>
 /// If we have a trade pair of for instance ETH - BTC then to exhange x-ETH to y-BTC we're doing a sell order.
 /// In other words the from currency is the one that dictates.
 /// </summary>
 public ExchangeOrderAction(IExchangeTrader tradingIntegration, ExchangeTradePair tradePair, ExchangeOrderType orderType, decimal transactionAmountInFromCurrency)
 {
     this.TradePair              = tradePair;
     this.OrderType              = orderType;
     this.BaseCurrency           = this.TradePair.TradePair.ToCurrency; // The base currency is the to currency
     this.EstimatedCost          = this.TradePair.FeePercent / 100m * transactionAmountInFromCurrency;
     this.MaxExposureCost        = 0m;                                  // We set this to zero as order actions are instantaneous.
     this.EstimatedTimeToExecute = new TimeSpan(0, 0, 10);              // We arbitrarly set the estimated time to execute to 10seconds. Generally, buying or selling at market price will be executed immediately.
     this.TradingIntegration     = tradingIntegration;
     this.TransactionAmount      = transactionAmountInFromCurrency;
 }