protected override void OnTimer() { var remainingTime = _triggerTimeInServerTimeZone - Server.Time; DrawRemainingTime(remainingTime); if (!_ordersCreated) { var sellOrderTargetPrice = Symbol.Bid - PipsAway * Symbol.PipSize; ChartObjects.DrawHorizontalLine("sell target", sellOrderTargetPrice, Colors.Red, 1, LineStyle.DotsVeryRare); var buyOrderTargetPrice = Symbol.Ask + PipsAway * Symbol.PipSize; ChartObjects.DrawHorizontalLine("buy target", buyOrderTargetPrice, Colors.Blue, 1, LineStyle.DotsVeryRare); if (Server.Time <= _triggerTimeInServerTimeZone && (_triggerTimeInServerTimeZone - Server.Time).TotalSeconds <= SecondsBefore) { _ordersCreated = true; var expirationTime = _triggerTimeInServerTimeZone.AddSeconds(SecondsTimeout); PlaceStopOrder(TradeType.Sell, Symbol, Volume, sellOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime); PlaceStopOrder(TradeType.Buy, Symbol, Volume, buyOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime); ChartObjects.RemoveObject("sell target"); ChartObjects.RemoveObject("buy target"); } } if (_ordersCreated && !PendingOrders.Any(o => o.Label == Label)) { Print("Orders expired"); Stop(); } }
protected override void OnBar() { if (_currentPosition != null) { BarsSinceEntry++; //Print("Bars since entry: {0}", BarsSinceEntry); ModifyOppositeColourBarTrailingStop(); } if (!_canOpenPosition || PendingOrders.Any()) { return; } if (ShouldWaitBeforeLookingForNewSetup()) { return; } if (_takeLongsParameter && HasBullishSignal()) { EnterLongPosition(); } else if (_takeShortsParameter && HasBearishSignal()) { EnterShortPosition(); } }
protected override void OnBar() { if (AdjustPendingOrder && PendingOrders.Any()) { CheckToAdjustPendingOrder(); } base.OnBar(); }
/// <summary>Called when new data is received</summary> public override void Step() { base.Step(); Debugging.BreakOnPointOfInterest(); if (Instrument.NewCandle) { Debugging.LogInstrument(); } if (PendingOrders.Any()) { return; } // Look for an existing trade for this strategy. var position = Positions.FirstOrDefault(); if (position == null) { // 'ep' must be lower than 'tp' var ep = 0.2; var tp = 0.6; var sl = 0.8; var exp = 1; var step = Instrument.MCS; //MedianCandleSize(-5,1); var sym = Instrument.LatestPrice; var trade0 = new Trade(Instrument, TradeType.Buy, Label, ep: sym.Ask + ep * step, sl: sym.Ask - sl * step, tp: sym.Ask + tp * step, risk: 0.5f) { Expiration = (Bot.UtcNow + Instrument.TimeFrame.ToTimeSpan(exp)).DateTime }; var trade1 = new Trade(Instrument, TradeType.Sell, Label, ep: sym.Bid - ep * step, sl: sym.Bid + sl * step, tp: sym.Bid - tp * step, risk: 0.5f) { Expiration = (Bot.UtcNow + Instrument.TimeFrame.ToTimeSpan(exp)).DateTime }; Broker.CreatePendingOrder(trade0); Broker.CreatePendingOrder(trade1); } else { } }
/// <summary>Called when new data is received</summary> public override void Step() { base.Step(); if (Instrument.NewCandle || Positions.Any() || PendingOrders.Any()) { Dump(); } var sign0 = Math.Sign(EMA0[0].CompareTo(EMA1[0])); var sign1 = Math.Sign(EMA0[-1].CompareTo(EMA1[-1])); var order = PendingOrders.FirstOrDefault(); var position = Positions.FirstOrDefault(); // Cancel or close positions/orders that are against the trend if (order != null && order.Sign() != sign0) { Broker.CancelPendingOrder(order); order = null; } if (position != null && position.Sign() != sign0) { Broker.CloseAt(Instrument, position, EMA0[0]); } // Look for EMA crosses if (sign0 != sign1) { var mcs = Instrument.MCS; var price = EMA0[0] - sign0 * Instrument.Spread; if (order == null || Math.Abs(order.TargetPrice - price) > 2) { // Cancel any previous pending orders Broker.CancelAllPendingOrders(Label); // Create a pending order at the cross price var sl = price - sign0 * mcs * 5; var vol = Broker.ChooseVolume(Instrument, Math.Abs(price - sl), risk: Risk); var trade = new Trade(Instrument, CAlgo.SignToTradeType(sign0), Label, price, sl, null, vol); Broker.CreatePendingOrder(trade); } } }
protected override void OnTimer() { int index = MarketSeries.Close.Count - 1; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; try { NI = DisplayUpcomingNews(); } catch (Exception e) { Log("Exception3: {0}", e.Message); } //If we have an order we can che if (!ShowNewsOnly) { try { var remainingTime = _triggerTimeInServerTimeZone - Server.Time; DrawRemainingTime(remainingTime); } catch (Exception e) { Log("Exception4: {0}", e.Message); } } if (ShowPastNews) { //If first loop, we need to check all histarical bars for news if (first_run) { for (int idx = 0; idx < index; idx++) { DisplayPastNews(idx); } first_run = false; } //Otherwise just the latest else { DisplayPastNews(index); } } //If we have no pending ordes or positions open we need to setup next newstrade (switch _ordersCreated to false) if (_ordersCreated && !PendingOrders.Any(o => o.Label == Label) && ((Positions.FindAll(Label, Symbol, TradeType.Buy).Length + Positions.FindAll(Label, Symbol, TradeType.Sell).Length) == 0)) { Log("Resuming Order operations"); _ordersCreated = false; } //If we have a market order and it is active then leave. This is really Ugly.... if (_ordersCreated && (Positions.Count > 0)) { if (TrailingStop) { updateSL(); } return; } try { _triggerTimeInServerTimeZone = NI.UtcDateTime; } catch (Exception e) { Log("Exception5: {0}", e.Message); } if (!_ordersCreated && !ShowNewsOnly) { //ExecuteMarketOrder(TradeType.Sell, Symbol, 1000, Label, null, 1); //ExecuteMarketOrder(TradeType.Buy, Symbol, 1000, Label, null, 1); //_ordersCreated = true; var sellOrderTargetPrice = Symbol.Bid - PipsAway * Symbol.PipSize; ChartObjects.DrawHorizontalLine("sell target", sellOrderTargetPrice, Colors.Red, 1, LineStyle.DotsVeryRare); var buyOrderTargetPrice = Symbol.Ask + PipsAway * Symbol.PipSize; ChartObjects.DrawHorizontalLine("buy target", buyOrderTargetPrice, Colors.Blue, 1, LineStyle.DotsVeryRare); if (Server.Time <= _triggerTimeInServerTimeZone && (_triggerTimeInServerTimeZone - Server.Time).TotalSeconds <= SecondsBefore) { _ordersCreated = true; var expirationTime = _triggerTimeInServerTimeZone.AddSeconds(SecondsTimeout); if (TrailingStop) { PlaceStopOrder(TradeType.Sell, Symbol, Volume, sellOrderTargetPrice, Label, StopLoss, null, expirationTime); PlaceStopOrder(TradeType.Buy, Symbol, Volume, buyOrderTargetPrice, Label, StopLoss, null, expirationTime); } else { PlaceStopOrder(TradeType.Sell, Symbol, Volume, sellOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime); PlaceStopOrder(TradeType.Buy, Symbol, Volume, buyOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime); } ChartObjects.RemoveObject("sell target"); ChartObjects.RemoveObject("buy target"); } } }
/// <summary>Called when new data is received</summary> public override void Step() { base.Step(); if (Instrument.NewCandle) { Dump(); } // Don't open new positions while there are pending orders or existing positions if (Positions.Any() || PendingOrders.Any()) { return; } // Look for peak patterns TradeType tt; QuoteCurrency ep; var pat = Instrument.IsPeakPattern(Instrument.IdxNow, out tt, out ep); if (pat != null) { var pattern = pat.Value; Dump(); Debugging.Dump(new PricePeaks(Instrument, 0)); Debugging.Dump(new SnR(Instrument)); Debugging.Trace("Peak pattern: {0}".Fmt(pattern)); var sign = tt.Sign(); var mcs = Instrument.MCS; // Convert the patterns to trades switch (pattern) { case EPeakPattern.BreakOutHigh: case EPeakPattern.BreakOutLow: { // For break outs, enter immediately and use a candle // follow position manager because they tend to run. var price_range = Instrument.PriceRange(-10, 1); var sl = price_range.Mid - sign * price_range.Size * 0.6; 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); var pos = Broker.CreateOrder(trade); if (pos != null) { PositionManagers.Add(new PositionManagerCandleFollow(this, pos, 5)); } break; } case EPeakPattern.HighReversal: case EPeakPattern.LowReversal: { // For reversals, enter when the price is near the trend line. // Use a fixed SL/TP var price_range = Instrument.PriceRange(-10, 1); var sl = price_range.Mid - sign * price_range.Size * 0.6; var tp = price_range.Mid + sign * price_range.Size * 0.4; var vol = Broker.ChooseVolume(Instrument, Math.Abs(ep - sl), risk: Risk); // If the current price is better than the entry price, enter immediately if (sign * (ep - Instrument.CurrentPrice(sign)) > 0) { var trade = new Trade(Instrument, tt, Label, ep, sl, tp, vol); Broker.CreateOrder(trade); } else { var order = new Trade(Instrument, tt, Label, ep, sl, tp, vol) { Expiration = Instrument.ExpirationTime(1) }; Broker.CreatePendingOrder(order); } break; } } } }
/// <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; } } }