Exemple #1
0
 public void ComputeFees(CommercialAccount objAccount, TradingHistory history)
 {
     if (DateTime.Now > this.StartDate)
     {
         if (objAccount.PastDebits.Count == 0)
         {
             //todo: handle that case
         }
         else
         {
             if (objAccount.LastDebit.Time.Subtract(objAccount.FirstDebit.Time) > TrialDuration.Value)
             {
                 foreach (CommercialFee objFee in Fees.Instances)
                 {
                     List <WalletPayment> feeList;
                     if (!objAccount.PastDebits.TryGetValue(objFee.Name, out feeList))
                     {
                         feeList = new List <WalletPayment>();
                         objAccount.PastDebits[objFee.Name] = feeList;
                     }
                     if (feeList.Count == 0 || feeList[0].Time.Add(objFee.Period.Value) < DateTime.Now)
                     {
                         var newPayment = objFee.ComputePayment(history);
                         objAccount.AddDebit(objFee, newPayment);
                     }
                 }
             }
         }
     }
 }
Exemple #2
0
        public void ExecuteOrders(MarketInfo objMarket, ref Wallet targetWallet, ref TradingHistory history)
        {
            var trades        = new List <Trade>();
            var fees          = new List <Payment>();
            var matchedOrders = this.MatchOrders(ref targetWallet, objMarket.Ticker.Last);

            foreach (var matchedOrder in matchedOrders)
            {
                Trade trade = new Trade()
                {
                    Time   = objMarket.Time,
                    Price  = matchedOrder.Price,
                    Amount = matchedOrder.Amount
                };
                Payment fee = new Payment()
                {
                    Time  = objMarket.Time,
                    Label = matchedOrder.FriendlyId
                };
                if (matchedOrder.OrderType == OrderType.Buy)
                {
                    trade.TradeType = TradeType.Buy;
                    fee.Currency    = objMarket.PrimaryCode;
                    fee.Amount      = matchedOrder.Amount * BidCommission / 100m;
                    fee.Label       = string.Format("{0} - Bid Fee: {1} % = {2} {3}"
                                                    , fee.Label
                                                    , BidCommission.ToString(CultureInfo.InvariantCulture)
                                                    , fee.Amount
                                                    , fee.Currency);
                    targetWallet.SecondaryBalance = targetWallet.SecondaryBalance - matchedOrder.Value;
                    targetWallet.PrimaryBalance   = targetWallet.PrimaryBalance + matchedOrder.Amount - fee.Amount;
                }
                else if (matchedOrder.OrderType == OrderType.Sell)
                {
                    trade.TradeType = TradeType.Sell;
                    fee.Currency    = objMarket.SecondaryCode;
                    fee.Amount      = matchedOrder.Value * AskCommission / 100m;
                    fee.Label       = string.Format("{0} - Ask Fee: {1} % = {2} {3}"
                                                    , fee.Label
                                                    , AskCommission.ToString(CultureInfo.InvariantCulture)
                                                    , fee.Amount
                                                    , fee.Currency);
                    targetWallet.SecondaryBalance = targetWallet.SecondaryBalance + matchedOrder.Value - fee.Amount;
                    targetWallet.PrimaryBalance   = targetWallet.PrimaryBalance - matchedOrder.Amount;
                }
                trades.Add(trade);
                fees.Add(fee);
                targetWallet.Orders.Remove(matchedOrder);
            }

            targetWallet.Time = objMarket.Time;
            history.Update(targetWallet, objMarket, trades, fees);
        }
        public Wallet ComputeNewOrders(Wallet currentOrders, MarketInfo objMarket, ExchangeInfo objExchange, TradingHistory history)
        {
            //the newOrders Wallet variable will contain all ask/bid/cancel orders to issue

            var newOrders = new Wallet();

            //start with reserved resource
            //Dim askReserve As Decimal = Math.Max(Me._AskReserveAmount, currentOrders.btcs * (Me._AskReserveRate / 100))
            //Dim bidReserve As Decimal = Math.Max(Me._BidReserveValue, currentOrders.usds * (Me._BidReserveRate / 100))

            decimal avBtcsForTrading = currentOrders.PrimaryBalance;
            //- askReserve
            decimal avUsdsForTrading = currentOrders.SecondaryBalance;

            //- bidReserve

            //Then We simplify the current orders by merging orders of the same price, issueing corresponding cancel/new orders
            newOrders.ConsolidateOrders(ref currentOrders, true);

            //Feed the new orders wallet with available resources, Reserve resources for current open orders
            newOrders.PrimaryBalance   = Math.Max(avBtcsForTrading - currentOrders.GetTotalAsksPrimary(), 0);
            newOrders.SecondaryBalance = Math.Max(avUsdsForTrading - currentOrders.GetTotalBidsSecondary(), 0);

            var tContext = new TradingContext(currentOrders, newOrders, objMarket, objExchange, history.GetLastTrend(), this);

            this.ComputeNewOrders(ref tContext);


            tContext.NewOrders.FitOrders(objExchange);
            //we update the trading history with last data
            history.Update(currentOrders, objMarket, tContext.NewOrders);
            return(tContext.NewOrders);
        }
        public WalletPayment ComputePayment(TradingHistory history)
        {
            WalletPayment ComputePayment = null;

            return(ComputePayment);
        }
        public Wallet ComputeNewOrders(Wallet currentOrders, MarketInfo objMarket, ExchangeInfo objExchange, TradingHistory history)
        {
            var newOrders  = new Wallet();
            var askReserve = Math.Max(this.AskReserveAmount, currentOrders.PrimaryBalance * AskReserveRate / 100m);
            var bidReserve = Math.Max(this.BidReserveValue, currentOrders.SecondaryBalance * BidReserveRate / 100m);

            decimal avBtcsForTrading = currentOrders.PrimaryBalance - askReserve;
            decimal avUsdsForTrading = currentOrders.SecondaryBalance - bidReserve;

            //todo: should we update the original wallet?
            newOrders.ConsolidateOrders(ref currentOrders, true);

            newOrders.PrimaryBalance   = Math.Max(avBtcsForTrading - currentOrders.GetTotalAsksPrimary(), decimal.Zero);
            newOrders.SecondaryBalance = Math.Max(decimal.Subtract(avUsdsForTrading, currentOrders.GetTotalBidsSecondary()), decimal.Zero);

            var tContext = new TradingContext(currentOrders, newOrders, objMarket, objExchange, history.GetLastTrend(), this);

            this.ComputeNewOrders(ref tContext);
            if (this.NoAsks)
            {
                tContext.NewOrders.ClearAsks();
                if (this.ClearAsks)
                {
                    tContext.NewOrders.CancelExistingOrders(tContext.CurrentOrders.OrderedAsks.ToArray());
                }
            }
            if (this.NoBids)
            {
                tContext.NewOrders.ClearBids();
                if (this.ClearBids)
                {
                    tContext.NewOrders.CancelExistingOrders(tContext.CurrentOrders.OrderedBids.ToArray());
                }
            }
            tContext.NewOrders.FitOrders(objExchange);
            history.Update(currentOrders, objMarket, tContext.NewOrders);
            return(tContext.NewOrders);
        }
        /// <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);
        }