Пример #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
 private double CalculateRequiredShortAmount(double buyAmount, double spread)
 {
     return((buyAmount * Long.HighestBidInBaseCurrency() + spread * buyAmount) / Short.LowestAskInBaseCurrency());
 }
Пример #3
0
 private double CalculateRequiredLongAmount(double sellAmount, double spread)
 {
     return(sellAmount * Short.LowestAskInBaseCurrency() / (Long.HighestBidInBaseCurrency() + spread));
 }
Пример #4
0
 private double CalculateLongBuyAmountByBaseAmount(double baseAmount)
 {
     return(baseAmount / Long.HighestBidInBaseCurrency());
 }
        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);
        }