Exemplo n.º 1
0
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">TradeBars IDictionary object with your stock data</param>
        public void OnData(TradeBars data)
        {
            if (!_macd.IsReady)
            {
                return;
            }
            if (!data.ContainsKey(_ibm))
            {
                return;
            }
            if (_lastAction.Date == Time.Date)
            {
                return;
            }
            _lastAction = Time;

            var holding = Portfolio[_spy];

            if (holding.Quantity <= 0 && _macd > _macd.Signal && data[_ibm].Price > _ema)
            {
                SetHoldings(_ibm, 0.25m);
            }
            else if (holding.Quantity >= 0 && _macd < _macd.Signal && data[_ibm].Price < _ema)
            {
                SetHoldings(_ibm, -0.25m);
            }
        }
        /// <summary>
        /// On receiving new tradebar data it will be passed into this function. The general pattern is:
        /// "public void OnData( CustomType name ) {...s"
        /// </summary>
        /// <param name="data">TradeBars data type synchronized and pushed into this function. The tradebars are grouped in a dictionary.</param>
        public void OnData(TradeBars data)
        {
            //int x = 0;
            //int y = 10;
            //int z = y / x;

            //if (!Portfolio.Invested)
            //{
            //    SetHoldings("SPY", 1);
            //}

            if (!Portfolio.HoldStock && data.ContainsKey("SPY"))
            {
                Order("SPY", (int)Math.Floor(Portfolio.Cash / data["SPY"].Close));
                Debug("Debug Purchased MSFT: " + Portfolio.Cash);
            }

            if (Time.TimeOfDay.TotalSeconds % 10 == 0)
            {
                int i = Transactions.GetIncrementOrderId();
                var order = new Order("BTC", 10, OrderType.Market, Time, data["BTC"].Price, "Tag: Test");
                order.Status = OrderStatus.Filled;
                Transactions.Orders.AddOrUpdate<int, Order>(i, order);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// On receiving new tradebar data it will be passed into this function. The general pattern is:
        /// "public void OnData( CustomType name ) {...s"
        /// </summary>
        /// <param name="data">TradeBars data type synchronized and pushed into this function. The tradebars are grouped in a dictionary.</param>
        public void OnData(TradeBars data)
        {
            //int x = 0;
            //int y = 10;
            //int z = y / x;

            //if (!Portfolio.Invested)
            //{
            //    SetHoldings("SPY", 1);
            //}

            if (!Portfolio.HoldStock && data.ContainsKey("SPY"))
            {
                Order("SPY", (int)Math.Floor(Portfolio.Cash / data["SPY"].Close));
                Debug("Debug Purchased MSFT: " + Portfolio.Cash);
            }

            if (Time.TimeOfDay.TotalSeconds % 10 == 0)
            {
                int i     = Transactions.GetIncrementOrderId();
                var order = new Order("BTC", 10, OrderType.Market, Time, data["BTC"].Price, "Tag: Test");
                order.Status = OrderStatus.Filled;
                Transactions.Orders.AddOrUpdate <int, Order>(i, order);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">TradeBars IDictionary object with your stock data</param>
        public void OnData(TradeBars data)
        {
            if (!macd.IsReady)
            {
                return;
            }
            if (!data.ContainsKey("IBM"))
            {
                return;
            }
            if (lastAction.Date == Time.Date)
            {
                return;
            }
            lastAction = Time;

            var holding = Portfolio["SPY"];

            if (holding.Quantity <= 0 && macd > macd.Signal && data["IBM"].Price > ema)
            {
                SetHoldings("IBM", 0.25m);
            }
            else if (holding.Quantity >= 0 && macd < macd.Signal && data["IBM"].Price < ema)
            {
                SetHoldings("IBM", -0.25m);
            }
        }
Exemplo n.º 5
0
        /*
         *	New data arrives here.
         *	The "Slice" data represents a slice of time, it has all the data you need for a moment.
         */
        public override void OnData(Slice data)
        {
            // slice has lots of useful information
            TradeBars bars      = data.Bars;
            Splits    splits    = data.Splits;
            Dividends dividends = data.Dividends;

            //Get just this bar.
            TradeBar bar;

            if (bars.ContainsKey("SPY"))
            {
                bar = bars["SPY"];
            }

            if (!Portfolio.HoldStock)
            {
                // place an order, positive is long, negative is short.
                // Order("SPY",  quantity);

                // or request a fixed fraction of a specific asset.
                // +1 = 100% long. -2 = short all capital with 2x leverage.
                SetHoldings("SPY", 1);

                // debug message to your console. Time is the algorithm time.
                // send longer messages to a file - these are capped to 10kb
                Debug("Purchased SPY on " + Time.ToShortDateString());
                //Log("This is a longer message send to log.");
            }
        }
Exemplo n.º 6
0
 /// <summary>
 /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
 /// </summary>
 public void OnData(TradeBars data)
 {
     foreach (var symbol in _symbols.Where(s => data.ContainsKey(s)))
     {
         //Create a trading asset package for each symbol
         _vwaps[symbol].Update(data[symbol]);
         //_tradingAssets[symbol].Scan(data[symbol]);
     }
 }
Exemplo n.º 7
0
 public void OnData(TradeBars data)
 {
     if (!Portfolio.HoldStock && data.ContainsKey("AAPL"))
     {
         int quantity = (int)Math.Floor(Portfolio.Cash / data["AAPL"].Close);
         Order("AAPL", quantity);
         Debug("Purchased SPY on " + Time.ToShortDateString());
         Notify.Email("*****@*****.**", "Test", "Test Body", "test attachment");
     }
 }
Exemplo n.º 8
0
 /// <summary>
 /// Raises the data event.
 /// </summary>
 /// <param name="data">Data.</param>
 public void OnData(TradeBars data)
 {
     if (!Portfolio.HoldStock && data.ContainsKey("AAPL"))
     {
         int quantity = (int)Math.Floor(Portfolio.Cash / data["AAPL"].Close);
         Order("AAPL", quantity);
         Debug("Purchased SPY on " + Time.ToShortDateString());
         Notify.Email("*****@*****.**", "Test", "Test Body", "test attachment");
     }
 }
Exemplo n.º 9
0
        private void UpdateBars(TradeBars data)
        {
            foreach (var bar in data.Values)
            {
                if (!_bars.ContainsKey(bar.Symbol))
                {
                    _bars.Add(bar.Symbol, bar);
                }

                _bars[bar.Symbol] = bar;
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">Slice object keyed by symbol containing the stock data</param>
        public void OnData(TradeBars data)
        {
            TradeBar currentBar = data [Symbol];

            if (!data.ContainsKey (Symbol))
                return;

            _tradeBars.Add (currentBar);
            if (!_tradeBars.IsReady)
                return;

            if (!ema.IsReady)
                return;
            _emaValues.Add (ema.Current.Value);
            if (_emaValues.Count > 10)
                _emaValues.RemoveAt (0);
            var slope = 0m;
            if (_emaValues.Count > 2) {

                var xVals = new double[_emaValues.Count];
                var yVals = new double[_emaValues.Count];

                // load input data for regression
                for (int i = 0; i < _emaValues.Count; i++) {
                    xVals [i] = i;
                    // we want the log of our y values
                    yVals [i] = (double)_emaValues [i];
                }

                //http://numerics.mathdotnet.com/Regression.html

                // solves y=a + b*x via linear regression
                var fit = Fit.Line (xVals, yVals);
                var intercept = fit.Item1;
                slope = (decimal)fit.Item2;
            }
            var diff = currentBar.Close / ema.Current.Value - 1.0m;
            if (diff > 0.01m && slope > 0m) {

            if (!Portfolio[Symbol].Invested) {
                    SetHoldings (Symbol, 1);
                    Debug ("Purchased Stock");
                }

            } else {
                    Liquidate (Symbol);

                }
        }
Exemplo n.º 11
0
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">TradeBars IDictionary object with your stock data</param>
        public void OnData(TradeBars data)
        {
            if (!macd.IsReady) return;
            if (!data.ContainsKey("IBM")) return;
            if (lastAction.Date == Time.Date) return;
            lastAction = Time;

            var holding = Portfolio["SPY"];
            if (holding.Quantity <= 0 && macd > macd.Signal && data["IBM"].Price > ema)
            {
                SetHoldings("IBM", 0.25m);
            }
            else if (holding.Quantity >= 0 && macd < macd.Signal && data["IBM"].Price < ema)
            {
                SetHoldings("IBM", -0.25m);
            }
        }
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">Slice object keyed by symbol containing the stock data</param>
        public void OnData(TradeBars data)
        {
            if (!_rc.IsReady || !data.ContainsKey(_spy))
            {
                return;
            }
            var value = data[_spy].Value;

            if (_holdings.Quantity <= 0 && value < _rc.LowerChannel)
            {
                SetHoldings(_spy, 1);
                Plot("Trade Plot", "Buy", value);
            }

            if (_holdings.Quantity >= 0 && value > _rc.UpperChannel)
            {
                SetHoldings(_spy, -1);
                Plot("Trade Plot", "Sell", value);
            }
        }
Exemplo n.º 13
0
        /********************************************************
        * CLASS METHODS
        *********************************************************/
        /// <summary>
        /// Launch the algorithm manager to run this strategy
        /// </summary>
        /// <param name="job">Algorithm job</param>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="feed">Datafeed object</param>
        /// <param name="transactions">Transaction manager object</param>
        /// <param name="results">Result handler object</param>
        /// <param name="setup">Setup handler object</param>
        /// <param name="realtime">Realtime processing object</param>
        /// <remarks>Modify with caution</remarks>
        public static void Run(AlgorithmNodePacket job, IAlgorithm algorithm, IDataFeed feed, ITransactionHandler transactions, IResultHandler results, ISetupHandler setup, IRealTimeHandler realtime)
        {
            //Initialize:
            var backwardsCompatibilityMode = false;
            var tradebarsType = typeof (TradeBars);
            var ticksType = typeof(Ticks);
            var startingPerformance = setup.StartingCapital;
            var backtestMode = (job.Type == PacketType.BacktestNode);
            var methodInvokers = new Dictionary<Type, MethodInvoker>();

            //Initialize Properties:
            _frontier = setup.StartingDate;
            _runtimeError = null;
            _algorithmId = job.AlgorithmId;
            _algorithmState = AlgorithmStatus.Running;
            _previousTime = setup.StartingDate.Date;

            //Create the method accessors to push generic types into algorithm: Find all OnData events:

            //Algorithm 1.0 Data Accessors.
            //If the users defined these methods, add them in manually. This allows keeping backwards compatibility to algorithm 1.0.
            var oldTradeBarsMethodInfo = (algorithm.GetType()).GetMethod("OnTradeBar",   new[] { typeof(Dictionary<string, TradeBar>) });
            var oldTicksMethodInfo = (algorithm.GetType()).GetMethod("OnTick", new[] { typeof(Dictionary<string, List<Tick>>) });

            //Algorithm 2.0 Data Generics Accessors.
            //New hidden access to tradebars with custom type.
            var newTradeBarsMethodInfo = (algorithm.GetType()).GetMethod("OnData", new[] { tradebarsType });
            var newTicksMethodInfo = (algorithm.GetType()).GetMethod("OnData", new[] { ticksType });

            if (newTradeBarsMethodInfo == null && newTicksMethodInfo == null)
            {
                backwardsCompatibilityMode = true;
                if (oldTradeBarsMethodInfo != null) methodInvokers.Add(tradebarsType, oldTradeBarsMethodInfo.DelegateForCallMethod());
                if (oldTradeBarsMethodInfo != null) methodInvokers.Add(ticksType, oldTicksMethodInfo.DelegateForCallMethod());
            }
            else
            {
                backwardsCompatibilityMode = false;
                if (newTradeBarsMethodInfo != null) methodInvokers.Add(tradebarsType, newTradeBarsMethodInfo.DelegateForCallMethod());
                if (newTicksMethodInfo != null) methodInvokers.Add(ticksType, newTicksMethodInfo.DelegateForCallMethod());
            }

            //Go through the subscription types and create invokers to trigger the event handlers for each custom type:
            foreach (var config in feed.Subscriptions)
            {
                //If type is a tradebar, combine tradebars and ticks into unified array:
                if (config.Type.Name != "TradeBar" && config.Type.Name != "Tick")
                {
                    //Get the matching method for this event handler - e.g. public void OnData(Quandl data) { .. }
                    var genericMethod = (algorithm.GetType()).GetMethod("OnData", new[] { config.Type });

                    //Is we already have this Type-handler then don't add it to invokers again.
                    if (methodInvokers.ContainsKey(config.Type)) continue;

                    //If we couldnt find the event handler, let the user know we can't fire that event.
                    if (genericMethod == null)
                    {
                        _runtimeError = new Exception("Data event handler not found, please create a function matching this template: public void OnData(" + config.Type.Name + " data) {  }");
                        _algorithmState = AlgorithmStatus.RuntimeError;
                        return;
                    }
                    methodInvokers.Add(config.Type, genericMethod.DelegateForCallMethod());
                }
            }

            //Loop over the queues: get a data collection, then pass them all into relevent methods in the algorithm.
            Log.Debug("AlgorithmManager.Run(): Algorithm initialized, launching time loop.");
            foreach (var newData in DataStream.GetData(feed, setup.StartingDate))
            {
                //Check this backtest is still running:
                if (_algorithmState != AlgorithmStatus.Running) break;

                //Go over each time stamp we've collected, pass it into the algorithm in order:
                foreach (var time in newData.Keys)
                {
                    //Set the time frontier:
                    _frontier = time;

                    //Execute with TimeLimit Monitor:
                    if (Isolator.IsCancellationRequested) return;

                    //Refresh the realtime event monitor:
                    realtime.SetTime(time);

                    //Fire EOD if the time packet we just processed is greater
                    if (backtestMode && _previousTime.Date != time.Date)
                    {
                        //Sample the portfolio value over time for chart.
                        results.SampleEquity(_previousTime, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));

                        if (startingPerformance == 0)
                        {
                            results.SamplePerformance(_previousTime.Date, 0);
                        }
                        else
                        {
                            results.SamplePerformance(_previousTime.Date, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPerformance) * 100 / startingPerformance, 10));
                        }

                        startingPerformance = algorithm.Portfolio.TotalPortfolioValue;
                    }

                    //Check if the user's signalled Quit: loop over data until day changes.
                    if (algorithm.GetQuit())
                    {
                        _algorithmState = AlgorithmStatus.Quit;
                        break;
                    }

                    //Pass in the new time first:
                    algorithm.SetDateTime(time);

                    //Trigger the data events: Invoke the types we have data for:
                    var oldBars = new Dictionary<string, TradeBar>();
                    var oldTicks = new Dictionary<string, List<Tick>>();
                    var newBars = new TradeBars(time);
                    var newTicks = new Ticks(time);

                    //Invoke all non-tradebars, non-ticks methods:
                    // --> i == Subscription Configuration Index, so we don't need to compare types.
                    foreach (var i in newData[time].Keys)
                    {
                        //Data point and config of this point:
                        var dataPoints = newData[time][i];
                        var config = feed.Subscriptions[i];

                        //Create TradeBars Unified Data --> OR --> invoke generic data event. One loop.
                        foreach (var dataPoint in dataPoints)
                        {
                            //Update the securities properties: first before calling user code to avoid issues with data
                            algorithm.Securities.Update(time, dataPoint);

                            //Update registered consolidators for this symbol index
                            for (var j = 0; j < config.Consolidators.Count; j++)
                            {
                                config.Consolidators[j].Update(dataPoint);
                            }

                            switch (config.Type.Name)
                            {
                                case "TradeBar":
                                    var bar = dataPoint as TradeBar;
                                    try
                                    {
                                        if (bar != null)
                                        {
                                            if (backwardsCompatibilityMode)
                                            {
                                                if (!oldBars.ContainsKey(bar.Symbol)) oldBars.Add(bar.Symbol, bar);
                                            }
                                            else
                                            {
                                                if (!newBars.ContainsKey(bar.Symbol)) newBars.Add(bar.Symbol, bar);
                                            }
                                        }
                                    }
                                    catch (Exception err)
                                    {
                                        Log.Error(time.ToLongTimeString() + " >> " + bar.Time.ToLongTimeString() + " >> " + bar.Symbol + " >> " + bar.Value.ToString("C"));
                                        Log.Error("AlgorithmManager.Run(): Failed to add TradeBar (" + bar.Symbol + ") Time: (" + time.ToLongTimeString() + ") Count:(" + newBars.Count + ") " + err.Message);
                                    }
                                    break;

                                case "Tick":
                                    var tick = dataPoint as Tick;
                                    if (tick != null)
                                    {
                                         if (backwardsCompatibilityMode) {
                                             if (!oldTicks.ContainsKey(tick.Symbol)) { oldTicks.Add(tick.Symbol, new List<Tick>()); }
                                             oldTicks[tick.Symbol].Add(tick);
                                         }
                                         else
                                         {
                                             if (!newTicks.ContainsKey(tick.Symbol)) { newTicks.Add(tick.Symbol, new List<Tick>()); }
                                             newTicks[tick.Symbol].Add(tick);
                                         }
                                    }
                                    break;

                                default:
                                    //Send data into the generic algorithm event handlers
                                    try
                                    {
                                        methodInvokers[config.Type](algorithm, dataPoint);
                                    }
                                    catch (Exception err)
                                    {
                                        _runtimeError = err;
                                        _algorithmState = AlgorithmStatus.RuntimeError;
                                        Log.Debug("AlgorithmManager.Run(): RuntimeError: Custom Data: " + err.Message + " STACK >>> " + err.StackTrace);
                                        return;
                                    }
                                    break;
                            }
                        }
                    }

                    //After we've fired all other events in this second, fire the pricing events:
                    if (backwardsCompatibilityMode)
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v1.0 Event Handlers...");
                        try
                        {
                            if (oldTradeBarsMethodInfo != null && oldBars.Count > 0) methodInvokers[tradebarsType](algorithm, oldBars);
                            if (oldTicksMethodInfo != null && oldTicks.Count > 0) methodInvokers[ticksType](algorithm, oldTicks);
                        }
                        catch (Exception err)
                        {
                            _runtimeError = err;
                            _algorithmState = AlgorithmStatus.RuntimeError;
                            Log.Debug("AlgorithmManager.Run(): RuntimeError: Backwards Compatibility Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }
                    else
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v2.0 Event Handlers...");
                        try
                        {
                            if (newTradeBarsMethodInfo != null && newBars.Count > 0) methodInvokers[tradebarsType](algorithm, newBars);
                            if (newTicksMethodInfo != null && newTicks.Count > 0) methodInvokers[ticksType](algorithm, newTicks);
                        }
                        catch (Exception err)
                        {
                            _runtimeError = err;
                            _algorithmState = AlgorithmStatus.RuntimeError;
                            Log.Debug("AlgorithmManager.Run(): RuntimeError: New Style Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }

                    //If its the historical/paper trading models, wait until market orders have been "filled"
                    // Manually trigger the event handler to prevent thread switch.
                    transactions.ProcessSynchronousEvents();

                    //Save the previous time for the sample calculations
                    _previousTime = time;

                } // End of Time Loop

                // Process any required events of the results handler such as sampling assets, equity, or stock prices.
                results.ProcessSynchronousEvents();
            } // End of ForEach DataStream

            //Stream over:: Send the final packet and fire final events:
            Log.Trace("AlgorithmManager.Run(): Firing On End Of Algorithm...");
            try
            {
                algorithm.OnEndOfAlgorithm();
            }
            catch (Exception err)
            {
                _algorithmState = AlgorithmStatus.RuntimeError;
                _runtimeError = new Exception("Error running OnEndOfAlgorithm(): " + err.Message, err.InnerException);
                Log.Debug("AlgorithmManager.OnEndOfAlgorithm(): " + err.Message + " STACK >>> " + err.StackTrace);
                return;
            }

            // Process any required events of the results handler such as sampling assets, equity, or stock prices.
            results.ProcessSynchronousEvents(forceProcess: true);

            //Liquidate Holdings for Calculations:
            if (_algorithmState == AlgorithmStatus.Liquidated || !Engine.LiveMode)
            {
                Log.Trace("AlgorithmManager.Run(): Liquidating algorithm holdings...");
                algorithm.Liquidate();
                results.LogMessage("Algorithm Liquidated");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Liquidated);
            }

            //Manually stopped the algorithm
            if (_algorithmState == AlgorithmStatus.Stopped)
            {
                Log.Trace("AlgorithmManager.Run(): Stopping algorithm...");
                results.LogMessage("Algorithm Stopped");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Stopped);
            }

            //Backtest deleted.
            if (_algorithmState == AlgorithmStatus.Deleted)
            {
                Log.Trace("AlgorithmManager.Run(): Deleting algorithm...");
                results.DebugMessage("Algorithm Id:(" + job.AlgorithmId + ") Deleted by request.");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Deleted);
            }

            //Algorithm finished, send regardless of commands:
            results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Completed);

            //Take final samples:
            results.SampleRange(algorithm.GetChartUpdates());
            results.SampleEquity(_frontier, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));
            results.SamplePerformance(_frontier, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPerformance) * 100 / startingPerformance, 10));
        }
Exemplo n.º 14
0
        /********************************************************
         * CLASS METHODS
         *********************************************************/
        /// <summary>
        /// Launch the algorithm manager to run this strategy
        /// </summary>
        /// <param name="job">Algorithm job</param>
        /// <param name="algorithm">Algorithm instance</param>
        /// <param name="feed">Datafeed object</param>
        /// <param name="transactions">Transaction manager object</param>
        /// <param name="results">Result handler object</param>
        /// <param name="setup">Setup handler object</param>
        /// <param name="realtime">Realtime processing object</param>
        /// <remarks>Modify with caution</remarks>
        public static void Run(AlgorithmNodePacket job, IAlgorithm algorithm, IDataFeed feed, ITransactionHandler transactions, IResultHandler results, ISetupHandler setup, IRealTimeHandler realtime)
        {
            //Initialize:
            var backwardsCompatibilityMode = false;
            var tradebarsType       = typeof(TradeBars);
            var ticksType           = typeof(Ticks);
            var startingPerformance = setup.StartingCapital;
            var backtestMode        = (job.Type == PacketType.BacktestNode);
            var methodInvokers      = new Dictionary <Type, MethodInvoker>();

            //Initialize Properties:
            _frontier       = setup.StartingDate;
            _runtimeError   = null;
            _algorithmId    = job.AlgorithmId;
            _algorithmState = AlgorithmStatus.Running;
            _previousTime   = setup.StartingDate.Date;

            //Create the method accessors to push generic types into algorithm: Find all OnData events:

            //Algorithm 1.0 Data Accessors.
            //If the users defined these methods, add them in manually. This allows keeping backwards compatibility to algorithm 1.0.
            var oldTradeBarsMethodInfo = (algorithm.GetType()).GetMethod("OnTradeBar", new[] { typeof(Dictionary <string, TradeBar>) });
            var oldTicksMethodInfo     = (algorithm.GetType()).GetMethod("OnTick", new[] { typeof(Dictionary <string, List <Tick> >) });

            //Algorithm 2.0 Data Generics Accessors.
            //New hidden access to tradebars with custom type.
            var newTradeBarsMethodInfo = (algorithm.GetType()).GetMethod("OnData", new[] { tradebarsType });
            var newTicksMethodInfo     = (algorithm.GetType()).GetMethod("OnData", new[] { ticksType });

            if (newTradeBarsMethodInfo == null && newTicksMethodInfo == null)
            {
                backwardsCompatibilityMode = true;
                if (oldTradeBarsMethodInfo != null)
                {
                    methodInvokers.Add(tradebarsType, oldTradeBarsMethodInfo.DelegateForCallMethod());
                }
                if (oldTradeBarsMethodInfo != null)
                {
                    methodInvokers.Add(ticksType, oldTicksMethodInfo.DelegateForCallMethod());
                }
            }
            else
            {
                backwardsCompatibilityMode = false;
                if (newTradeBarsMethodInfo != null)
                {
                    methodInvokers.Add(tradebarsType, newTradeBarsMethodInfo.DelegateForCallMethod());
                }
                if (newTicksMethodInfo != null)
                {
                    methodInvokers.Add(ticksType, newTicksMethodInfo.DelegateForCallMethod());
                }
            }

            //Go through the subscription types and create invokers to trigger the event handlers for each custom type:
            foreach (var config in feed.Subscriptions)
            {
                //If type is a tradebar, combine tradebars and ticks into unified array:
                if (config.Type.Name != "TradeBar" && config.Type.Name != "Tick")
                {
                    //Get the matching method for this event handler - e.g. public void OnData(Quandl data) { .. }
                    var genericMethod = (algorithm.GetType()).GetMethod("OnData", new[] { config.Type });

                    //Is we already have this Type-handler then don't add it to invokers again.
                    if (methodInvokers.ContainsKey(config.Type))
                    {
                        continue;
                    }

                    //If we couldnt find the event handler, let the user know we can't fire that event.
                    if (genericMethod == null)
                    {
                        _runtimeError   = new Exception("Data event handler not found, please create a function matching this template: public void OnData(" + config.Type.Name + " data) {  }");
                        _algorithmState = AlgorithmStatus.RuntimeError;
                        return;
                    }
                    methodInvokers.Add(config.Type, genericMethod.DelegateForCallMethod());
                }
            }

            //Loop over the queues: get a data collection, then pass them all into relevent methods in the algorithm.
            Log.Debug("AlgorithmManager.Run(): Algorithm initialized, launching time loop.");
            foreach (var newData in DataStream.GetData(feed, setup.StartingDate))
            {
                //Check this backtest is still running:
                if (_algorithmState != AlgorithmStatus.Running)
                {
                    break;
                }

                //Go over each time stamp we've collected, pass it into the algorithm in order:
                foreach (var time in newData.Keys)
                {
                    //Set the time frontier:
                    _frontier = time;

                    //Execute with TimeLimit Monitor:
                    if (Isolator.IsCancellationRequested)
                    {
                        return;
                    }

                    //Refresh the realtime event monitor:
                    realtime.SetTime(time);

                    //Fire EOD if the time packet we just processed is greater
                    if (backtestMode && _previousTime.Date != time.Date)
                    {
                        //Sample the portfolio value over time for chart.
                        results.SampleEquity(_previousTime, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));

                        if (startingPerformance == 0)
                        {
                            results.SamplePerformance(_previousTime.Date, 0);
                        }
                        else
                        {
                            results.SamplePerformance(_previousTime.Date, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPerformance) * 100 / startingPerformance, 10));
                        }

                        startingPerformance = algorithm.Portfolio.TotalPortfolioValue;
                    }

                    //Check if the user's signalled Quit: loop over data until day changes.
                    if (algorithm.GetQuit())
                    {
                        _algorithmState = AlgorithmStatus.Quit;
                        break;
                    }

                    //Pass in the new time first:
                    algorithm.SetDateTime(time);

                    //Trigger the data events: Invoke the types we have data for:
                    var oldBars  = new Dictionary <string, TradeBar>();
                    var oldTicks = new Dictionary <string, List <Tick> >();
                    var newBars  = new TradeBars(time);
                    var newTicks = new Ticks(time);

                    //Invoke all non-tradebars, non-ticks methods:
                    // --> i == Subscription Configuration Index, so we don't need to compare types.
                    foreach (var i in newData[time].Keys)
                    {
                        //Data point and config of this point:
                        var dataPoints = newData[time][i];
                        var config     = feed.Subscriptions[i];

                        //Create TradeBars Unified Data --> OR --> invoke generic data event. One loop.
                        foreach (var dataPoint in dataPoints)
                        {
                            //Update the securities properties: first before calling user code to avoid issues with data
                            algorithm.Securities.Update(time, dataPoint);

                            //Update registered consolidators for this symbol index
                            for (var j = 0; j < config.Consolidators.Count; j++)
                            {
                                config.Consolidators[j].Update(dataPoint);
                            }

                            switch (config.Type.Name)
                            {
                            case "TradeBar":
                                var bar = dataPoint as TradeBar;
                                try
                                {
                                    if (bar != null)
                                    {
                                        if (backwardsCompatibilityMode)
                                        {
                                            if (!oldBars.ContainsKey(bar.Symbol))
                                            {
                                                oldBars.Add(bar.Symbol, bar);
                                            }
                                        }
                                        else
                                        {
                                            if (!newBars.ContainsKey(bar.Symbol))
                                            {
                                                newBars.Add(bar.Symbol, bar);
                                            }
                                        }
                                    }
                                }
                                catch (Exception err)
                                {
                                    Log.Error(time.ToLongTimeString() + " >> " + bar.Time.ToLongTimeString() + " >> " + bar.Symbol + " >> " + bar.Value.ToString("C"));
                                    Log.Error("AlgorithmManager.Run(): Failed to add TradeBar (" + bar.Symbol + ") Time: (" + time.ToLongTimeString() + ") Count:(" + newBars.Count + ") " + err.Message);
                                }
                                break;

                            case "Tick":
                                var tick = dataPoint as Tick;
                                if (tick != null)
                                {
                                    if (backwardsCompatibilityMode)
                                    {
                                        if (!oldTicks.ContainsKey(tick.Symbol))
                                        {
                                            oldTicks.Add(tick.Symbol, new List <Tick>());
                                        }
                                        oldTicks[tick.Symbol].Add(tick);
                                    }
                                    else
                                    {
                                        if (!newTicks.ContainsKey(tick.Symbol))
                                        {
                                            newTicks.Add(tick.Symbol, new List <Tick>());
                                        }
                                        newTicks[tick.Symbol].Add(tick);
                                    }
                                }
                                break;

                            default:
                                //Send data into the generic algorithm event handlers
                                try
                                {
                                    methodInvokers[config.Type](algorithm, dataPoint);
                                }
                                catch (Exception err)
                                {
                                    _runtimeError   = err;
                                    _algorithmState = AlgorithmStatus.RuntimeError;
                                    Log.Error("AlgorithmManager.Run(): RuntimeError: Custom Data: " + err.Message + " STACK >>> " + err.StackTrace);
                                    return;
                                }
                                break;
                            }
                        }
                    }

                    //After we've fired all other events in this second, fire the pricing events:
                    if (backwardsCompatibilityMode)
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v1.0 Event Handlers...");
                        try
                        {
                            if (oldTradeBarsMethodInfo != null && oldBars.Count > 0)
                            {
                                methodInvokers[tradebarsType](algorithm, oldBars);
                            }
                            if (oldTicksMethodInfo != null && oldTicks.Count > 0)
                            {
                                methodInvokers[ticksType](algorithm, oldTicks);
                            }
                        }
                        catch (Exception err)
                        {
                            _runtimeError   = err;
                            _algorithmState = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: Backwards Compatibility Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }
                    else
                    {
                        //Log.Debug("AlgorithmManager.Run(): Invoking v2.0 Event Handlers...");
                        try
                        {
                            if (newTradeBarsMethodInfo != null && newBars.Count > 0)
                            {
                                methodInvokers[tradebarsType](algorithm, newBars);
                            }
                            if (newTicksMethodInfo != null && newTicks.Count > 0)
                            {
                                methodInvokers[ticksType](algorithm, newTicks);
                            }
                        }
                        catch (Exception err)
                        {
                            _runtimeError   = err;
                            _algorithmState = AlgorithmStatus.RuntimeError;
                            Log.Error("AlgorithmManager.Run(): RuntimeError: New Style Mode: " + err.Message + " STACK >>> " + err.StackTrace);
                            return;
                        }
                    }

                    //If its the historical/paper trading models, wait until market orders have been "filled"
                    // Manually trigger the event handler to prevent thread switch.
                    transactions.ProcessSynchronousEvents();

                    //Save the previous time for the sample calculations
                    _previousTime = time;
                } // End of Time Loop

                // Process any required events of the results handler such as sampling assets, equity, or stock prices.
                results.ProcessSynchronousEvents();
            } // End of ForEach DataStream

            //Stream over:: Send the final packet and fire final events:
            Log.Trace("AlgorithmManager.Run(): Firing On End Of Algorithm...");
            try
            {
                algorithm.OnEndOfAlgorithm();
            }
            catch (Exception err)
            {
                _runtimeError   = new Exception("Error running OnEndOfAlgorithm(): " + err.Message, err.InnerException);
                _algorithmState = AlgorithmStatus.RuntimeError;
                return;
            }

            // Process any required events of the results handler such as sampling assets, equity, or stock prices.
            results.ProcessSynchronousEvents();

            //Liquidate Holdings for Calculations:
            if (_algorithmState == AlgorithmStatus.Liquidated || !Engine.LiveMode)
            {
                Log.Trace("AlgorithmManager.Run(): Liquidating algorithm holdings...");
                algorithm.Liquidate();
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Liquidated);
            }

            //Manually stopped the algorithm
            if (_algorithmState == AlgorithmStatus.Stopped)
            {
                Log.Trace("AlgorithmManager.Run(): Stopping algorithm...");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Stopped);
            }

            //Backtest deleted.
            if (_algorithmState == AlgorithmStatus.Deleted)
            {
                Log.Trace("AlgorithmManager.Run(): Deleting algorithm...");
                results.DebugMessage("Algorithm Id:(" + job.AlgorithmId + ") Deleted by request.");
                results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Deleted);
            }

            //Algorithm finished, send regardless of commands:
            results.SendStatusUpdate(job.AlgorithmId, AlgorithmStatus.Completed);

            //Take final samples:
            results.SampleRange(algorithm.GetChartUpdates());
            results.SampleEquity(_frontier, Math.Round(algorithm.Portfolio.TotalPortfolioValue, 4));
            results.SamplePerformance(_frontier, Math.Round((algorithm.Portfolio.TotalPortfolioValue - startingPerformance) * 100 / startingPerformance, 10));
        } // End of Run();
Exemplo n.º 15
0
        public void OnData(TradeBars data)
        {
            OrderSignal actualOrder = OrderSignal.doNothing;

            int i = 0;  // just for logging

            foreach (string symbol in Symbols)
            {
                if (!data.ContainsKey(symbol) || !Strategy[symbol].IsReady) continue;

                bool breakCondition = (Time.Date == new DateTime(2015, 08, 07) || Time.Date == new DateTime(2015, 08, 10))
                                      && isNormalOperativeTime 
                                      && symbol == "MSFT";

                if (isNormalOperativeTime)
                {
                    actualOrder = Strategy[symbol].ActualSignal;
                }
                else if (noOvernight && isMarketAboutToClose)
                {
                    actualOrder = CloseAllPositions(symbol);
                }

                ExecuteStrategy(symbol, actualOrder);
                

                #region Logging stuff - Filling the data StockLogging

                //Time,Close,Decycle,InvFisher,LightSmoothPrice,Momersion,PSAR,Position
                string newLine = string.Format("{0},{1},{2},{3},{4}",
                                               Time.ToString("u"),
                                               data[symbol].Close,
                                               Strategy[symbol].SmoothedSeries.Current.Value,
                                               PSARDict[symbol].Current.Value,
                                               Portfolio[symbol].Invested ? Portfolio[symbol].IsLong ? 1 : -1 : 0
                                               );
                stockLogging[i].AppendLine(newLine);
                i++;

                #endregion Logging stuff - Filling the data StockLogging
            }
            barCounter++; // just for logging
        }
Exemplo n.º 16
0
        /// <summary>
        /// OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
        /// </summary>
        /// <param name="data">Slice object keyed by symbol containing the stock data</param>
        public void OnData(TradeBars data)
        {
            TradeBar currentBar = data [Symbol];


            if (!data.ContainsKey(Symbol))
            {
                return;
            }

            _tradeBars.Add(currentBar);
            if (!_tradeBars.IsReady)
            {
                return;
            }

            if (!ema.IsReady)
            {
                return;
            }
            _emaValues.Add(ema.Current.Value);
            if (_emaValues.Count > 10)
            {
                _emaValues.RemoveAt(0);
            }
            var slope = 0m;

            if (_emaValues.Count > 2)
            {
                var xVals = new double[_emaValues.Count];
                var yVals = new double[_emaValues.Count];

                // load input data for regression
                for (int i = 0; i < _emaValues.Count; i++)
                {
                    xVals [i] = i;
                    // we want the log of our y values
                    yVals [i] = (double)_emaValues [i];
                }

                //http://numerics.mathdotnet.com/Regression.html

                // solves y=a + b*x via linear regression
                var fit       = Fit.Line(xVals, yVals);
                var intercept = fit.Item1;
                slope = (decimal)fit.Item2;
            }
            var diff = currentBar.Close / ema.Current.Value - 1.0m;

            if (diff > 0.01m && slope > 0m)
            {
                if (!Portfolio[Symbol].Invested)
                {
                    SetHoldings(Symbol, 1);
                    Debug("Purchased Stock");
                }
            }
            else
            {
                Liquidate(Symbol);
            }
        }
Exemplo n.º 17
0
        public void OnData(TradeBars data)
        {
            foreach (var symbol in _symbols.Where(s => data.ContainsKey(s)))
            {
                _selectionDatas[symbol].Update(data[symbol], Portfolio[symbol].Quantity);
                Securities[symbol].IsTradable = true;
            }

            /*foreach (var symbol in _hedgeSymbols.Where(s => data.ContainsKey(s) && !Portfolio[s].Invested))
             * {
             *  Log("BUY >> " + symbol);
             *  SetHoldings(symbol, FractionOfPortfolio);
             * }*/

            if (IsWarmingUp)
            {
                return;
            }

            foreach (var symbol in _symbols.Where(s => Portfolio[s].Invested))
            {
                var bullishToBearish = Portfolio[symbol].IsLong &&
                                       _selectionDatas[symbol].TrendDirection == TrendSelectionData.Direction.Bearish;
                var bearishToBullish = Portfolio[symbol].IsShort &&
                                       _selectionDatas[symbol].TrendDirection == TrendSelectionData.Direction.Bullish;
                var takeProfit = Portfolio[symbol].UnrealizedProfitPercent >= 0.3m;
                var stopLoss   = Portfolio[symbol].UnrealizedProfitPercent < -0.1m;
                if (bullishToBearish || bearishToBullish || takeProfit || stopLoss)
                {
                    Log("Flat >> " + Securities[symbol].Price + " Symbol " + symbol + " Profit: " + Portfolio[symbol].UnrealizedProfitPercent);
                    //Liquidate(symbol);
                    LimitOrder(symbol, -Portfolio[symbol].Quantity, data[symbol].Price);
                    Securities[symbol].IsTradable = false;
                }
            }

            var trending = _selectionDatas
                           .Where(kvp => kvp.Value.IsReady && Securities[kvp.Key].IsTradable)
                           .Select(kvp => kvp)
                           .ToList();

            trending.Sort((a, b) => a.Value.CompareTo(b.Value));

            var topTrending = trending.Take(NumberOfSymbols - Portfolio.Count);

            foreach (var security in topTrending)
            {
                if (security.Value.TrendDirection == TrendSelectionData.Direction.Bullish)
                {
                    Log("Buy >> " + Securities[security.Key].Price + " Symbol " + security + " Profit: " + Portfolio[security.Key].UnrealizedProfitPercent);
                    //SetHoldings(security.Key, FractionOfPortfolio);
                    LimitOrder(security.Key, (int)(Portfolio.Cash / data[security.Key].Price), data[security.Key].Price);
                }
                else if (security.Value.TrendDirection == TrendSelectionData.Direction.Bearish)
                {
                    Log("Sell >> " + Securities[security.Key].Price + " Symbol " + security + " Profit: " + Portfolio[security.Key].UnrealizedProfitPercent);
                    //SetHoldings(security.Key, -FractionOfPortfolio);
                    LimitOrder(security.Key, -(int)(Portfolio.Cash / data[security.Key].Price), data[security.Key].Price);
                }
            }

            Plot("ICH", "Price", data[_bench].Price);
            Plot("ICH", "SenkouA", _selectionDatas[_bench]._ich.SenkouA);
            Plot("ICH", "SenkouB", _selectionDatas[_bench]._ich.SenkouB);

            Plot("ICH", "ADX", _selectionDatas[_bench]._adx);
            Plot("ICH", "ADX.NegativeDirectionalIndex", _selectionDatas[_bench]._adx.NegativeDirectionalIndex);
            Plot("ICH", "ADX.PositiveDirectionalIndex", _selectionDatas[_bench]._adx.PositiveDirectionalIndex);
        }