Пример #1
0
        private bool TryOpenMoreDeals(double bottomAsk, double topBid, double spreadToOpen)
        {
            int zoneIndex = OrderGrid.GetZoneIndex(spreadToOpen);

            if (zoneIndex == -1)
            {
                return(false);
            }
            double baseAmount = GetRemainAmountForZoneInBaseCurrency(zoneIndex);

            if (baseAmount == 0)
            {
                return(false);
            }

            double buyAmount                = CalculateLongBuyAmountByBaseAmount(baseAmount);
            double actualBuyAmount          = GetActualBottomAskAmount(bottomAsk);
            double finalBuyAmount           = Math.Min(buyAmount, actualBuyAmount);
            double requiredShortSellAmount  = CalculateRequiredShortAmount(finalBuyAmount, spreadToOpen);
            double availableShortSellAmount = GetActualShortBidAmount(topBid);
            double finalSellAmount          = Math.Min(requiredShortSellAmount, availableShortSellAmount);

            if (finalSellAmount < requiredShortSellAmount)
            {
                finalSellAmount = availableShortSellAmount;
                finalBuyAmount  = CalculateRequiredLongAmount(finalSellAmount, spreadToOpen);
            }

            MarketBuy(Long, bottomAsk, finalBuyAmount);
            MarketSell(Short, topBid, finalSellAmount);

            var order = new StatisticalArbitrageOrderInfo()
            {
                LongAmount       = finalBuyAmount,
                LongValue        = bottomAsk,
                ShortAmount      = finalSellAmount,
                ShortTotalAmount = finalSellAmount,
                ShortValue       = topBid,
                ZoneIndex        = zoneIndex,
                SpentDeposit     = Long.HighestBidInBaseCurrency() * finalBuyAmount,
                Spread           = spreadToOpen
            };

            LastItem             = new StatisticalArbitrageHistoryItem();
            LastItem.Time        = DateTime.UtcNow;
            LastItem.Earned      = Earned;
            LastItem.LongPrice   = bottomAsk;
            LastItem.ShortPrice  = topBid;
            LastItem.LongAmount  = finalBuyAmount;
            LastItem.ShortAmount = finalSellAmount;
            LastItem.Open        = true;
            StrategyData.Add(LastItem);

            //OpenedOrders.Add(order);
            OnOrderOpened(LastItem);

            return(true);
        }
Пример #2
0
        protected virtual StatisticalArbitrageOrderInfo GetOpenedOrderWithMaxSpread()
        {
            StatisticalArbitrageOrderInfo maxItem = null;

            //foreach(StatisticalArbitrageOrderInfo item in OpenedOrders) {
            //    if(maxItem == null || maxItem.Spread < item.Spread)
            //        maxItem = item;
            //}
            return(maxItem);
        }
Пример #3
0
        private bool TryCloseDeals(double bottomBid, double topAsk, double spreadToClose)
        {
            if (spreadToClose > CloseSpread)
            {
                return(false);
            }
            if (OpenedOrders.Count == 0)
            {
                return(false);
            }

            StatisticalArbitrageOrderInfo order = GetOpenedOrderWithMaxSpread();
            double actualSellAmount             = GetActualBottomBidAmount(bottomBid);
            double finalSellAmount = Math.Min(actualSellAmount, order.LongAmount);
            double koeffSell       = finalSellAmount / order.LongAmount;

            double actualBuyAmount = GetActualShortAskAmount(topAsk);
            double finalBuyAmount  = Math.Min(actualBuyAmount, order.ShortAmount);
            double koeffBuy        = finalBuyAmount / order.ShortAmount;
            double koeff           = Math.Min(koeffBuy, koeffSell);

            finalSellAmount *= koeff;
            finalBuyAmount  *= koeff;


            MarketSell(Long, bottomBid, finalSellAmount);
            MarketBuy(Short, topAsk, finalBuyAmount);

            order.LongAmount  -= finalSellAmount;
            order.ShortAmount -= finalBuyAmount;
            double eInc = (1 / order.LongValue - 1 / order.ShortValue) * finalBuyAmount;

            Earned += eInc;

            LastItem             = new StatisticalArbitrageHistoryItem();
            LastItem.Time        = DateTime.UtcNow;
            LastItem.Earned      = Earned;
            LastItem.LongAmount  = finalSellAmount;
            LastItem.LongPrice   = bottomBid;
            LastItem.ShortPrice  = topAsk;
            LastItem.ShortAmount = finalBuyAmount;
            LastItem.Close       = true;
            StrategyData.Add(LastItem);

            //if(order.LongAmount <= 0 && order.ShortAmount <= 0)
            //    OpenedOrders.Remove(order);
            OnOrderClosed(LastItem);

            return(true);
        }
        private bool TryOpenMoreDeals(double bottomAsk, double topBid, double spreadToOpen)
        {
            if (spreadToOpen < SpreadOpenPosition)
            {
                return(false);
            }

            //int zoneIndex = OrderGrid.GetZoneIndex(spreadToOpen);
            //if(zoneIndex == -1)
            //    return false;
            //double baseAmount = GetRemainAmountForZoneInBaseCurrency(zoneIndex);
            //if(baseAmount == 0)
            //    return false;

            double baseAmount               = MaxAllowedDeposit * 0.9;
            double buyAmount                = CalculateLongBuyAmountByBaseAmount(baseAmount);
            double actualBuyAmount          = GetActualBottomAskAmount(bottomAsk);
            double finalBuyAmount           = Math.Min(buyAmount, actualBuyAmount);
            double requiredShortSellAmount  = CalculateRequiredShortAmount(finalBuyAmount, spreadToOpen);
            double availableShortSellAmount = GetActualShortBidAmount(topBid);
            double finalSellAmount          = Math.Min(requiredShortSellAmount, availableShortSellAmount);

            if (finalSellAmount < requiredShortSellAmount)
            {
                finalSellAmount = availableShortSellAmount;
                finalBuyAmount  = CalculateRequiredLongAmount(finalSellAmount, spreadToOpen);
            }

            if (finalBuyAmount == 0 || finalSellAmount == 0 || finalBuyAmount * bottomAsk < MinDepositForOpenPosition)
            {
                return(false);
            }

            var order = new StatisticalArbitrageOrderInfo()
            {
                ShortValue   = topBid,
                SpentDeposit = Long.HighestBidInBaseCurrency() * finalBuyAmount,
                Spread       = spreadToOpen
            };

            if (Long.SpentInBaseCurrency(bottomAsk, finalBuyAmount) * 1.05 > MaxAllowedDeposit)
            {
                LogManager.Default.Add(LogType.Error, this, Name, "not enough deposit for open long position", "spent = " + Long.SpentInBaseCurrency(bottomAsk, finalBuyAmount) + " in " + Long.BaseCurrency + "; deposit = " + MaxAllowedDeposit);
                return(false);
            }

            if (Short.SpentInBaseCurrency(topBid, finalSellAmount) * 1.05 > GetMaxAllowedShortDeposit())
            {
                LogManager.Default.Add(LogType.Error, this, Name, "not enough deposit for open long position", "spent = " + Short.SpentInBaseCurrency(topBid, finalSellAmount) + " in " + Short.BaseCurrency + "; deposit = " + GetMaxAllowedShortDeposit());
                return(false);
            }

            OpenedPairs.Add(order);
            OpenPositionInfo lp = OpenLongPosition(Long, "OL", bottomAsk, finalBuyAmount, 1000);

            if (lp == null)
            {
                OpenedPairs.Remove(order);
                LogManager.Default.Add(LogType.Error, this, Name, "failed open long position", "price = " + bottomAsk + "; amount = " + finalBuyAmount + "; spent = " + Long.SpentInBaseCurrency(bottomAsk, finalBuyAmount) + " in " + Long.BaseCurrency);
                return(false);
            }

            OpenPositionInfo sp = OpenShortPosition(Short, "OS", topBid, finalSellAmount, 1000);

            if (sp == null)
            {
                OpenedPairs.Remove(order);
                LogManager.Default.Add(LogType.Error, this, Name, "failed open short position", "price = " + topBid + "; amount = " + finalSellAmount + "; spent = " + Short.SpentInBaseCurrency(topBid, finalSellAmount));
                return(false);
            }

            order.LongPosition     = lp;
            order.ShortPosition    = sp;
            order.LongAmount       = lp.OpenAmount;
            order.LongValue        = lp.OpenValue;
            order.ShortAmount      = sp.OpenAmount;
            order.ShortTotalAmount = sp.OpenValue;

            LastItem = new StatisticalArbitrageHistoryItem();
            LastItem.OpenedPositions.Add(order.LongPosition);
            LastItem.OpenedPositions.Add(order.ShortPosition);
            LastItem.Time        = DataProvider.CurrentTime;
            LastItem.Earned      = Earned;
            LastItem.LongBid     = Long.OrderBook.HighestBid;
            LastItem.LongAsk     = bottomAsk;
            LastItem.ShortBid    = topBid;
            LastItem.ShortAsk    = Short.OrderBook.LowestAsk;
            LastItem.LongAmount  = finalBuyAmount;
            LastItem.ShortAmount = finalSellAmount;
            LastItem.Open        = true;
            LastItem.Index       = StrategyData.Count;
            LastItem.Mark        = "OPEN";
            StrategyData.Add(LastItem);

            //OpenedOrders.Add(order);
            OnOrderOpened(LastItem);

            return(true);
        }