Пример #1
0
 /// <summary>Watch for position closed</summary>
 protected override void OnPositionClosed(Position position)
 {
     if (PosMgr != null && position == PosMgr.Position)
     {
         PosMgr = null;
     }
 }
Пример #2
0
        /// <summary>Called when new data is received</summary>
        public override void Step()
        {
            // Only on new candles
            Position = FindLivePosition(Position);
            if (!Instrument.NewCandle)
            {
                return;
            }

            if (Debugger.IsAttached)
            {
                Debugging.Dump(Instrument, high_res: 20.0, emas: new[] { 100 });
                if (Instrument.Count == 230)
                {
                    Debug.WriteLine("Break");
                }
            }

            var sym = Instrument.Symbol;
            var mcs = Instrument.MedianCandleSize(-10, 0);
            var C0  = Instrument[0];
            var C1  = Instrument[-1];
            var C2  = Instrument[-2];

            // One at a time
            if (Position == null)
            {
                TradeType tt;
                string    msg;

                // Look for a reversal
                int           reversal_direction;
                QuoteCurrency target_entry;
                if (!Instrument.IsCandlePattern(0, out reversal_direction, out target_entry))
                {
                    return;
                }

                var preceeding_trend = Instrument.MeasureTrend(-10, 0);

                var tt_confirmation = C1.Bullish ? TradeType.Buy : TradeType.Sell;

                const double EmaSlopeToMCS = 20;
                var          ema           = Bot.Indicators.ExponentialMovingAverage(Bot.MarketSeries.Close, 100);
                var          ema_slope     = ema.Result.FirstDerivative(ema.Result.Count - 1) * EmaSlopeToMCS / mcs;

                // If the EMA slope is flat, look for ranging
                if (Math.Abs(ema_slope) < 1.0)
                {
                    // Side of the EMA. Must be significantly to one side of the EMA
                    var dist = C1.Close - ema.Result.LastValue;
                    if (Math.Abs(dist) < mcs)
                    {
                        return;
                    }

                    tt  = C1.Close < ema.Result.LastValue ? TradeType.Buy : TradeType.Sell;
                    msg = "{0} - ranging EMA. Slope = {1}, Distance = {2}".Fmt(tt, ema_slope, dist);
                }
                // Otherwise look for indecision near the EMA
                else
                {
                    var dist = C1.Close - ema.Result.LastValue;
                    if (Maths.Abs(dist) > mcs)
                    {
                        return;
                    }

                    tt  = ema_slope > 0.0 ? TradeType.Buy : TradeType.Sell;
                    msg = "{0} - trending EMA. Slope = {1}, Dist = {2}".Fmt(tt, ema_slope, dist);
                }

                // Check the candle confirms the direction
                if (tt != tt_confirmation)
                {
                    return;
                }

                var sign  = tt.Sign();
                var rtr   = new RangeF(1.0, 2.0);
                var trade = new Trade(Bot, Instrument, tt, Label, rtr_range: rtr);
                Bot.Print(msg);
                Position        = Bot.Broker.CreateOrder(trade);
                PositionManager = new PositionManager(Instrument, Position);
            }
            else
            {
                PositionManager.Step();
            }
        }
Пример #3
0
        // Trade management
        // - Set SL past recent peaks / 00 levels
        // - Close trade if signals change

        /// <summary>Watch for pending order filled</summary>
        protected override void OnPositionOpened(Position position)
        {
            PosMgr = new PositionManagerNervious(this, position);
        }
Пример #4
0
        /// <summary>Called when new data is received</summary>
        public override void Step()
        {
            base.Step();

            // Find the position associated with this strategy
            Position = FindLivePosition(Position);

            switch (State)
            {
            case EState.FindEntryTrigger:
                #region
            {
                // In this state we're waiting for an entry trigger.
                Debug.Assert(Position == null);

                // Do nothing unless the conditions are right
                if (SuitabilityScore < 0.5)
                {
                    return;
                }

                if (Instrument.NewCandle)
                {
                    Dump();
                }

                // Always trade with the trend
                var sign = Math.Sign(Trend);
                var tt   = sign > 0 ? TradeType.Buy : TradeType.Sell;

                // Look for a candle pattern that indicates entry
                int           forecast_direction;
                QuoteCurrency target_entry;
                if (!Instrument.IsCandlePattern(0, out forecast_direction, out target_entry) ||
                    forecast_direction != sign)
                {
                    return;
                }

                // Switch to the 'EnterOnPullBack' state
                State       = EState.EnterOnPullBack;
                TargetEntry = new TargetEntryData(target_entry, tt);
                Dump();
                break;
            }

                #endregion
            case EState.EnterOnPullBack:
                #region
            {
                if (Instrument.NewCandle)
                {
                    Dump();
                }

                // In this state we're waiting for the price to pull back
                // to the target entry. Check this on every tick.
                var tt = TargetEntry.TT;
                var cp = Instrument.CurrentPrice(tt.Sign());
                if (Misc.Sign(cp - TargetEntry.Price) != tt.Sign())
                {
                    var trade = new Trade(Bot, Instrument, tt, Label);
                    Position = Bot.Broker.CreateOrder(trade);
                    Dump();
                }
                break;
            }

                #endregion
            case EState.ManagePosition:
                #region
            {
                if (Instrument.NewCandle)
                {
                    Dump();
                }

                // Manage a trade position
                PositionManager.Step();
                break;
            }
                #endregion
            }
        }