Пример #1
0
        public void TotalPnlLongIsTheSumOfRealizedAndUnrealizedPnlForShortPositions()
        {
            var trade = new Trade();
            var date = new DateTime(2000, 1, 1);
            trade.Orders = new List<Order>
            {
                new Order { Instrument = _inst, Quantity = -10, FXRateToBase = 1, Price = 100, BuySell = "BUY", TradeDate = date },
                new Order { Instrument = _inst, Quantity = 5, FXRateToBase = 1, Price = 95, BuySell = "SELL", TradeDate = date }
            };

            var tracker = new TradeTracker(trade, 1);
            foreach (Order o in trade.Orders)
            {
                tracker.AddOrder(o);
            }

            var data = new Dictionary<int, TimeSeries> { 
                { 1, TimeSeriesGenerator.GenerateData(date, date, 90) }
            };

            foreach (TimeSeries ts in data.Values)
            {
                ts.ProgressTo(date);
            }

            tracker.Update(date, data, null);

            Assert.AreEqual(5 * 5 + 10 * 5, tracker.TotalPnL);
            Assert.AreEqual(5 * 5 + 10 * 5, tracker.TotalPnlShort);
        }
Пример #2
0
        public TradeTracker(Trade trade, decimal optionsCapitalUsageMultiplier)
        {
            _optionsCapitalUsageMultiplier = optionsCapitalUsageMultiplier;

            Positions = new Dictionary<int, Position>()
            {
                //dummy position used for cash transactions without a related instrument
                { NullInstrumentId, new Position(new Instrument(), _optionsCapitalUsageMultiplier)} 
            };
            CurrencyPositions = new Dictionary<int, CurrencyPosition>();

            CumulativeReturns = new SortedList<DateTime, double>();
            CumulativePnL = new SortedList<DateTime, decimal>();

            Capital = new AllocatedCapital();

            _ordersRemaining = trade.Orders == null ? 0 : trade.Orders.Count;
            _cashTransactionsRemaining = trade.CashTransactions == null ? 0 : trade.CashTransactions.Count;

            Trade = trade;

            _currentEquity = 1;
            _totalPnL = 0;
            TodaysPnL = 0;
        }
Пример #3
0
        public void SetUp()
        {
            _inst = new Instrument {ID = 1, Multiplier = 1, AssetCategory = AssetClass.Stock};

            _t = new Trade
            {
                Orders = new List<Order>(),
                CashTransactions = new List<CashTransaction>(),
                FXTransactions = new List<FXTransaction>()
            };

            _dsMock = new Mock<IDataSourcer>();

            _dsMock.Setup(x => x.GetData(It.IsAny<Instrument>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), It.IsAny<QDMS.BarSize>()))
                .Returns<Instrument, DateTime, DateTime, QDMS.BarSize>((a, b, c, d) => GenerateData(b, c));

            _contextMock = new Mock<IDBContext>();

            _dbSetStub = new DbSetStub<EquitySummary>();
            var equitySummaries = new List<EquitySummary> 
            { 
                new EquitySummary 
                { 
                    Date = new DateTime(2000,1,1),
                    Total = 10000
                }
            };
            _dbSetStub.AddRange(equitySummaries);
            _contextMock.SetupGet(x => x.EquitySummaries).Returns(_dbSetStub);

            _repository = new TradesRepository(_contextMock.Object, _dsMock.Object, 0.1m);
        }
Пример #4
0
        /// <summary>
        /// Create a new trade with a given name.
        /// Returns the created trade.
        /// </summary>
        protected Trade CreateTrade(string name)
        {
            var trade = new Trade() { Name = name, Open = true };
            TradesRepository.Add(trade);
            OpenTrades.Add(trade);

            Logger.Log(LogLevel.Info, "User script {0} created trade {1}", this.GetType().Name, trade);

            return trade;
        }
Пример #5
0
        /// <summary>
        /// Add a tag to a trade.
        /// </summary>
        protected void SetTag(Trade trade, string tagName)
        {
            var tag = Tags.FirstOrDefault(x => x.Name == tagName);
            if(tag == null)
            {
                Logger.Log(LogLevel.Info, "User script {0} tried to add tag {1} to trade {2}, but it was not found", this.GetType().Name, tagName, trade);
                return;
            }

            SetTag(trade, tag);
        }
Пример #6
0
        /// <summary>
        /// Set a trade's strategy.
        /// </summary>
        protected void SetStrategy(Trade trade, string strategyName)
        {
            var strategy = Strategies.FirstOrDefault(x => x.Name == strategyName);
            if (strategy == null)
            {
                Logger.Log(LogLevel.Warn, "User script {0} tried to set strategy of trade {1} to {2}, but it was not found.", this.GetType().Name, trade, strategyName);
                return;
            }

            SetStrategy(trade, strategy);
        }
Пример #7
0
        /// <summary>
        /// Add a tag to a trade.
        /// </summary>
        protected void SetTag(Trade trade, Tag tag)
        {
            if (tag == null) return;
            if (trade.Tags != null && trade.Tags.Contains(tag)) return;

            if(trade.Tags == null)
            {
                trade.Tags = new ObservableCollection<Tag>();
            }

            trade.Tags.Add(tag);

            Logger.Log(LogLevel.Info, "User script {0} added tag {1} to trade {2}", this.GetType().Name, tag, trade);
        }
Пример #8
0
        public TradeWindow(Trade trade, IDBContext context, IDataSourcer dataSourcer)
        {
            Trade = trade;
            _context = context;

            InitializeComponent();

            ViewModel = new TradeViewModel(trade, dataSourcer, context);
            DataContext = ViewModel;

            InitializeFontSizes();

            FontFamilyComboBox.ItemsSource = Fonts.SystemFontFamilies;
            FontSizeComboBox.ItemsSource = FontSizes;

            //load the notes
            LoadNotes();
        }
Пример #9
0
        public TradeViewModel(Trade trade, IDataSourcer dataSourcer, IDBContext context) : base(null)
        {
            context.Trades
                    .Where(x => x.ID == trade.ID)
                    .Include(x => x.Strategy)
                    .Include(x => x.Orders)
                    .Include("Orders.Instrument")
                    .Include("Orders.Currency")
                    .Include(x => x.CashTransactions)
                    .Include("CashTransactions.Instrument")
                    .Include("CashTransactions.Currency")
                    .Include(x => x.FXTransactions)
                    .Include("FXTransactions.FunctionalCurrency")
                    .Include("FXTransactions.FXCurrency")
                    .Load();

            Trade = trade;
            Tracker = TradeSim.SimulateTrade(trade, context, dataSourcer, Properties.Settings.Default.optionsCapitalUsageMultiplier);
        }
Пример #10
0
        /// <summary>
        /// Add an order to a trade.
        /// Returns true if the trade is found and the order successfully added.
        /// </summary>
        protected bool SetTrade(Order order, Trade trade)
        {
            if(trade == null)
            {
                Logger.Log(LogLevel.Warn, "User script {0} tried to add order {1} to a null trade", this.GetType().Name, order);
                return false;
            }

            if(!trade.Open)
            {
                Logger.Log(LogLevel.Warn, "User script {0} tried to add order {1} to a closed trade: {2}", this.GetType().Name, order, trade);
                return false;
            }

            TradesRepository.AddOrder(trade, order);
            
            Logger.Log(LogLevel.Info, "User script {0} added order {1} to trade {2}", this.GetType().Name, order, trade);

            return true;
        }
Пример #11
0
        public static TradeTracker SimulateTrade(Trade trade, IDBContext context, IDataSourcer dataSourcer, decimal optionsCapitalUsageMultiplier)
        {
            var tracker = new TradeTracker(trade, optionsCapitalUsageMultiplier);

            //starting and ending dates
            DateTime startDate = trade.DateOpened;
            DateTime endDate;
            
            if(!trade.Open && trade.DateClosed != null)
            {
                endDate = trade.DateClosed.Value.Date;
            }
            else
            {
                var lastSummary = context.EquitySummaries.OrderByDescending(x => x.Date).First();
                endDate = lastSummary.Date.Date;
            }

            var orders = trade.Orders == null 
                ? new List<Order>()
                : trade.Orders.OrderBy(x => x.TradeDate).ToList();

            var cashTransactions = trade.CashTransactions == null
                ? new List<CashTransaction>()
                : trade.CashTransactions.OrderBy(x => x.TransactionDate).ToList();

            var fxTransactions = trade.FXTransactions == null
                ? new List<FXTransaction>()
                : trade.FXTransactions.OrderBy(x => x.DateTime).ToList();

            //Grab the data
            Dictionary<int, TimeSeries> data = GetInstrumentData(trade, dataSourcer, startDate, endDate);
            Dictionary<int, TimeSeries> fxData = GetFXData(trade, context);

            DateTime currentDate = startDate.Date;
            //Loop through the dates
            while (currentDate <= endDate)
            {
                //Progress time series to current date
                foreach (TimeSeries ts in data.Values)
                {
                    ts.ProgressTo(currentDate);
                }
                foreach (TimeSeries ts in fxData.Values)
                {
                    ts.ProgressTo(currentDate);
                }

                //Add orders
                while (orders.Count > 0 && orders[0].TradeDate.Date <= currentDate)
                {
                    tracker.AddOrder(orders[0]);
                    orders.RemoveAt(0);
                }

                //Add cash transactions
                while (cashTransactions.Count > 0 && cashTransactions[0].TransactionDate.Date <= currentDate)
                {
                    tracker.AddCashTransaction(cashTransactions[0]);
                    cashTransactions.RemoveAt(0);
                }

                //add fx transactions
                while (fxTransactions.Count > 0 && fxTransactions[0].DateTime.Date <= currentDate)
                {
                    tracker.AddFXTransaction(fxTransactions[0]);
                    fxTransactions.RemoveAt(0);
                }

                tracker.Update(currentDate, data, fxData);

                if (orders.Count == 0 && cashTransactions.Count == 0 && fxTransactions.Count == 0 && !tracker.Open) break;

                currentDate = currentDate.AddDays(1);
            }

            return tracker;
        }
Пример #12
0
 public TradeViewModel() : base(null)
 {
     Trade = new Trade();
 }
Пример #13
0
        /// <summary>
        /// Close a trade.
        /// </summary>
        protected void CloseTrade(Trade trade)
        {
            if(!trade.Open)
            {
                Logger.Log(LogLevel.Info, "User script {0} tried to close trade {1} but it was already closed", this.GetType().Name, trade);
                return;
            }

            if(!trade.IsClosable())
            {
                Logger.Log(LogLevel.Info, "User script {0} tried to close trade {1} but the trade can not be closed", this.GetType().Name, trade);
                return;
            }

            trade.Open = false;
            TradesRepository.UpdateStats(trade);

            Logger.Log(LogLevel.Info, "User script {0} closed trade {1}", this.GetType().Name, trade);
        }
Пример #14
0
        /// <summary>
        /// Set a trade's strategy.
        /// </summary>
        protected void SetStrategy(Trade trade, Strategy strategy)
        {
            trade.Strategy = strategy;

            Logger.Log(LogLevel.Info, "User script {0} set strategy of trade {1} to {2}", this.GetType().Name, trade, strategy);
        }
Пример #15
0
        private void TradePickerNewTradeTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.Key == Key.Enter && !String.IsNullOrEmpty(TradePickerNewTradeTextBox.Text))
            {
                var selectedOrder = (Order)OrdersGrid.SelectedItem;
                var newTrade = new Trade { Name = TradePickerNewTradeTextBox.Text, Open = true };
                Context.Trades.Add(newTrade);
                newTrade.Tags = new List<Tag>();

                Task.Run(() =>
                    {
                        TradesRepository.AddOrder(newTrade, selectedOrder);
                        TradesRepository.Save();
                    });
                TradePickerNewTradeTextBox.Text = "";
                OrdersGridTradePickerPopup.IsOpen = false;
                OrdersGrid.CommitEdit();
            }
        }
Пример #16
0
        public void AddingOrderInForeignCurrencyResultsInFxPositionAddition()
        {
            var trade = new Trade();
            var date = new DateTime(2000, 1, 1);
            var eur = new Currency { ID = 2, Name = "EUR" };
            trade.Orders = new List<Order>
            {
                new Order { Instrument = _inst, Quantity = 10, FXRateToBase = 1.5m, Multiplier = 1, Price = 100, BuySell = "BUY", TradeDate = date, Currency = eur, CurrencyID = 2 },
            };

            var tracker = new TradeTracker(trade, 1);
            foreach (Order o in trade.Orders)
            {
                tracker.AddOrder(o);
            }

            Assert.IsTrue(tracker.CurrencyPositions.ContainsKey(2));
            Assert.IsTrue(tracker.CurrencyPositions[2].Quantity == -10 * 100);
            Assert.IsTrue(tracker.CurrencyPositions[2].CostBasis == 1.5m);
        }
Пример #17
0
        private static List<int> GetNeededFXIDs(Trade trade)
        {
            var currencyIDs = new List<int>();
            if (trade.Orders != null)
            {
                currencyIDs.AddRange(trade.Orders.Select(x => x.CurrencyID));
            }

            if (trade.CashTransactions != null)
            {
                currencyIDs.AddRange(trade.CashTransactions.Select(x => x.CurrencyID));
            }

            if (trade.FXTransactions != null)
            {
                currencyIDs.AddRange(trade.FXTransactions.Select(x => x.FXCurrencyID));
            }
            return currencyIDs.Distinct().ToList();
        }
Пример #18
0
        private static Dictionary<int, TimeSeries> GetFXData(Trade trade, IDBContext context)
        {
            List<int> neededFXIDs = GetNeededFXIDs(trade);
            var fxData = new Dictionary<int, TimeSeries>();
            foreach (int id in neededFXIDs)
            {
                if (id <= 1) continue;

                int id1 = id;
                fxData.Add(id, TimeSeriesFromFXRates(context.FXRates.Where(x => x.FromCurrencyID == id1).OrderBy(x => x.Date)));
            }
            return fxData;
        }
Пример #19
0
        public void SetTradeStats(Trade trade)
        {
            var positions = Positions.Values;

            //Capital usage stats
            trade.CapitalTotal =
                Capital.Gross.Count(x => x > 0) > 0
                    ? Capital.Gross.Where(x => x > 0).Average()
                    : 0;

            trade.CapitalLong =
                Capital.Long.Count(x => x > 0) > 0
                    ? Capital.Long.Where(x => x > 0).Average()
                    : 0;

            trade.CapitalShort =
                Capital.Short.Count(x => x > 0) > 0
                    ? Capital.Short.Where(x => x > 0).Average()
                    : 0;

            trade.CapitalNet = trade.CapitalLong - trade.CapitalShort;

            //Realized dollar result stats
            trade.ResultDollars = RealizedPnL;
            trade.ResultDollarsLong = RealizedPnLLong;
            trade.ResultDollarsShort = RealizedPnLShort;

            //Realized percent result stats
            trade.ResultPct = trade.CapitalTotal > 0
                ? (double)(trade.ResultDollars / trade.CapitalTotal)
                : 0;

            trade.ResultPctLong = trade.CapitalLong > 0
                ? (double)(trade.ResultDollarsLong / trade.CapitalLong)
                : 0;

            trade.ResultPctShort = trade.CapitalShort > 0
                ? (double)(trade.ResultDollarsShort / trade.CapitalShort)
                : 0;

            //Commissions
            if (trade.Orders != null)
            {
                trade.Commissions = trade.Orders.Sum(x => x.CommissionInBase);
            }


            //Unrealized result stats
            trade.UnrealizedResultDollars = TotalPnL - RealizedPnL;
            trade.UnrealizedResultDollarsLong = positions.Sum(x => x.PnLLong - x.RealizedPnLLong);
            trade.UnrealizedResultDollarsShort = positions.Sum(x => x.PnLShort - x.RealizedPnLShort);

            //Unrealized percent result stats
            trade.UnrealizedResultPct = trade.CapitalTotal > 0
                ? (double)(trade.UnrealizedResultDollars / trade.CapitalTotal)
                : 0;

            trade.UnrealizedResultPctLong = trade.CapitalLong > 0
                ? (double)(trade.UnrealizedResultDollarsLong / trade.CapitalLong)
                : 0;

            trade.UnrealizedResultPctShort = trade.CapitalShort > 0
                ? (double)(trade.UnrealizedResultDollarsShort / trade.CapitalShort)
                : 0;
        }
Пример #20
0
        public void AddingCashTransactionInForeignCurrencyResultsInFxPositionAddition()
        {
            var trade = new Trade();
            var date = new DateTime(2000, 1, 1);
            var eur = new Currency { ID = 2, Name = "EUR" };
            var ct = new CashTransaction { InstrumentID = 1, Currency = eur, CurrencyID = 2, Amount = 50, FXRateToBase = 1.5m, Instrument = _inst, TransactionDate = date, AssetCategory = AssetClass.Stock };
            trade.CashTransactions = new List<CashTransaction> { ct };
            var tracker = new TradeTracker(trade, 1);
            foreach (CashTransaction c in trade.CashTransactions)
            {
                tracker.AddCashTransaction(c);
            }

            Assert.IsTrue(tracker.CurrencyPositions.ContainsKey(2));
            Assert.IsTrue(tracker.CurrencyPositions[2].Quantity == 50);
            Assert.IsTrue(tracker.CurrencyPositions[2].CostBasis == 1.5m);
        }
Пример #21
0
        private static Dictionary<int, TimeSeries> GetInstrumentData(Trade trade, IDataSourcer dataSourcer, DateTime startDate, DateTime endDate)
        {
            var data = new Dictionary<int, TimeSeries>();
            if (trade.Orders == null) return data;

            foreach (EntityModel.Instrument inst in trade.Orders.Select(x => x.Instrument).Distinct(x => x.ID))
            {
                data.Add(inst.ID, new TimeSeries(dataSourcer.GetData(inst, startDate, endDate)));
            }
            return data;
        }
Пример #22
0
        public void TodaysPnlResetsEvenWhenTrackerIsNotOpen()
        {
            var trade = new Trade();
            var date = new DateTime(2000, 1, 1);
            trade.Orders = new List<Order>
            {
                new Order { Instrument = _inst, Quantity = -10, FXRateToBase = 1, Price = 100, BuySell = "BUY", TradeDate = date },
                new Order { Instrument = _inst, Quantity = 5, FXRateToBase = 1, Price = 95, BuySell = "SELL", TradeDate = date }
            };

            var tracker = new TradeTracker(trade, 1);
            foreach (Order o in trade.Orders)
            {
                tracker.AddOrder(o);
            }

            var data = new Dictionary<int, TimeSeries> { 
                { 1, TimeSeriesGenerator.GenerateData(date, date.AddDays(1), 90) }
            };

            foreach (TimeSeries ts in data.Values)
            {
                ts.ProgressTo(date);
            }

            tracker.Update(date, data, null);

            Assert.AreEqual(5 * 5 + 10 * 5, tracker.TodaysPnL);

            data[1].ProgressTo(date.AddDays(1));
            tracker.Update(date.AddDays(1), data, null);
            Assert.AreEqual(0, tracker.TodaysPnL);
        }
Пример #23
0
        public void CapitalUsageCorrectlyTracked()
        {
            var inst2 = new Instrument { ID = 2, Multiplier = 1, AssetCategory = AssetClass.Stock };

            var order1 = new Order
            {
                Instrument = _inst,
                InstrumentID = _inst.ID,
                Multiplier = 1,
                FXRateToBase = 1,
                Price = 10,
                Quantity = 100,
                CurrencyID = 1,
                BuySell = "BUY",
                IsReal = true,
                TradeDate = new DateTime(2000, 1, 2)
            };

            var order2 = new Order
            {
                Instrument = inst2,
                InstrumentID = inst2.ID,
                Multiplier = 1,
                FXRateToBase = 1,
                Price = 20,
                Quantity = -100,
                CurrencyID = 1,
                BuySell = "SELL",
                IsReal = true,
                TradeDate = new DateTime(2000, 1, 3, 12, 0, 0)
            };

            var order3 = new Order
            {
                Instrument = inst2,
                InstrumentID = inst2.ID,
                Multiplier = 1,
                FXRateToBase = 1,
                Price = 19,
                Quantity = 100,
                CurrencyID = 1,
                BuySell = "BUY",
                IsReal = true,
                TradeDate = new DateTime(2000, 1, 3, 13, 0, 0)
            };

            var trade = new Trade
            {
                Orders = new List<Order> { order1, order2, order3 }
            };

            var trades = new List<Trade> { trade };

            _data = new Dictionary<int, TimeSeries>
            {
                { 1, TimeSeriesGenerator.GenerateData(new DateTime(2000,1,1), new DateTime(2000,2,1), 11) },
                { 2, TimeSeriesGenerator.GenerateData(new DateTime(2000,1,1), new DateTime(2000,2,1), 20) }
            };

            var tracker = new PortfolioTracker(_data, _fxData, trades, "test", new DateTime(2000, 1, 1), 1);

            var date = new DateTime(2000, 1, 1);
            foreach (TimeSeries ts in _data.Values)
            {
                ts.ProgressTo(date);
            }
            
            tracker.ProcessItemsAt(date);
            tracker.OnDayClose(date, 10000);

            Assert.AreEqual(0, tracker.Capital.Gross.Last());

            date = date.AddDays(1);
            foreach (TimeSeries ts in _data.Values)
            {
                ts.ProgressTo(date);
            }
            tracker.ProcessItemsAt(date);
            tracker.OnDayClose(date, 10000);

            Assert.AreEqual(10 * 100, tracker.Capital.Gross.Last());
            Assert.AreEqual(10 * 100, tracker.Capital.Long.Last());

            date = date.AddDays(1);
            foreach (TimeSeries ts in _data.Values)
            {
                ts.ProgressTo(date);
            }
            tracker.ProcessItemsAt(date);
            tracker.OnDayClose(date, 10000);

            Assert.AreEqual(11 * 100 + 20 * 100, tracker.Capital.Gross.Last());
            Assert.AreEqual(11 * 100, tracker.Capital.Long.Last());
            Assert.AreEqual(20 * 100, tracker.Capital.Short.Last());
        }
Пример #24
0
        public void TotalPnlLongIsTheSumOfRealizedAndUnrealizedPnlForCurrencyPositions()
        {
            var trade = new Trade();
            var date = new DateTime(2000, 1, 1);
            var fxCurrency = new Currency { ID = 2, Name = "CAD" };
            trade.FXTransactions = new List<FXTransaction>
            {
                new FXTransaction { FXCurrency = fxCurrency, Quantity = 1000, Proceeds = 1500, Cost = -1500 },
                new FXTransaction { FXCurrency = fxCurrency, Quantity = -500, Proceeds = -850, Cost = 850 },
            };

            var tracker = new TradeTracker(trade, 1);
            foreach (FXTransaction fxt in trade.FXTransactions)
            {
                tracker.AddFXTransaction(fxt);
            }

            var data = new Dictionary<int, TimeSeries> { 
                { 2, TimeSeriesGenerator.GenerateData(date, date, 1.55m) }
            };

            foreach (TimeSeries ts in data.Values)
            {
                ts.ProgressTo(date);
            }

            tracker.Update(date, new Dictionary<int, TimeSeries>(), data);

            Assert.AreEqual(100 + 500 * (1.55m - 1.5m), tracker.TotalPnL);
        }
Пример #25
0
        private void OrdersContextMenuNewTradeTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                //close the context menu
                var ordersGridContextMenu = (ContextMenu)Resources["OrdersGridContextMenu"];
                var ordersContextMenuNewTradeTextBox = (TextBox)sender;
                ordersGridContextMenu.IsOpen = false;

                //only add a trade if there's a name in the box
                if (String.IsNullOrEmpty(ordersContextMenuNewTradeTextBox.Text)) return;

                List<Order> selectedOrders = OrdersGrid.SelectedItems.Cast<Order>().ToList();

                var newTrade = new Trade { Name = ordersContextMenuNewTradeTextBox.Text, Open = true };
                Context.Trades.Add(newTrade);
                newTrade.Tags = new List<Tag>();

                Task.Run(() =>
                {
                    foreach (Order o in selectedOrders)
                    {
                        TradesRepository.AddOrder(newTrade, o);
                    }
                    TradesRepository.Save();
                });

                ordersContextMenuNewTradeTextBox.Text = "";
            }
        }