Multiple orders
Multiple orders
25 Oct 2012, 20:17
This is my ordersend logic:
if (position == null && pendingorder == null)
{
Trade.CreateBuyStopOrder(Symbol,Volume,Symbol.Bid,Symbol.Bid - Symbol.PipSize * StopLoss,null,Server.Time.AddSeconds(20));
}
I don't understand why my Robot sometimes open multiple orders at same time,sometimes up to 4.
How do I stop this?
Replies
admin
26 Oct 2012, 10:30
Hello,
We need to see the whole logic so that we can further investigate.
It seems that the variables position and pendingorder may not be initialized and remain null.
Are position and pendingorder global?
If so, are you setting the value of position and pendingorder:
protected override void OnPositionOpened(Position openedPosition)
{
position = openedPosition;
}
@admin
Uche
26 Oct 2012, 10:43
This is my code:
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Robots
{
[Robot]
public class Uchechukwu : Robot
{
[Parameter]
public DataSeries Source { get; set; }
[Parameter(DefaultValue = 100)]
public int WprPeriod { get; set; }
[Parameter("HV Period", DefaultValue = 14)]
public int HVPeriod { get; set; }
[Parameter("HV Barhistory", DefaultValue = 400)]
public int HVBarhistory { get; set; }
[Parameter(DefaultValue = 2)]
public int HVD { get; set; }
[Parameter(DefaultValue = 100000)]
public int Volume { get; set; }
[Parameter("Stop Loss (pips)", DefaultValue = 30)]
public int StopLoss { get; set; }
[Parameter("Trigger (pips)", DefaultValue = 30)]
public int Trigger { get; set; }
[Parameter("Trailing Stop (pips)", DefaultValue = 30)]
public int TrailingStop { get; set; }
[Parameter("MaxLoss", DefaultValue = -500.0)]
public double MaxLoss { get; set; }
private Position position;
private PendingOrder pendingorder;
private HistoricalVolatility _Hvol;
private WilliamsPctR _Wp;
///
/// Initialize Indicators
///
protected override void OnStart()
{
_Hvol = Indicators.HistoricalVolatility(Source,HVPeriod,HVBarhistory,HVD);
_Wp = Indicators.WilliamsPctR(WprPeriod);
}
protected override void OnTick()
{
if (Trade.IsExecuting) return;
double Hvol = _Hvol.Result.LastValue;
double Wp = _Wp.Result.LastValue;
double Time = Server.Time.Hour;
if (Time>=2 && Time<=23 && Hvol>=0.003 && Hvol<=0.020 && Wp<-80 && position == null)
{
if (pendingorder == null)
{
Trade.CreateBuyStopOrder(Symbol,Volume,Symbol.Bid,Symbol.Bid - Symbol.PipSize * StopLoss,null,Server.Time.AddSeconds(20));
}
}
if (Time>=2 && Time<=23 && Hvol>=0.003 && Hvol<=0.020 && Wp>-20 && position == null)
{
if (pendingorder == null)
{
Trade.CreateSellStopOrder(Symbol,Volume,Symbol.Ask,Symbol.Ask + Symbol.PipSize * StopLoss,null,Server.Time.AddSeconds(20));
}
}
if (pendingorder != null && pendingorder.SymbolCode == Symbol.Code)
{
if (position != null && position.SymbolCode == Symbol.Code || Symbol.Spread>2 || (pendingorder.TargetPrice-Symbol.Bid)*Symbol.PipSize>2 || (Symbol.Ask-pendingorder.TargetPrice)*Symbol.PipSize>2)
{
Trade.DeletePendingOrder(pendingorder);
}
}
if (position == null) return;
{
if (position != null && position.GrossProfit < MaxLoss)
{
Trade.Close(position);
}
if (position != null && position.TradeType == TradeType.Sell)
{
double distance = position.EntryPrice - Symbol.Ask;
if (distance > Trigger * Symbol.PipSize)
{
double newStopLossPrice = Symbol.Ask + TrailingStop * Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
{
Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
else
{
double distance = Symbol.Bid - position.EntryPrice;
if (distance > Trigger * Symbol.PipSize)
{
double newStopLossPrice = Symbol.Bid - TrailingStop * Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
{
Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
}
}
private void OpenPosition(TradeType command)
{
if (position != null)
{
Trade.Close(position);
position = null;
}
Trade.CreateMarketOrder(command, Symbol, Volume);
}
protected override void OnPositionOpened(Position openedPosition)
{
position = openedPosition;
Trade.ModifyPosition(openedPosition, GetAbsoluteStopLoss(openedPosition, StopLoss), null);
}
private double GetAbsoluteStopLoss(Position position, int stopLossInPips)
{
return position.TradeType == TradeType.Buy
? position.EntryPrice - Symbol.PipSize * stopLossInPips
: position.EntryPrice + Symbol.PipSize * stopLossInPips;
}
private void ClosePosition(Position position)
{
if (position == null) return;
Trade.Close(position);
}
}
}
@Uche
admin
26 Oct 2012, 12:31
OK. The problem is that you don't set the pendingorder field, therefore it is always null and the condition if (pendingorder == null) is always true.
So, on each tick the OnTick() event is called and a new pending order is requested from the server.
This statement if (Trade.IsExecuting) return; means that if a request is send to the server and the server did not respond yet then exit the method OnTick(). But if the server did respond this condition (Trade.IsExecuting) is false and the program continues execution with the following statements.
That is why you need to check if there is an order/position as well like you do: if (pendingorder == null) .
But the field that holds the information for the order/position needs to be set, i.e.
In your case you need to set the field pendingorder in the method OnPendingOrderCreated:
Also, this condition is always false and the pending order never gets deleted:
if (pendingorder != null && pendingorder.SymbolCode == Symbol.Code)
{
if (...)
{
Trade.DeletePendingOrder(pendingorder);
}
}
A few more points.
This method never gets called. What is the intended purpose of it?
private void OpenPosition(TradeType command)
{
if (position != null)
{
Trade.Close(position);
position = null;
}
Trade.CreateMarketOrder(command, Symbol, Volume);
}
if (position != null)
C# and .NET Programming - http://msdn.microsoft.com/en-us/library/orm-9780596521066-01-01.aspx
@admin
Uche
26 Oct 2012, 13:34
Hello,
I modified the code to:
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Robots
{
[Robot]
public class Uchechukwu : Robot
{
[Parameter]
public DataSeries Source { get; set; }
[Parameter(DefaultValue = 100)]
public int WprPeriod { get; set; }
[Parameter("HV Period", DefaultValue = 14)]
public int HVPeriod { get; set; }
[Parameter("HV Barhistory", DefaultValue = 400)]
public int HVBarhistory { get; set; }
[Parameter(DefaultValue = 2)]
public int HVD { get; set; }
[Parameter(DefaultValue = 100000)]
public int Volume { get; set; }
[Parameter("Stop Loss (pips)", DefaultValue = 30)]
public int StopLoss { get; set; }
[Parameter("Trigger (pips)", DefaultValue = 30)]
public int Trigger { get; set; }
[Parameter("Trailing Stop (pips)", DefaultValue = 30)]
public int TrailingStop { get; set; }
[Parameter("MaxLoss", DefaultValue = -500.0)]
public double MaxLoss { get; set; }
private Position position;
private PendingOrder pendingorder;
private HistoricalVolatility _Hvol;
private WilliamsPctR _Wp;
///
/// Initialize Indicators
///
protected override void OnStart()
{
_Hvol = Indicators.HistoricalVolatility(Source,HVPeriod,HVBarhistory,HVD);
_Wp = Indicators.WilliamsPctR(WprPeriod);
}
protected override void OnTick()
{
if (Trade.IsExecuting) return;
double Hvol = _Hvol.Result.LastValue;
double Wp = _Wp.Result.LastValue;
double Time = Server.Time.Hour;
if (Time>=2 && Time<=23 && Hvol>=0.003 && Hvol<=0.020 && Wp<-80 && position == null)
{
if (pendingorder == null)
{
Trade.CreateBuyStopOrder(Symbol,Volume,Symbol.Bid,Symbol.Bid - Symbol.PipSize * StopLoss,null,Server.Time.AddSeconds(20));
}
}
if (Time>=2 && Time<=23 && Hvol>=0.003 && Hvol<=0.020 && Wp>-20 && position == null)
{
if (pendingorder == null)
{
Trade.CreateSellStopOrder(Symbol,Volume,Symbol.Ask,Symbol.Ask + Symbol.PipSize * StopLoss,null,Server.Time.AddSeconds(20));
}
}
if (position == null) return;
{
if (position != null && position.TradeType == TradeType.Sell)
{
double distance = position.EntryPrice - Symbol.Ask;
if (distance > Trigger * Symbol.PipSize)
{
double newStopLossPrice = Symbol.Ask + TrailingStop * Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
{
Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
else
{
double distance = Symbol.Bid - position.EntryPrice;
if (distance > Trigger * Symbol.PipSize)
{
double newStopLossPrice = Symbol.Bid - TrailingStop * Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
{
Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
}
}
protected override void OnPendingOrderCreated(PendingOrder newOrder)
{
pendingorder = newOrder;
if (pendingorder != null && pendingorder.SymbolCode == Symbol.Code)
{
if (position != null && position.SymbolCode == Symbol.Code || Symbol.Spread>2 || (pendingorder.TargetPrice-Symbol.Bid)*Symbol.PipSize>2 || (Symbol.Ask-pendingorder.TargetPrice)*Symbol.PipSize>2)
{
Trade.DeletePendingOrder(pendingorder);
}
}
}
protected override void OnPositionOpened(Position openedPosition)
{
position = openedPosition;
if (position != null && position.GrossProfit < MaxLoss)
{
Trade.Close(position);
}
}
}
}
@Uche
admin
29 Oct 2012, 10:31
Hello,
We are not getting any double orders backtesting your robot. Can you make sure this is the only robot you are running and let us know?
You do need to include this event handler as well:
protected override void OnPositionClosed(Position closedPosition)
{
position = null;
}
@admin
admin
30 Oct 2012, 11:57
Hello,
Could you tell us the timeframe you are using as well as the exact input parameters? This way we can investigate further.
I presume that when you say multiple orders you mean simultaneous opennings of positions, correct?
Also, when you say moving the stop loss are you refering to programmatically modifying the position? Why do you suspect it creates a technical error?
Do you get an error message in the log? What exactly happens?
@admin
Uche
31 Oct 2012, 10:41
Hello Admin,
Please look closely at the code and performance to accertain why multiple orders are sent to the server.
Five orders were placed on one currency pair at same time while trading the 1min/2min charts;this is the highest number of orders I have seen so far.
I am trying to code my Mt4 strategy in Calgo,I love the speed and easy coding language but its starting to disappoint.
Kind regards
@Uche
admin
31 Oct 2012, 16:18
Hello,
We are testing your code but have been unsuccessful thus far in regenerating neither a technical error nor multiple positions.
In any case we are sending you a modified version of your code which might be a little more clear to read which includes reseting the pendingorder field to ensure that this robot creates exactly one position/pending order each time.
private Position position;
private PendingOrder pendingOrder;
private HistoricalVolatility _Hvol;
private WilliamsPctR _Wp;
// Initialize Indicators
protected override void OnStart()
{
_Hvol = Indicators.HistoricalVolatility(Source, HVPeriod, HVBarhistory, HVD);
_Wp = Indicators.WilliamsPctR(WprPeriod);
}
protected override void OnTick()
{
if (Trade.IsExecuting) return;
ResetPendingOrder();
double Hvol = _Hvol.Result.LastValue;
double Wp = _Wp.Result.LastValue;
double Time = Server.Time.Hour;
bool isTradingTime = Time >= 2 && Time <= 23;
bool isHighVolatility = Hvol >= 0.003 && Hvol <= 0.020;
if (isTradingTime && isHighVolatility && position == null && pendingOrder == null)
{
double? stopLoss;
DateTime? expiration = Server.Time.AddSeconds(20);
if (Wp < -80)
{
stopLoss = Symbol.Bid - Symbol.PipSize*StopLoss;
Trade.CreateBuyStopOrder(Symbol, Volume, Symbol.Bid, stopLoss, null, expiration);
}
else if (Wp > -20)
{
stopLoss = Symbol.Ask + Symbol.PipSize*StopLoss;
Trade.CreateSellStopOrder(Symbol, Volume, Symbol.Ask, stopLoss, null, expiration);
}
}
if (position == null) return;
if (position.TradeType == TradeType.Sell)
{
double distance = position.EntryPrice - Symbol.Ask;
if (distance > Trigger*Symbol.PipSize)
{
double newStopLossPrice = Symbol.Ask + TrailingStop*Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
{
Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
else
{
double distance = Symbol.Bid - position.EntryPrice;
if (distance > Trigger*Symbol.PipSize)
{
double newStopLossPrice = Symbol.Bid - TrailingStop*Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
{
Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
}
private void ResetPendingOrder()
{
bool exists = false;
foreach (var accountPendingOrder in Account.PendingOrders)
{
if (pendingOrder.Equals(accountPendingOrder))
{
exists = true;
break;
}
}
if (!exists)
pendingOrder = null;
}
protected override void OnPendingOrderCreated(PendingOrder newOrder)
{
pendingOrder = newOrder;
bool isLargeSpread = Symbol.Spread > 2;
bool isLargeBidDiff = (pendingOrder.TargetPrice - Symbol.Bid)*Symbol.PipSize > 2;
bool isLargeAskDiff = (Symbol.Ask - pendingOrder.TargetPrice)*Symbol.PipSize > 2;
if (position != null || isLargeSpread || isLargeBidDiff || isLargeAskDiff)
{
Trade.DeletePendingOrder(pendingOrder);
pendingOrder = null;
}
}
protected override void OnPositionOpened(Position openedPosition)
{
position = openedPosition;
// Pending Order Filled
pendingOrder = null;
if (position.GrossProfit < MaxLoss)
{
Trade.Close(position);
}
}
protected override void OnPositionClosed(Position closedPosition)
{
position = null;
}
}
}
@admin
Uche
31 Oct 2012, 18:51
RE:
Hello,
We are testing your code but have been unsuccessful thus far in regenerating neither a technical error nor multiple positions.
In any case we are sending you a modified version of your code which might be a little more clear to read which includes reseting the pendingorder field to ensure that this robot creates exactly one position/pending order each time.
private Position position;
private PendingOrder pendingOrder;
private HistoricalVolatility _Hvol;
private WilliamsPctR _Wp;
// Initialize Indicators
protected override void OnStart()
{
_Hvol = Indicators.HistoricalVolatility(Source, HVPeriod, HVBarhistory, HVD);
_Wp = Indicators.WilliamsPctR(WprPeriod);
}
protected override void OnTick()
{
if (Trade.IsExecuting) return;
ResetPendingOrder();
double Hvol = _Hvol.Result.LastValue;
double Wp = _Wp.Result.LastValue;
double Time = Server.Time.Hour;
bool isTradingTime = Time >= 2 && Time <= 23;
bool isHighVolatility = Hvol >= 0.003 && Hvol <= 0.020;
if (isTradingTime && isHighVolatility && position == null && pendingOrder == null)
{
double? stopLoss;
DateTime? expiration = Server.Time.AddSeconds(20);
if (Wp < -80)
{
stopLoss = Symbol.Bid - Symbol.PipSize*StopLoss;
Trade.CreateBuyStopOrder(Symbol, Volume, Symbol.Bid, stopLoss, null, expiration);
}
else if (Wp > -20)
{
stopLoss = Symbol.Ask + Symbol.PipSize*StopLoss;
Trade.CreateSellStopOrder(Symbol, Volume, Symbol.Ask, stopLoss, null, expiration);
}
}
if (position == null) return;
if (position.TradeType == TradeType.Sell)
{
double distance = position.EntryPrice - Symbol.Ask;
if (distance > Trigger*Symbol.PipSize)
{
double newStopLossPrice = Symbol.Ask + TrailingStop*Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice < position.StopLoss)
{
Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
else
{
double distance = Symbol.Bid - position.EntryPrice;
if (distance > Trigger*Symbol.PipSize)
{
double newStopLossPrice = Symbol.Bid - TrailingStop*Symbol.PipSize;
if (position.StopLoss == null || newStopLossPrice > position.StopLoss)
{
Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
}
private void ResetPendingOrder()
{
bool exists = false;
foreach (var accountPendingOrder in Account.PendingOrders)
{
if (pendingOrder.Equals(accountPendingOrder))
{
exists = true;
break;
}
}
if (!exists)
pendingOrder = null;
}
protected override void OnPendingOrderCreated(PendingOrder newOrder)
{
pendingOrder = newOrder;
bool isLargeSpread = Symbol.Spread > 2;
bool isLargeBidDiff = (pendingOrder.TargetPrice - Symbol.Bid)*Symbol.PipSize > 2;
bool isLargeAskDiff = (Symbol.Ask - pendingOrder.TargetPrice)*Symbol.PipSize > 2;
if (position != null || isLargeSpread || isLargeBidDiff || isLargeAskDiff)
{
Trade.DeletePendingOrder(pendingOrder);
pendingOrder = null;
}
}
protected override void OnPositionOpened(Position openedPosition)
{
position = openedPosition;
// Pending Order Filled
pendingOrder = null;
if (position.GrossProfit < MaxLoss)
{
Trade.Close(position);
}
}
protected override void OnPositionClosed(Position closedPosition)
{
position = null;
}
}
}
Looks good on tester.Lets see how it goes on real time.
Thanks for prompt response.
@Uche
admin
01 Nov 2012, 12:30
Hello,
In the event OnPositionOpened GrossProfit will be very small. You can test it with a print statement.
protected override void OnPositionOpened(Position openedPosition)
{
position = openedPosition;
// Pending Order Filled
pendingOrder = null;
Print("GrossProfit = {0}", position.GrossProfit);
if (position.GrossProfit < MaxLoss)
{
Trade.Close(position);
}
}
@admin
Uche
07 Nov 2012, 17:03
RE:
Its an OnTick crash.....object not set on instance...Hello,
Can you tell us for which symbols it is happening as well as the error message(s) you are receiving so that we can speed up the investigation?
@Uche
trader4mat
26 Oct 2012, 08:21
I had the same problem, The robot doesn't wait untill the trade is executed and runs the algorithm a couple of times while the trade is in execution.
Add this line of code:
4maT
@trader4mat