Exemplo n.º 1
0
 /// <summary>
 /// Sets the associated quantfund.
 /// </summary>
 /// <param name="quantfund">The quantfund.</param>
 public virtual void SetQuantFund(IQuantFund quantfund)
 {
     if (QuantFund == null && quantfund != null)
     {
         QuantFund = quantfund;
     }
 }
Exemplo n.º 2
0
        /// <summary>
        /// Add cash
        /// </summary>
        /// <param name="quantfund"></param>
        /// <param name="currency"></param>
        /// <param name="cash"></param>
        /// <param name="settlementutc"></param>
        public void AddCash(CurrencyType currency, decimal cash, IQuantFund quantfund = null, DateTime?settlementutc = null)
        {
            //Get funds for quant fund
            CashPosition cashposition;

            if (quantfund == null)
            {
                cashposition = GetBaseAccount(currency);
            }
            else
            {
                //Check if we know this quant fund
                if (!_cashknown.ContainsKey(quantfund.FundId))
                {
                    _cashknown[quantfund.FundId] = new Dictionary <CurrencyType, CashPosition>();
                }

                //Check if we know this currency type
                if (!_cashknown[quantfund.FundId].TryGetValue(currency, out cashposition))
                {
                    cashposition = new CashPosition(currency, 0);
                    _cashknown[quantfund.FundId].Add(currency, cashposition);
                }
            }

            //Set items
            cashposition.AddCash(settlementutc.HasValue
                ? new UnsettledCash(cash, settlementutc.Value)
                : new SettledCash(cash));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Set initial fund allocation to quant fund, can only be set once
        /// </summary>
        /// <param name="quantfund"></param>
        /// <param name="basecurrency"></param>
        /// <param name="cash"></param>
        public void AddQuantFund(IQuantFund quantfund, CurrencyType basecurrency, decimal cash)
        {
            lock (_locker)
            {
                //Can only be set once
                if (_cashknown.ContainsKey(quantfund.FundId))
                {
                    return;
                }

                //Check cash integrity
                cash = Math.Abs(cash);

                //Get base balance
                var baseposition = GetCashPositions()[basecurrency];

                //Check if we have enough funds
                if (baseposition.TotalCash < cash)
                {
                    _log.Warn($"You are allocating more cash than the account has on cash available. Avalaible = {baseposition.TotalCash}, Allocate ({quantfund.FundId}) = {cash}");
                }

                _cashknown.Add(quantfund.FundId,
                               new Dictionary <CurrencyType, CashPosition>
                {
                    { basecurrency, new CashPosition(basecurrency, cash) }
                });

                //Some logging
                _log.Info($"Allocated {cash} {basecurrency} amount to fund with name {quantfund.Name}");

                //Remove from base
                baseposition.AddCash(new SettledCash(-cash));
            }
        }
Exemplo n.º 4
0
 /// <summary>
 /// Sets the associated quantfund.
 /// </summary>
 /// <param name="quantfund">The quantfund.</param>
 public override void SetQuantFund(IQuantFund quantfund)
 {
     if (QuantFund == null && quantfund != null)
     {
         QuantFund = quantfund;
         SetQuantFund(quantfund);
     }
 }
Exemplo n.º 5
0
 /// <summary>
 /// Removes all the scheduled actions for the specified quantfund.
 /// </summary>
 /// <param name="quantfund">The quantfund.</param>
 public void Remove(IQuantFund quantfund)
 {
     lock (_locker)
     {
         var found = _eventActions.Where(x => x.Value.FundId == quantfund.FundId).ToArray();
         found.ForEach(e => _eventActions.Remove(e.Key));
     }
 }
Exemplo n.º 6
0
        /// <summary>
        /// Removes the quant fund from this portfolio.
        /// </summary>
        /// <param name="quantfund">The quantfund.</param>
        /// <exception cref="NotImplementedException"></exception>
        public void RemoveFund(IQuantFund quantfund)
        {
            throw new NotImplementedException();

            //Send updates (so we know this quant fund was remvoved)
            EventRunner.Enqueue(FundInfoMessage.Generate(Id, quantfund), true);

            //Remove funds
            CashManager.RemoveQuantFund(quantfund);
        }
Exemplo n.º 7
0
 /// <summary>
 /// Generate fund information message
 /// </summary>
 /// <param name="portfolioid"></param>
 /// <param name="quantfund"></param>
 /// <returns></returns>
 public static FundInfoMessage Generate(string portfolioid, IQuantFund quantfund)
 {
     return(new FundInfoMessage
     {
         Status = quantfund.State,
         Id = quantfund.FundId,
         IsRunning = quantfund.IsRunning,
         Name = quantfund.Name,
         ROI = quantfund.Results.QuantFund.ROI,
         PortfolioId = portfolioid,
         StartedUtc = quantfund.StartedDTUtc
     });
 }
Exemplo n.º 8
0
        /// <summary>
        /// Adds a datasubscription for all non market price data available (delisting, splits, trading status etc)
        /// </summary>
        /// <param name="security">The security.</param>
        /// <param name="quantfund"></param>
        public void AddSubscription(IQuantFund quantfund, Security security)
        {
            //Helper function
            void AddSubscriptionType(DataType datatype)
            {
                var subscriptionrequest =
                    DataSubscriptionRequest.CreateSubscriptionRequest(security.Ticker, _datafeed.DataSource, null, datatype);

                AddSubscription(subscriptionrequest);

                //Add subscription to registered subscriptions
                if (!_registeredsubscriptions.ContainsKey(quantfund.FundId))
                {
                    _registeredsubscriptions.Add(quantfund.FundId, new List <DataSubscription>()
                    {
                        new DataSubscription(quantfund.FundId, subscriptionrequest, security, TimeZone.Utc, null)
                    });
                }
                else if (_registeredsubscriptions[quantfund.FundId].Count(x =>
                                                                          x.Request.GetSubscriptionName() == subscriptionrequest.GetSubscriptionName()) == 0)
                {
                    _registeredsubscriptions[quantfund.FundId].Add(new DataSubscription(quantfund.FundId, subscriptionrequest, security, TimeZone.Utc, null));
                }
            }

            //Add delisting information
            AddSubscriptionType(DataType.Delisting);

            //Add dividend notifications
            AddSubscriptionType(DataType.Dividend);

            //Add earning reports
            AddSubscriptionType(DataType.Earning);

            //Add financial reports
            AddSubscriptionType(DataType.Financial);

            //Add key stats
            AddSubscriptionType(DataType.KeyStat);

            //Add stock splits
            AddSubscriptionType(DataType.Split);

            //Add trading status updates
            AddSubscriptionType(DataType.TradingStatus);

            //Check base conversion
            AddBaseCurrencyConversionFeed(security);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Processes the submit ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="quantfund">Associated Quant Fund</param>
        /// <returns></returns>
        private OrderTicket ProcessSubmitTicket(SubmitOrderTicket ticket, IQuantFund quantfund)
        {
            if (quantfund != null && quantfund.IsBackfilling)
            {
                ticket.SetResponse(
                    OrderTicketResponse.Error(ticket.OrderId, OrderTicketResponseErrorCode.QuantFundBackfilling,
                                              $"Quant fund {ticket.FundId} is currently backfilling, cannot process orders."));
            }
            else
            {
                _orderTicketQueue.Add(ticket);
                ticket.SetResponse(OrderTicketResponse.Processed(ticket.OrderId), OrderTicketState.Processing);
            }

            return(ticket);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Removes the quant fund associated subscriptions.
        /// </summary>
        /// <param name="quantfund">The quantfund.</param>
        public void RemoveQuantFundSubscriptions(IQuantFund quantfund)
        {
            //get all tickers
            var tickers = ActiveTickers(quantfund);

            //Remove quant fund
            _registeredsubscriptions.Remove(quantfund.FundId);

            //Get all items which are no longer needed
            var active = _registeredsubscriptions
                         .SelectMany(x => x.Value.Select(n => n.Ticker))
                         .Distinct();

            //Remove all no longer used
            tickers.Where(x => !active.Contains(x))
            .ForEach(RemoveSubscription);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Cancels the order ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="quantfund">Ticket associated quant fund</param>
        /// <returns></returns>
        private OrderTicket ProcessCancelTicket(CancelOrderTicket ticket, IQuantFund quantfund)
        {
            //Try and get current order ticket
            if (!OrderTracker.TryGetOrder(ticket.OrderId, out PendingOrder pendingorder))
            {
                ticket.SetResponse(OrderTicketResponse.Error(ticket.OrderId, OrderTicketResponseErrorCode.UnableToFindOrder));
                return(ticket);
            }

            try
            {
                //Try and process cancel ticket
                if (pendingorder.OrderState.IsDone())
                {
                    _log.Error($"Order is already of state {pendingorder.OrderState} while trying to cancel this order");
                    ticket.SetResponse(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.InvalidOrderStatus));
                }
                else if (quantfund != null && quantfund.IsBackfilling)
                {
                    ticket.SetResponse(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.QuantFundBackfilling));
                }
                else
                {
                    // update the order status
                    var order = pendingorder.Order as OrderImpl;
                    order.State = OrderState.CancelPending;
                    pendingorder.UpdateOrder(order);

                    // notify the portfolio with an order event
                    HandleOrderTicketEvent(OrderTicketEvent.Cancelled(pendingorder.OrderId));

                    // send the request to be processed
                    ticket.SetResponse(OrderTicketResponse.Processed(ticket.OrderId), OrderTicketState.Processing);
                    _orderTicketQueue.Add(ticket);
                }
            }
            catch (Exception exc)
            {
                _log.Error(exc);
                ticket.SetResponse(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.ProcessingError, exc.Message));
            }

            //return result
            return(ticket);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Remove quant fund from following cash positions
        /// </summary>
        /// <param name="quantfund"></param>
        public void RemoveQuantFund(IQuantFund quantfund)
        {
            lock (_locker)
            {
                //Check if we know this quantfund
                if (!_cashknown.ContainsKey(quantfund.FundId))
                {
                    return;
                }

                //Remove balance from quant fund
                var cashholder = GetCashPositions(quantfund)[BaseCurrency];
                var baseholder = GetCashPositions()[BaseCurrency];

                //Move from cash holder and add to base
                baseholder.AddCash(new SettledCash(cashholder.TotalSettledCash));
                baseholder.AddCash(new UnsettledCash(cashholder.TotalUnsettledCash, cashholder.DateTimeAllIsSettledUtc));

                //Remove fund
                _cashknown.Remove(quantfund.FundId);
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Processes the update ticket.
        /// </summary>
        /// <param name="ticket">The ticket.</param>
        /// <param name="quantfund">Ticket associated quant fund</param>
        /// <returns></returns>
        private OrderTicket ProcessUpdateTicket(UpdateOrderTicket ticket, IQuantFund quantfund)
        {
            //Try and get current order ticket
            if (!OrderTracker.TryGetOrder(ticket.OrderId, out PendingOrder pendingorder))
            {
                ticket.SetResponse(OrderTicketResponse.Error(ticket.OrderId, OrderTicketResponseErrorCode.UnableToFindOrder));
                return(ticket);
            }

            try
            {
                //Try and process cancel ticket
                if (pendingorder.OrderState.IsDone())
                {
                    _log.Error($"Order is already of state {pendingorder.OrderState} while trying to update this order");
                    ticket.SetResponse(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.InvalidOrderStatus));
                }
                else if (quantfund != null && quantfund.IsBackfilling)
                {
                    ticket.SetResponse(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.QuantFundBackfilling));
                }
                else
                {
                    // send the request to be processed
                    ticket.SetResponse(OrderTicketResponse.Processed(ticket.OrderId), OrderTicketState.Processing);
                    _orderTicketQueue.Add(ticket);
                }
            }
            catch (Exception exc)
            {
                _log.Error(exc);
                ticket.SetResponse(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.ProcessingError, exc.Message));
            }

            //Return what we have
            return(ticket);
        }
Exemplo n.º 14
0
 /// <summary>
 /// Gets the cash positions that are part of a quant fund.
 /// </summary>
 /// <param name="quantfund">The quantfund.</param>
 /// <returns></returns>
 public Dictionary <CurrencyType, CashPosition> GetCashPositions(IQuantFund quantfund) => _cashknown[quantfund.FundId];
Exemplo n.º 15
0
        /// <summary>
        /// Settle funds to account right away
        /// </summary>
        /// <param name="account">The account.</param>
        /// <param name="quantfund">The quantfund.</param>
        /// <param name="security">The security.</param>
        /// <param name="occureddtutc">The occureddtutc.</param>
        /// <param name="amount">The amount.</param>
        /// <exception cref="NullReferenceException">Could not find quant fund for settlement</exception>
        public void SettleFunds(BrokerAccount account, Security security, DateTime occureddtutc, decimal amount, IQuantFund quantfund = null)
        {
            //check if we found agent
            if (quantfund == null)
            {
                throw new NullReferenceException("Could not find quant fund for settlement");
            }

            //Add settled funds
            account.Cash.AddCash(security.BaseCurrency, amount, quantfund);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Settle funds, delayed
        /// </summary>
        /// <param name="account">The account.</param>
        /// <param name="quantfund">The quantfund.</param>
        /// <param name="security">The security.</param>
        /// <param name="occureddtutc">The occureddtutc.</param>
        /// <param name="amount">The amount.</param>
        public void SettleFunds(BrokerAccount account, Security security, DateTime occureddtutc, decimal amount, IQuantFund quantfund = null)
        {
            //Added funds
            if (amount > 0)
            {
                //Get exchangeModel based local time
                DateTime settlementdate = security.Exchange.LocalTime;

                //Check for date based on market opened date and time
                for (int i = 0; i < DelayedDays; i++)
                {
                    settlementdate = settlementdate.AddDays(i);

                    if (!security.Exchange.IsOpenOnDate(settlementdate))
                    {
                        i--;
                    }
                }

                //Get correct date and time
                settlementdate = settlementdate.Add(TimeOfDay);

                //Convert time of day from local exchangeModel timezone to utc based time
                settlementdate = settlementdate.ConvertTo(security.Exchange.TimeZone, TimeZone.Utc);

                //Add unsettled funds (to be settled on a later time and date)
                account.Cash.AddCash(security.BaseCurrency, amount, quantfund, settlementdate);
            }
            else //Used funds, settle right away
            {
                account.Cash.AddCash(security.BaseCurrency, amount, quantfund);
            }
        }
Exemplo n.º 17
0
 /// <summary>
 /// Initialize new scheduled action instance
 /// </summary>
 /// <param name="quantfund"></param>
 /// <param name="date"></param>
 /// <param name="time"></param>
 /// <param name="action"></param>
 /// <param name="name"></param>
 public ScheduledAction(IQuantFund quantfund, DateComposite date, TimeComposite time, Action <string, DateTime> action, string name = "")
     : this(date, time, action, name) => FundId = quantfund.FundId;
Exemplo n.º 18
0
 /// <summary>
 /// Gets the currently active tickers by quant fund
 /// </summary>
 /// <param name="quantfund">The quantfund.</param>
 /// <returns></returns>
 public string[] ActiveTickers(IQuantFund quantfund) =>
 _registeredsubscriptions.ContainsKey(quantfund.FundId)
         ? _registeredsubscriptions[quantfund.FundId].Select(x => x.Ticker).Distinct().ToArray() :
 new string[0];
Exemplo n.º 19
0
        /// <summary>
        /// Adds a datasubscription which is derived from the requested data aggregator instance
        /// Force tick will force the data to contain the highest granularity (otherwise it might be based on 1-minute data)
        /// TODO: add unit test, if we request 1 minute data and than request tick data we should keep the tick data request and replace all 1 minute request with the tick data request? (so that we only keep the tick data request)
        /// TODO: we will only do ticks or tradebars! (where a trade bar is based on any data)
        /// </summary>
        /// <param name="quantfund"></param>
        /// <param name="security">The security.</param>
        /// <param name="aggregator">The aggregator.</param>
        /// <param name="forcetick">if set to <c>true</c> [forcetick].</param>
        /// <returns>Can be a different dataggregator due to change in data requested</returns>
        public DataAggregator AddSubscription(IQuantFund quantfund, Security security, DataAggregator aggregator, bool forcetick = false)
        {
            //Initial values
            TimeSpan?aggregationneeded = null;
            DataType datatypeneeded    = DataType.Tick;
            TimeSpan preaggregated     = TimeSpan.FromMinutes(1);

            if (!forcetick)
            {
                //TradeBar -> TradeBar
                if (aggregator is TimeSerieAggregator <TradeBar, TradeBar> tradetotrade && tradetotrade.IsTimeBased)
                {
                    if (tradetotrade.Period.Value.TotalSeconds % 60 == 0D)
                    {
                        aggregator        = new TradeAggregator(tradetotrade.Period.Value);
                        aggregationneeded = preaggregated;
                        datatypeneeded    = DataType.TradeBar;
                    }
                }

                //Tick -> TradeBar
                if (aggregator is TimeSerieAggregator <Tick, TradeBar> ticktobar && ticktobar.IsTimeBased)
                {
                    if (ticktobar.Period.Value.TotalSeconds % 60 == 0D)
                    {
                        aggregator        = new TickQuoteBarAggregator(ticktobar.Period.Value);
                        aggregationneeded = TimeSpan.FromMinutes(1);
                        datatypeneeded    = DataType.TradeBar;
                    }
                }
            }

            //get and add subscription
            var subscription = DataSubscriptionRequest.CreateSubscriptionRequest(security.Ticker, _datafeed.DataSource,
                                                                                 aggregationneeded, datatypeneeded);

            subscription = AddSubscription(subscription);

            //Add base currency conversion
            AddBaseCurrencyConversionFeed(security);

            //Check if we already have a similar data aggregator, reuse the existing version if possible
            if (_registeredsubscriptions.ContainsKey(quantfund.FundId))
            {
                var found    = _registeredsubscriptions[quantfund.FundId].FirstOrDefault(x => x.Request.GetSubscriptionName() == subscription.GetSubscriptionName());
                var existing = found?.Aggregators.FirstOrDefault(x => x.Name == aggregator.Name);
                if (existing != null)
                {
                    return(existing);
                }
                else if (found == null)
                {
                    _registeredsubscriptions[quantfund.FundId].Add(new DataSubscription(quantfund.FundId, subscription,
                                                                                        security, security.Exchange.TimeZone, aggregator));
                }
                else
                {
                    found.Aggregators.Add(aggregator);
                }
            }
            else
            {
                //Add new
                _registeredsubscriptions.Add(quantfund.FundId, new List <DataSubscription>());
                _registeredsubscriptions[quantfund.FundId].Add(new DataSubscription(quantfund.FundId, subscription, security, security.Exchange.TimeZone, aggregator));
            }

            //Return our current aggregator
            return(aggregator);
        }
Exemplo n.º 20
0
 /// <summary>
 /// Update cash position based on account action
 /// TODO: add sync action to scheduler for live trading (get current funds from account via broker API) => will be done via tickethandler (it will contact the api)
 /// </summary>
 /// <param name="action"></param>
 /// <param name="currency"></param>
 /// <param name="amount"></param>
 /// <param name="quantfund">In case the cash position affects a specific quant fund</param>
 public void Process(AccountActionType action, CurrencyType currency, decimal amount, IQuantFund quantfund = null)
 {
     //Check action type and process
     if (action == AccountActionType.Sync)
     {
         SyncFunds(currency, amount);
     }
     else if (action == AccountActionType.Credit)
     {
         throw new NotImplementedException();
     }
     else if (action == AccountActionType.Deposit)
     {
         throw new NotImplementedException();
     }
     else if (action == AccountActionType.Dividend)
     {
         throw new NotImplementedException();
     }
     else if (action == AccountActionType.Withdrawal)
     {
         throw new NotImplementedException();
     }
     //TODO: What to do with currently set funds and fund withdrawals
 }
Exemplo n.º 21
0
 /// <summary>
 /// Get current buying power for quant fund
 /// </summary>
 /// <param name="quantfund">Corresponding quant fund to request buying power for</param>
 /// <returns></returns>
 public decimal GetBuyingPower(IQuantFund quantfund) =>
 _cashknown[quantfund.FundId].Values.Sum(x => _conversion.Convert(x.TotalSettledCash, x.BaseCurrency, BaseCurrency)) * _brokeraccount.Leverage;
Exemplo n.º 22
0
 /// <summary>
 /// Gets the calculated funds.
 /// </summary>
 /// <param name="quantfund">The quantfund.</param>
 /// <param name="account">Current account object</param>
 /// <returns></returns>
 public CalculatedFunds GetCalculatedFunds(IQuantFund quantfund, BrokerAccount account) =>
 new CalculatedFunds(GetUnsettledCash(quantfund), GetCash(quantfund), BaseCurrency, quantfund.Positions,
                     _leverage, account.PatternDayTradingHit, account.DayTradingOrdersLeft);
Exemplo n.º 23
0
 public decimal GetRemainingMargin(IQuantFund quantfund = null)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 24
0
 /// <summary>
 /// Get total amount of unsettled cash for quant fund
 /// </summary>
 /// <param name="quantfund"></param>
 /// <returns></returns>
 public decimal GetUnsettledCash(IQuantFund quantfund) => _cashknown[quantfund.FundId].Values.Sum(x => _conversion.Convert(x.TotalUnsettledCash, x.BaseCurrency, BaseCurrency));