Description
Robot Create For Pending Order before the News, Exactly on second and add trailing stop
Parameters:
- News Hour UTC - Hour when news will be published (UTC time)
- News Minute - Minute when news will be published (UTC time)
- Pips away - The number of pips away from the current market price where the pending buy and sell orders will be placed.
- Take Profit - Take Profit in pips for each order
- Stop Loss - Stop Loss in pips for each order
- Volume - trading volume
- Seconds before - Seconds Before News when robot will place Pending Orders
- Seconds timeout - Seconds After News when Pending Orders will be deleted
- One Cancels Other - If "Yes" then when one order will be filled, another order will be deleted
-
Include Trailing Stop if you want to trailing
-
Trailing Stop Trigger (pips): Trailing if you won pips
-
Trailing Stop Step (pips): step to move trailing stop
If you have any questions or need to code a robot or change don't hesitate to contact me at
Email: Nghiand.amz@gmail.com Telegram: https://t.me/ndnghia
You can find all bot at https://gumroad.com/nghia312
Donate me at https://nghia312.gumroad.com/l/yagsz
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using cAlgo.API;
using Button = cAlgo.API.Button;
using HorizontalAlignment = cAlgo.API.HorizontalAlignment;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class NewsRobot : Robot
{
[Parameter("News Year", Group = "Day, set to 0 if ignore", DefaultValue = 0, MinValue = 0, MaxValue = 3000)]
public int NewsYear { get; set; }
[Parameter("News Month", Group = "Day, set to 0 if ignore", DefaultValue = 0, MinValue = 0, MaxValue = 12)]
public int NewsMonth { get; set; }
[Parameter("News Day", Group = "Day, set to 0 if ignore", DefaultValue = 0, MinValue = 0, MaxValue = 31)]
public int NewsDay { get; set; }
[Parameter("News Hour UTC", Group = "News", DefaultValue = 14, MinValue = 0, MaxValue = 23)]
public int NewsHour { get; set; }
[Parameter("News Minute", Group = "News", DefaultValue = 30, MinValue = 0, MaxValue = 59)]
public int NewsMinute { get; set; }
[Parameter("Pips away", Group = "News", DefaultValue = 10)]
public int PipsAway { get; set; }
[Parameter("Take Profit", Group = "News", DefaultValue = 50)]
public int TakeProfit { get; set; }
[Parameter("Stop Loss", Group = "News", DefaultValue = 10)]
public int StopLoss { get; set; }
[Parameter("Lot", Group = "News", DefaultValue = 1, MinValue = 0)]
public double Lot { get; set; }
[Parameter("Seconds Before", Group = "News", DefaultValue = 10, MinValue = 1)]
public int SecondsBefore { get; set; }
[Parameter("Seconds Timeout", Group = "News", DefaultValue = 10, MinValue = 1)]
public int SecondsTimeout { get; set; }
[Parameter("One Cancels Other", Group = "News")]
public bool Oco { get; set; }
[Parameter("Close all after seconds (0 mean not close)", Group = "News", DefaultValue = 0)]
public int CloseAllAfterSeconds { get; set; }
[Parameter("ShowTimeLeftNews", Group = "News", DefaultValue = false)]
public bool ShowTimeLeftToNews { get; set; }
[Parameter("ShowTimeLeftPlaceOrders", Group = "News", DefaultValue = true)]
public bool ShowTimeLeftToPlaceOrders { get; set; }
[Parameter("Include Trailing Stop", Group = "Trailing", DefaultValue = true)]
public bool IncludeTrailingStop { get; set; }
[Parameter("Trailing Stop Trigger (pips)", Group = "Trailing", DefaultValue = 20)]
public double TrailingStopTrigger { get; set; }
[Parameter("Trailing Stop Step (pips)", Group = "Trailing", DefaultValue = 10)]
public double TrailingStopStep { get; set; }
private bool _ordersCreated;
private DateTime _triggerTimeInServerTimeZone;
private const string Label = "News Robot";
protected override void OnStart()
{
Positions.Opened += OnPositionOpened;
Positions.Closed += Positions_Closed;
var btnDonate = new Button()
{
Text = "PLEASE DONATE",
Margin = 5,
BackgroundColor = Color.Green
};
btnDonate.Click += btnDonate_Click;
var stackPanel = new StackPanel()
{
Width = 200,
HorizontalAlignment = HorizontalAlignment.Right
};
stackPanel.AddChild(btnDonate);
Chart.AddControl(stackPanel);
Timer.Start(1);
}
private void Positions_Closed(PositionClosedEventArgs obj)
{
try
{
var position = obj.Position;
if (position.Label == Label && position.SymbolName == SymbolName)
{
//if (position.NetProfit > 100)
//{
// MessageBoxResult targetMessageResult = API.MessageBox.Show("Congratulation you've won, donate to developer?",
// "Congratulation!!", MessageBoxButton.YesNo, MessageBoxImage.Question);
// if (targetMessageResult == MessageBoxResult.Yes)
// {
// StartDonate();
// }
//}
//Stop();
}
}
catch (Exception ex)
{
Print(ex);
}
}
private void btnDonate_Click(ButtonClickEventArgs obj)
{
try
{
StartDonate();
}
catch (Exception ex)
{
Print(ex);
}
}
private void StartDonate()
{
ProcessStartInfo sInfo = new ProcessStartInfo("https://nghia312.gumroad.com/l/yagsz");
sInfo.UseShellExecute = true;
Process.Start(sInfo);
}
protected override void OnTick()
{
if (IncludeTrailingStop)
{
SetTrailingStop();
}
}
private void SetTrailingStop()
{
var sellPositions = Positions.FindAll(Label, SymbolName, TradeType.Sell);
foreach (Position position in sellPositions)
{
double distance = position.EntryPrice - Symbol.Ask;
if (distance < TrailingStopTrigger * Symbol.PipSize)
continue;
double newStopLossPrice = Symbol.Ask + TrailingStopStep * Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
var buyPositions = Positions.FindAll(Label, SymbolName, TradeType.Buy);
foreach (Position position in buyPositions)
{
double distance = Symbol.Bid - position.EntryPrice;
if (distance < TrailingStopTrigger * Symbol.PipSize)
continue;
double newStopLossPrice = Symbol.Bid - TrailingStopStep * Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
protected override void OnTimer()
{
var trigTime = Server.Time;
if (NewsYear != 0 && NewsMonth != 0 && NewsDay != 0)
{
trigTime = new DateTime(NewsYear, NewsMonth, NewsDay);
}
_triggerTimeInServerTimeZone = new DateTime(trigTime.Year, trigTime.Month, trigTime.Day, NewsHour, NewsMinute, 0);
var remainingTime = _triggerTimeInServerTimeZone - Server.Time;
DrawRemainingTime(remainingTime);
var expirationTime = _triggerTimeInServerTimeZone.AddSeconds(SecondsTimeout);
if (!_ordersCreated)
{
var sellOrderTargetPrice = Symbol.Bid - PipsAway * Symbol.PipSize;
Chart.DrawHorizontalLine("sell target", sellOrderTargetPrice, Color.Red, 1, LineStyle.DotsVeryRare);
var buyOrderTargetPrice = Symbol.Ask + PipsAway * Symbol.PipSize;
Chart.DrawHorizontalLine("buy target", buyOrderTargetPrice, Color.Blue, 1, LineStyle.DotsVeryRare);
if (Server.Time <= _triggerTimeInServerTimeZone && (_triggerTimeInServerTimeZone - Server.Time).TotalSeconds <= SecondsBefore)
{
_ordersCreated = true;
var volume = Symbol.QuantityToVolumeInUnits(Lot);
var nomalVolume = Symbol.NormalizeVolumeInUnits(volume);
var res = PlaceStopOrder(TradeType.Sell, SymbolName, nomalVolume, sellOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime);
var res2 = PlaceStopOrder(TradeType.Buy, SymbolName, nomalVolume, buyOrderTargetPrice, Label, StopLoss, TakeProfit, expirationTime);
Chart.RemoveObject("sell target");
Chart.RemoveObject("buy target");
}
}
if (_ordersCreated && !PendingOrders.Any(o => o.Label == Label))
{
foreach (var order in PendingOrders)
{
if (order.Label == Label && order.SymbolName == SymbolName)
{
CancelPendingOrderAsync(order);
}
}
}
var closeTimeout = _triggerTimeInServerTimeZone.AddSeconds(CloseAllAfterSeconds);
if (Server.Time >= closeTimeout)
{
var positions = Positions.FindAll(Label, SymbolName);
foreach (var position in positions)
{
position.Close();
}
}
}
private void DrawRemainingTime(TimeSpan remainingTimeToNews)
{
if (ShowTimeLeftToNews)
{
if (remainingTimeToNews > TimeSpan.Zero)
{
Chart.DrawStaticText("countdown1", "Time left to news: " + FormatTime(remainingTimeToNews),
VerticalAlignment.Top, HorizontalAlignment.Left, Color.Red);
}
else
{
Chart.RemoveObject("countdown1");
}
}
if (ShowTimeLeftToPlaceOrders)
{
var remainingTimeToOrders = remainingTimeToNews - TimeSpan.FromSeconds(SecondsBefore);
if (remainingTimeToOrders > TimeSpan.Zero)
{
Chart.DrawStaticText("countdown2", "Time left to place orders: " + FormatTime(remainingTimeToOrders),
VerticalAlignment.Top, HorizontalAlignment.Right, Color.Red);
}
else
{
Chart.RemoveObject("countdown2");
}
}
}
private static StringBuilder FormatTime(TimeSpan remainingTime)
{
var remainingTimeStr = new StringBuilder();
if (remainingTime.TotalHours >= 1)
remainingTimeStr.Append((int)remainingTime.TotalHours + "h ");
if (remainingTime.TotalMinutes >= 1)
remainingTimeStr.Append(remainingTime.Minutes + "m ");
if (remainingTime.TotalSeconds > 0)
remainingTimeStr.Append(remainingTime.Seconds + "s");
return remainingTimeStr;
}
private void OnPositionOpened(PositionOpenedEventArgs args)
{
var position = args.Position;
if (position.Label == Label && position.SymbolName == SymbolName)
{
if (Oco)
{
foreach (var order in PendingOrders)
{
if (order.Label == Label && order.SymbolName == SymbolName)
{
CancelPendingOrderAsync(order);
}
}
}
}
}
}
}
nghiand.amz
Joined on 06.07.2020
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: DragonNewsBotWithTrailing.algo
- Rating: 5
- Installs: 1044
- Modified: 28/12/2022 17:35
Comments
Hi
I am on a Demo account and in the process of familiarising myself with the parameters of “News triger bot with trailing stop”. Could you please indicate whether the stop loss pips are determined from the current market price or from a pending order when it is triggered?
Thank you for posting that it could be just the thing to give inspiration to someone who needs it! Keep up the great work! kravers seafood mobile al menu
Thanks a lot for a great bot.
I tested the demo, and the Stop Loss (SL) was triggered every time. Pending orders were placed before the News time. However, upon examining the graph on a 1-tick timeframe, I noticed that the price jumped (gapped) around 7-8 seconds, moving against our intended order direction and triggering our SL. Could you please modify the code so that the bot can open orders 8-9 seconds after the News time?