Exemple #1
0
        /// <summary>Called when new data is received</summary>
        public override void Step()
        {
            base.Step();
            if (!Instrument.NewCandle)
            {
                return;
            }

            var position = Positions.FirstOrDefault();

            if (position == null)
            {
                var snr = new SnR(Instrument, tf: TimeFrame.Hour8);
                var mcs = Instrument.MCS;

                // Look for price being near an SnR level
                var price = Instrument.LatestPrice;
                var near  = snr.Nearest(price.Mid, 0);
                if (near == null || Math.Abs(near.Price - price.Mid) > 0.5 * mcs)
                {
                    return;
                }

                // Get the preceding trend
                var trend = Instrument.MeasureTrendFromCandles(-5, 1);
            }
        }
        /// <summary></summary>
        protected override void StepCore()
        {
            // If the SL is on the winning side, let the trade run its course
            var sl_rel = Position.StopLossRel();

            if (sl_rel < 0)
            {
                return;
            }

            var mcs             = Instrument.MCS;
            var sign            = Position.Sign();
            var price           = Instrument.LatestPrice;
            var trend_sign_slow = Strategy.TrendSignSlow;
            var trend_sign_fast = Strategy.TrendSignFast;

            // If the position opposes the slow trend, try to close it at break even
            if (sign == -trend_sign_slow && sign == -trend_sign_fast)
            {
                var cp = price.Price(-sign);

                // Choose a SL based on SnR levels
                var snr  = new SnR(Instrument); Debugging.Dump(snr);
                var near = snr.Nearest(cp, -sign, min_dist: mcs * 0.5);
                var sl   = near != null ? near.Price : cp - sign * mcs;
                if (Math.Abs(sl - Position.EntryPrice) < sl_rel)
                {
                    Broker.ModifyOrder(Instrument, Position, sl: sl);
                    Debugging.Trace("  +Position opposes the trend (trend={0}), closing at break even".Fmt(trend_sign_slow));
                    return;
                }
            }

            // If the trade is better than RtR=1:1, and the close probability is high close the trade
            // For closing positions, use Ask when the price is high, Bit when the price is low
            var prob_sign = Strategy.ProbSign;
            var prob      = Strategy.Prob(prob_sign);

            if (sign == prob_sign && Math.Abs(prob) > StrategyPriceDistribution.ClosePositionProb)
            {
                // If the price gradient is in the direction of the trade, don't close it
                var d = Instrument.HighRes.FirstDerivative(-1);
                if (Math.Sign(d) == sign)
                {
                    return;
                }

                var min_profit = Instrument.Symbol.QuoteToAcct(sl_rel * Position.Volume);
                if (Position.NetProfit > min_profit)
                {
                    Debugging.Trace("  +Close Prob: {0}".Fmt(prob));
                    Broker.ClosePosition(Position);
                }
            }
        }
Exemple #3
0
        /// <summary>Called when new data is received</summary>
        public override void Step()
        {
            base.Step();
            using (Broker.SuspendRiskCheck(ignore_risk: true))
            {
                const double TakeProfitFrac = 1.020;
                const double ReverseFrac    = 0.998;
                Dump();

                // The unit of volume to trade
                var mcs = Instrument.MCS;
                var ep  = Instrument.LatestPrice.Mid;
                var vol = Broker.ChooseVolume(Instrument, 5.0 * mcs);

                // Open a trade in the direction of the trend
                if (ProfitSign == 0)
                {
                    Dump();
                    Debugging.Trace("Idx={0},Tick={1} - Setting profit sign ({2}) - Equity = ${3}".Fmt(Instrument.Count, Bot.TickNumber, TrendSign, Equity));

                    var tt    = CAlgo.SignToTradeType(TrendSign);
                    var trade = new Trade(Instrument, tt, Label, ep, null, null, vol);
                    Broker.CreateOrder(trade);
                    LastEquity = Equity;
                }

                // While the profit direction is the same as the trend direction
                // look for good spots to add hedged pending orders
                if (ProfitSign == TrendSign)
                {
                    // If the current price is at a SnR level, add pending orders on either side.
                    // Hopefully price will reverse at the SnR level and only trigger one of the pending orders.
                    // If price then reverses we can sell an existing profitable trade and be left with the
                    // profit direction going in the right direction
                    var snr       = new SnR(Instrument, ep);
                    var lvl_above = snr.Nearest(ep, +1, min_dist: 0.5 * mcs, min_strength: 0.7);
                    var lvl_below = snr.Nearest(ep, -1, min_dist: 0.5 * mcs, min_strength: 0.7);

                    // Choose price levels for the pending orders
                    var above = lvl_above != null ? lvl_above.Price + 0.5 * mcs : ep + mcs;
                    var below = lvl_below != null ? lvl_below.Price - 0.5 * mcs : ep - mcs;

                    // Only recreate if necessary
                    if (!PendingOrders.Any(x => x.TradeType == TradeType.Buy && Maths.FEql(x.TargetPrice, above, 5 * Instrument.PipSize)) ||
                        !PendingOrders.Any(x => x.TradeType == TradeType.Sell && Maths.FEql(x.TargetPrice, below, 5 * Instrument.PipSize)))
                    {
                        Dump();
                        Debugging.Dump(snr);
                        Debugging.Trace("Idx={0},Tick={1} - Adjusting pending orders - Equity = ${2}".Fmt(Instrument.Count, Bot.TickNumber, Equity));

                        // Cancel any other pending orders further away than these too
                        Broker.CancelAllPendingOrders(Label);

                        var buy = new Trade(Instrument, TradeType.Buy, Label, above, null, null, vol);
                        var sel = new Trade(Instrument, TradeType.Sell, Label, below, null, null, vol);
                        Broker.CreatePendingOrder(buy);
                        Broker.CreatePendingOrder(sel);
                    }
                }

                // If the profit is against the Trend, do nothing until losing a fraction of last equity
                if (ProfitSign != TrendSign && Equity < ReverseFrac * LastEquity)
                {
                    Dump();
                    Debugging.Trace("Idx={0},Tick={1} - Changing profit sign to ({2}) - Equity = ${3}".Fmt(Instrument.Count, Bot.TickNumber, TrendSign, Equity));
                    var sign = -ProfitSign;

                    // Try to reverse the sign by closing profitable positions
                    foreach (var pos in Positions.Where(x => x.Sign() != sign && x.NetProfit > 0).OrderBy(x => - x.NetProfit).ToArray())
                    {
                        Broker.ClosePosition(pos);

                        // Break out when the profit direction has been reversed
                        if (ProfitSign == sign)
                        {
                            break;
                        }
                    }

                    // Couldn't reverse the sign by closing positions, open a new one
                    if (ProfitSign != sign)
                    {
                        var tt          = CAlgo.SignToTradeType(sign);
                        var reverse_vol = Math.Abs(NetVolume) + vol;
                        var trade       = new Trade(Instrument, tt, Label, ep, null, null, reverse_vol);
                        Broker.CreateOrder(trade);
                    }
                    LastEquity = Equity;
                }

                // If equity is greater than a threshold, take profits
                if (Equity > TakeProfitFrac * LastEquity)
                {
                    Dump();
                    Debugging.Trace("Idx={0},Tick={1} - Profit taking - Equity = ${2}".Fmt(Instrument.Count, Bot.TickNumber, Equity));

                    var sign = ProfitSign;
                    foreach (var pos in Positions.Where(x => x.Sign() == sign && x.NetProfit > 0).OrderBy(x => - x.NetProfit).ToArray())
                    {
                        if (pos.Volume >= Math.Abs(NetVolume))
                        {
                            continue;
                        }
                        Broker.ClosePosition(pos);
                    }
                    LastEquity = Equity;
                }
            }
        }