예제 #1
0
 public TradingContext(Wallet currentOrders, Wallet newOrders, MarketInfo objMarket, ExchangeInfo objExchange, TradingTrend lastTrend, ITradingStrategy objStrategy)
 {
     this.Exchange      = new ExchangeInfo();
     this.Market        = new MarketInfo();
     this.CurrentOrders = new Wallet();
     this.NewOrders     = new Wallet();
     this.CurrentOrders = currentOrders;
     this.NewOrders     = newOrders;
     this.Market        = objMarket;
     this.Exchange      = objExchange;
     this.LastTrend     = lastTrend;
     this.BaseStrategy  = objStrategy;
 }
        /// <summary>
        /// Static method that runs a simulation of a Market and bot runs for a given period,
        /// with the parameters and historical data supplied as parameters
        /// </summary>
        /// <param name="objSimulation">An instance of the simulation info class with properties defining how to perform the simulation</param>
        /// <param name="initialWallet">The Wallet to use at the start of the simulation</param>
        /// <param name="obStrategy">The existing strategy to use if the simulation object does not specify a custom strategy</param>
        /// <param name="objExchange">An instance of the Exchange parameters</param>
        /// <param name="exchangeHistory">Historical data for the Exchange object</param>
        /// <returns>the trading history computed from the simulation with resulting balance, issued and executed orders</returns>
        public static TradingHistory RunSimulation(SimulationInfo objSimulation, Wallet initialWallet
                                                   , ITradingStrategy obStrategy, ExchangeInfo objExchange, IEnumerable <Trade> exchangeHistory)
        {
            var toReturn = new TradingHistory();

            if (objSimulation.UseCustomStrategy)
            {
                obStrategy = objSimulation.CustomStrategy;
            }
            var objExchangeSimulator = new ExchangeSimulator()
            {
                Trades = exchangeHistory.ToList()
            };
            var currentWallet = (Wallet)initialWallet.Clone();
            //var lastBotMarket = new MarketInfo(DateTime.MinValue);
            var        lastBotTicker = 0m;
            var        lastBotTime   = DateTime.MinValue;
            MarketInfo objMarket     = null;
            int        nbEmptyRuns   = 0;

            foreach (var historicTrade in objExchangeSimulator.Trades
                     .Where(objTrade => objTrade.Time > objSimulation.StartDate &&
                            objTrade.Time < objSimulation.EndDate))
            {
                if ((currentWallet.OrderedAsks.Count > 0 && historicTrade.Price > currentWallet.LowestAsk.Price) ||
                    (currentWallet.OrderedBids.Count > 0 && historicTrade.Price < currentWallet.HighestBid.Price))
                {
                    nbEmptyRuns = 0;
                    objMarket   = objExchangeSimulator.GetMarket(historicTrade.Time);
                    objExchange.ExecuteOrders(objMarket, ref currentWallet, ref toReturn);
                }
                if (historicTrade.Time.Subtract(lastBotTime) > objSimulation.BotPeriod.Value)
                {
                    currentWallet.Time = historicTrade.Time;
                    bool isBigVariation =
                        Math.Abs((historicTrade.Price - lastBotTicker) / historicTrade.Price)
                        > objSimulation.SkippedVariationRate / 100;

                    if (!objSimulation.FastSimulation ||
                        nbEmptyRuns < objSimulation.SkippedMinVoidRuns ||
                        nbEmptyRuns >= objSimulation.SkippedMaxRuns ||
                        isBigVariation)
                    {
                        if (objMarket == null)
                        {
                            objMarket = objExchangeSimulator.GetMarket(historicTrade.Time);
                        }
                        var newOrders = obStrategy.ComputeNewOrders(currentWallet, objMarket, objExchange, toReturn);
                        currentWallet.IntegrateOrders(newOrders.Orders.ToArray());
                        lastBotTicker = objMarket.Ticker.Last;
                        if (newOrders.Orders.Count == 0 && !isBigVariation && nbEmptyRuns < objSimulation.SkippedMaxRuns)
                        {
                            nbEmptyRuns++;
                        }
                        else
                        {
                            nbEmptyRuns = 0;
                        }
                    }
                    else
                    {
                        nbEmptyRuns++;
                    }
                    lastBotTime = historicTrade.Time;
                }
                objMarket = null;
            }
            return(toReturn);
        }
예제 #3
0
        /// <summary>
        ///  Updates the orders according to the available balance (overflow orders are removed), and to the exchange min order settings.
        /// </summary>
        /// <param name="exchange">the exchange defining minimum order settings</param>
        public void FitOrders(ExchangeInfo exchange)
        {
            this.ConsolidateOrders();


            //first we fit orders according to the available resources
            decimal totalBids = this.GetTotalBidsSecondary();

            if (totalBids > 0)
            {
                var coefBids = Math.Max(this.SecondaryBalance, 0) / totalBids;
                if (coefBids < 1)
                {
                    decimal cumulativeBids = 0;
                    foreach (var bid in this.OrderedBids)
                    {
                        //bid.amount = Decimal.Round(bid.amount * coefBids, exchange.AmountDecil, MidpointRounding.ToEven)
                        cumulativeBids += bid.Value;
                        if (cumulativeBids > this.SecondaryBalance)
                        {
                            this.Orders.Remove(bid);
                        }
                    }
                }
            }
            var totalAsks = this.GetTotalAsksPrimary();

            if (totalAsks > 0)
            {
                var coefAsks = Math.Max(this.PrimaryBalance, 0) / totalAsks;
                if (coefAsks < 1)
                {
                    decimal cumulativeAsks = 0;
                    var     decreasingAsks = this.OrderedAsks;
                    decreasingAsks.Reverse();
                    foreach (var ask in decreasingAsks)
                    {
                        //ask.amount = Decimal.Round(ask.amount * coefAsks, exchange.AmountDecil, MidpointRounding.ToEven)
                        cumulativeAsks += ask.Amount;
                        if (cumulativeAsks > this.PrimaryBalance)
                        {
                            _orders.Remove(ask);
                        }
                    }
                }
            }


            var cleanOrders = new List <Order>();

            foreach (var objOrder in _orders)
            {
                if (objOrder.IsCancel)
                {
                    cleanOrders.Add(objOrder);
                }
                else
                {
                    if (objOrder.Amount >= Math.Max(exchange.MinOrderAmount, exchange.MinOrderValue / objOrder.Price))
                    {
                        objOrder.Price  = decimal.Round(objOrder.Price, exchange.PriceDecil);
                        objOrder.Amount = decimal.Round(objOrder.Amount, exchange.AmountDecil);
                        cleanOrders.Add(objOrder);
                    }
                }
            }
            Orders = cleanOrders;
        }
 public TradingHistory RunSimulation(Wallet initialWallet, ITradingStrategy obStrategy, ExchangeInfo objExchange, IEnumerable <Trade> exchangeHistory)
 {
     return(SimulationInfo.RunSimulation(this, initialWallet, obStrategy, objExchange, exchangeHistory));
 }