示例#1
0
        protected sealed override void OnTick()
        {
            ++TickNumber;
            Debugging.BreakOnPointOfInterest();

            // Emergency stop on large draw-down
            BalanceMinimum = Math.Max((double)BalanceMinimum, Account.Balance * (1.0 - Settings.MaxDrawDownFrac));
            if (Account.Equity < BalanceMinimum)
            {
                Debugging.Trace("Account equity (${0}) dropped below the balance minimum (${1}). Stopping".Fmt(Account.Equity, BalanceMinimum));
                Print("Account equity (${0}) dropped below the balance minimum (${1}). Stopping".Fmt(Account.Equity, BalanceMinimum));
                CloseAllPositions("Emergency Stop");
                Stop();
                return;
            }

            // Raise the Bot.Tick event before stepping the bot
            // Instruments are signed up to the Tick event so they will be updated first
            base.OnTick();
            Tick.Raise(this);

            try
            {
                // Update the account info
                Broker.Update();

                // Remove position sets that don't have any active positions
                var set_ids = Positions.Select(x => Guid_.Parse(x.Comment)).NotNull().ToHashSet(x => x.Value);
                foreach (var set_id in PositionSets.Keys.ToArray())
                {
                    if (set_ids.Contains(set_id))
                    {
                        continue;
                    }
                    PositionSets.Remove(set_id);
                }

                // Step active position managers
                foreach (var pm in PositionManagers)
                {
                    pm.Step();
                }

                // Entry cool down
                if (EntryCooldown != 0 && Instrument.NewCandle)
                {
                    --EntryCooldown;
                }

                // Step the bot
                Step();
            }
            catch (Exception ex)
            {
                Debugging.Trace(ex.Message);
                Debugging.Trace(ex.StackTrace);
            }
        }
示例#2
0
            public static Guid[] FromTSObject(dynamic[] tsArray)
            {
                if (tsArray is null)
                {
                    return(null);
                }
                var list = new System.Collections.Generic.List <Guid>();

                foreach (var tsItem in tsArray)
                {
                    list.Add(Guid_.FromTSObject(tsItem));
                }
                return(list.ToArray());
            }
示例#3
0
            public static dynamic GetTSObject(Guid[] dynArray)
            {
                if (dynArray is null)
                {
                    return(null);
                }
                var list = new System.Collections.Generic.List <dynamic>();

                foreach (var dynItem in dynArray)
                {
                    list.Add(Guid_.GetTSObject(dynItem));
                }
                return(list.ToArray());
            }
示例#4
0
        protected override void OnPositionOpened(Position position)
        {
            // Prevent positions being entered on the same bulge
            EntryCooldown = NonIntersectingCount;

            {            // Adjust the stop loss to allow for slip
                var mcs  = Instrument.MCS;
                var sign = position.Sign();
                var ep   = position.EntryPrice;
                var sl   = ep - sign * mcs * SLFrac;
                Broker.ModifyOrder(Instrument, position, sl: sl);
            }

            // If the main position of a position set opens, create a pending order in the opposite direction.
            // This is designed to catch the case when we choose a break-out trade but it's actually a reversal, or visa-versa.
            var id = Guid_.Parse(position.Comment);

            if (id != null && PositionSets[id.Value].Count == 1)
            {
                var mcs   = Instrument.MCS;
                var sign  = -position.Sign();
                var tt    = CAlgo.SignToTradeType(sign);
                var rel   = Math.Abs(position.EntryPrice - position.StopLoss.Value) * 0.75;
                var ep    = MA0[0] + sign * rel;
                var sl    = ep - sign * mcs * SLFrac;
                var tp    = (QuoteCurrency?)null;
                var vol   = Broker.ChooseVolume(Instrument, Math.Abs(ep - sl), risk: Risk);
                var trade = new Trade(Instrument, tt, Label, ep, sl, tp, vol, comment: Guid.NewGuid().ToString())
                {
                    Expiration = Instrument.ExpirationTime(2)
                };
                Broker.CreatePendingOrder(trade);
            }

            // Close positions if there is a breakout in the wrong direction
            PositionManagers.Add(new PositionManagerBreakOut(this, position, CloseBreakoutPeriods, only_if_in_profit: true));

            // Close positions when they fail to make new peaks
            PositionManagers.Add(new PositionManagerTopDrop(this, position, CloseTopDropCount, only_if_in_profit: true));

            // Close positions when there's a steady stream of adverse candles
            PositionManagers.Add(new PositionManagerAdverseCandles(this, position, CloseAdverseCount));
        }
示例#5
0
        private void HandlePositionOpened(PositionOpenedEventArgs args)
        {
            // Only watch positions created by this bot
            var position = args.Position;

            if (position.Label != Label)
            {
                return;
            }

            try
            {
                // Add the position to the set it belongs to, or begin a new set
                var id = Guid_.Parse(position.Comment);
                if (id != null)
                {
                    if (PositionSets.ContainsKey(id.Value))
                    {
                        PositionSets[id.Value].Add(position.Id);
                    }
                    else
                    {
                        PositionSets[id.Value] = new List <int>(new[] { position.Id });
                    }
                }

                // Notify position closed
                if (PositionOpened != null)
                {
                    PositionOpened(this, args);
                }
                OnPositionOpened(position);
            }
            catch (Exception ex)
            {
                Debugging.Trace(ex.Message);
                Debugging.Trace(ex.StackTrace);
            }
        }
示例#6
0
        private void HandlePositionClosed(PositionClosedEventArgs args)
        {
            // Only watch positions created by this strategy
            var position = args.Position;

            if (position.Label != Label)
            {
                return;
            }

            // Close all positions in the same set
            var id = Guid_.Parse(position.Comment);

            if (id != null && PositionSets.ContainsKey(id.Value))
            {
                var set = PositionSets[id.Value];
                Broker.ClosePositions(Positions.Where(x => set.Contains(x.Id)), "Closing Set");
                PositionSets.Remove(id.Value);
            }

            // Remove any position managers that are managing 'position'
            PositionManagers.RemoveIf(x => x.Position.Id == position.Id);

            try
            {
                // Notify position closed
                if (PositionClosed != null)
                {
                    PositionClosed(this, args);
                }
                OnPositionClosed(position);
            }
            catch (Exception ex)
            {
                Debugging.Trace(ex.Message);
                Debugging.Trace(ex.StackTrace);
            }
        }