Beispiel #1
0
        ///// <summary>Called when new data is received</summary>
        //public override void Step()
        //{
        //	var current_price = Instrument.CurrentPrice(0);
        //	var sym = Instrument.Symbol;

        //	// Find the stats for the recent price history
        //	PriceStats.Add((double)current_price);

        //	// Synchronise the Positions with our list
        //	SynchroniseLivePositions();

        //	// Measure the current net position
        //	var net = NetPosition;

        //	// If the sum of all trades is greater than the threshold, cash in
        //	// If the sum of all trades exceeds 90% of the balance to risk, bail out
        //	var profit_threshold = Misc.Max(1.0, Broker.Balance * TakeProfitPC);
        //	if (net > profit_threshold)
        //	{
        //		CloseOut();
        //		return; // Return so that closed positions get output while debugging
        //	}
        //	if (net < -BalanceRisked)
        //	{
        //		CloseOut();
        //		return; // Return so that closed positions get output while debugging
        //	}

        //	// Attempt to compress the positions
        //	for (;Positions.Count > 2;)
        //	{
        //		var pos0 = Positions.Back(0);
        //		var pos1 = Positions.Back(1);
        //		if (pos0.NetProfit + pos1.NetProfit > 1.0)
        //		{
        //			Broker.ClosePosition(pos0);
        //			Broker.ClosePosition(pos1);
        //			continue;
        //		}
        //		break;
        //	}

        //	// If we have no position, make a trade
        //	if (Positions.Count == 0)
        //	{
        //		// Get the current price direction
        //		var q = Quadratic.FromPoints(
        //			new v2(-2f, (float)Instrument[-2].Median),
        //			new v2(-1f, (float)Instrument[-1].Median),
        //			new v2(-0f, (float)Instrument[-0].Median));
        //		var next_price =(QuoteCurrency)q.F(1.0);

        //		var tt = next_price > current_price ? TradeType.Buy : TradeType.Sell;
        //		var sign = tt.Sign();

        //		// Create the initial trade
        //		var volume = sym.VolumeMin;
        //		var risk = Broker.MaxSL(Instrument, volume);
        //		var ep = Instrument.CurrentPrice(sign);
        //		var tp = ep + sign * risk;
        //		var sl = ep - sign * risk;
        //		var trade = new Trade(Instrument, tt, Label, ep, sl, tp, volume);

        //		// Record how much we're risking on this set of trades
        //		BalanceRisked = sym.QuoteToAcct(risk * volume);

        //		// Open the position
        //		var pos = Broker.CreateOrder(trade);
        //		if (pos != null)
        //			Positions.Add(pos);
        //	}
        //	else
        //	{
        //		// Get the loss threshold given the current number of trades
        //		var loss_per_level = BalanceRisked / ReversesCount;
        //		var loss_threshold = Positions.Count * loss_per_level;

        //		// If the net profit has dropped below the threshold, open a reverse trade
        //		if (net < -loss_threshold)
        //		{
        //			// The reverse trade is created such that the total risk remains the same.
        //			var prev = Positions.Back();
        //			var volume = sym.NormalizeVolume(prev.Volume * (Positions.Count + 1) / Positions.Count);
        //			var tt = prev.TradeType.Opposite();
        //			var ep = Instrument.CurrentPrice(tt.Sign());
        //			var tp = prev.StopLossAbs();
        //			var sl = prev.TakeProfitAbs();
        //			var trade = new Trade(Instrument, tt, Label, ep, sl, tp, volume);

        //			// Open the reverse position
        //			var pos = Broker.CreateOrder(trade);
        //			if (pos != null)
        //				Positions.Add(pos);
        //		}
        //	}

        //	int break_point;
        //	if (Instrument.NewCandle)
        //		break_point = 1;
        //}

        ///// <summary>Update the collection 'Positions' with any live positions created by this strategy</summary>
        //private void SynchroniseLivePositions()
        //{
        //	var live_positions = Bot.Positions.ToHashSet(x => x.Id);
        //	Positions.RemoveIf(x => !live_positions.Contains(x.Id));
        //}

        /// <summary>Returns a trade when a likely good trade is identified. Or null</summary>
        private Trade FindEntry()
        {
            // Get the current price direction
            var q = Quadratic.FromPoints(
                new v2(-2f, (float)Instrument[-2].Close),
                new v2(-1f, (float)Instrument[-1].Close),
                new v2(-0f, (float)Instrument[-0].Close));

            // Choose the trade type
            var curr_price = (double)Instrument.CurrentPrice(0);
            var next_price = q.F(1.0);
            var tt         = next_price > curr_price ? TradeType.Buy : TradeType.Sell;
            var sign       = tt.Sign();

            {                                                 // Look for some confirming signals
                // Does it match the long period EMA?
                const double ema100_threshold_gradient = 0.1; // pips per index
                var          ema100  = Bot.Indicators.ExponentialMovingAverage(Instrument.Data.Close, 100);
                var          grad100 = ema100.Result.FirstDerivative() / Instrument.MCS;
                if (Math.Abs(grad100) < ema100_threshold_gradient || Math.Sign(grad100) != sign)
                {
                    return(null);
                }

                // Does it match the short period EMA?
                const double ema14_threshold_gradient = 0.1f;                 // pips per index
                var          ema14  = Bot.Indicators.ExponentialMovingAverage(Instrument.Data.Close, 14);
                var          grad14 = ema14.Result.FirstDerivative() / Instrument.MCS;
                if (Math.Abs(grad14) < ema14_threshold_gradient || Math.Sign(grad14) != sign)
                {
                    return(null);
                }

                // Is the price within the MCS of the long period EMA?
                if (Math.Abs(curr_price - ema100.Result.LastValue) > Instrument.MCS)
                {
                    return(null);
                }

                // Is the instrument over-bought or over-sold
                var rsi = Bot.Indicators.RelativeStrengthIndex(Instrument.Data.Close, 14);
                if (tt == TradeType.Buy && rsi.Result.LastValue > 70.0)
                {
                    return(null);                    // Over bought
                }
                if (tt == TradeType.Sell && rsi.Result.LastValue < 30.0)
                {
                    return(null);                    // Over sold
                }
                // Has the current price just left a strong SnR level?

                // Is there a candle pattern that agrees with the trade
            }
            return(new Trade(Instrument, tt, Label));
        }
Beispiel #2
0
        [Test] public void FromPoints()
        {
            var a = new v2(0.5f, 0.3f);
            var b = new v2(0.7f, -0.2f);
            var c = new v2(1.0f, 0.6f);

            var q = Quadratic.FromPoints(a, b, c);

            Assert.Equal(q.F(a.x), a.y, Math_.TinyF);
            Assert.Equal(q.F(b.x), b.y, Math_.TinyF);
            Assert.Equal(q.F(c.x), c.y, Math_.TinyF);
        }
Beispiel #3
0
        /// <summary>Trade entry signal based on MACD</summary>
        protected TradeType?SignalMACD()
        {
            // Look for minima or maxima in the short period average
            var macd = Bot.Indicators.MacdCrossOver(26, 12, 9);

            // Fit a quadratic to the MACD line (blue one)
            var poly = Quadratic.FromPoints(
                -2.0, macd.MACD.Last(2),
                -1.0, macd.MACD.Last(1),
                -0.0, macd.MACD.Last(0));

            // If the quadratic predicts a peak it might be time to buy/sell.
            var peak_x = poly.StationaryPoints[0];

            if (peak_x < -1.0 || peak_x > 0.0)
            {
                return(null);
            }

            var blue = macd.MACD.LastValue;
            var red  = macd.Signal.LastValue;

            for (;;)
            {
                var minima = poly.ddF(peak_x) > 0;
                if (minima)                 // buy?
                {
                    // MACD must be below the signal line
                    if (blue > red)
                    {
                        break;
                    }

                    return(TradeType.Buy);
                }
                else                 // sell?
                {
                    // MACD must be above the signal line
                    if (blue < red)
                    {
                        break;
                    }

                    return(TradeType.Sell);
                }
            }
            return(null);
        }