RESOLVED: Execute sell when x number of buy trades open.
RESOLVED: Execute sell when x number of buy trades open.
28 Sep 2023, 18:27
Hello,
I've downloaded a free cBot and i'm trying to add a hedging strategy. Unfortunately, I really can't currently work out what I need to add to the below block of code to make it work. I do a lot of scripting but I'm not a programmer.
The hedging strategy consists of executing a sell order when the number of open buy positions equals the maximum set by the paramiter below
[Parameter("Maximum open buy positions?", Group = "Basic Setup", DefaultValue = 8, MinValue = 0)]
public int MaxOpenBuy { get; set; }
On looking for a direction, I found this thread https://ctrader.com/forum/cbot-support/9321 but still not sure how to apply it to the below. A further complication for me is that I'd like the hedge position to equal the volume of all open positions combined. I found the below line which seems relevent.
var buyTotalVolume = Positions.Where(x => x.TradeType == TradeType.Buy).Sum(x => x.VolumeInUnits);
Below is the code I would like to add the hedging to.
private void ProcessBuy()
{
if (Positions.Count(x => x.TradeType == TradeType.Buy && x.SymbolName == SymbolName && x.Label == ThiscBotLabel) == 0 && MarketSeries.Close.Last(1) > MarketSeries.Close.Last(2))
{
_initialVolume = GetVolume();
ExecuteMarketOrder(TradeType.Buy, SymbolName, _initialVolume, ThiscBotLabel, StopLossPips, null);
LastBuyTradeTime = MarketSeries.OpenTime.Last(0);
}
if (Positions.Count(x => x.TradeType == TradeType.Buy && x.SymbolName == SymbolName && x.Label == ThiscBotLabel) > 0)
{
if (Symbol.Ask < (Positions.Where(x => x.TradeType == TradeType.Buy && x.SymbolName == SymbolName && x.Label == ThiscBotLabel).Min(x => x.EntryPrice) - PipStep * Symbol.PipSize) && LastBuyTradeTime != MarketSeries.OpenTime.Last(0))
{
ExecuteMarketOrder(TradeType.Buy, SymbolName, CalculateVolume(TradeType.Buy), ThiscBotLabel, StopLossPips, null);
LastBuyTradeTime = MarketSeries.OpenTime.Last(0);
}
}
}
Any help with this would be amazing. Thanks in advance.
Replies
nickbowes2020
30 Sep 2023, 12:56
( Updated at: 01 Oct 2023, 16:08 )
Execute sell when x number of buy trades open.
I've managed to stop the bot opening a hedge position on every tick by checking how many hedge positions are currently open. See below.
// Conditions check before process hedge trade
if (Symbol.Spread / Symbol.PipSize <= MaxSpread)
{
if (Positions.Count(x => x.TradeType == TradeType.Buy && x.SymbolName == SymbolName && x.Label == ThiscBotLabel) == MaxOpenBuy)
ProcessBuyHedge();
}
// Calculate buy volume and execute sell order on execution of last allowed buy order
private void ProcessBuyHedge()
{
if (Positions.Count(x => x.TradeType == TradeType.Sell && x.SymbolName == SymbolName && x.Label == "BuyHedge") < 1)
{
var buyTotalVolume = Positions.Where(x => x.TradeType == TradeType.Buy).Sum(x => x.VolumeInUnits);
ExecuteMarketOrder(TradeType.Sell, SymbolName, buyTotalVolume, "BuyHedge", 50, 1500, null);
LastSellTradeTime = Bars.OpenTimes.Last(0);
}
}
However, what happens now is that when the hedge position opened by the above code hits either its stop loss or take profit, it immediately opens another hedge position at whatever price the last hedge position was closed. I would like to stop this happaning.
There are two ways I can think of to stop the unwanted hedge positions from opening.
- Check the entry price for the last buy position. If the current bid price is not within 5 or 10 pips of this price then do not open another hedge position.
- Create a unique name for the group of buy positions I would be hedging and only allow one hedge position to be opened for that buy group.
I think option one would be best. Could you help me with the following two things.
- How to get the last (still open) buy position entry price into a variable?
- How to compare the above with the current bid price?
Thanks in advance.
@nickbowes2020
nickbowes2020
01 Oct 2023, 16:02
( Updated at: 01 Oct 2023, 16:08 )
RE: Execute sell when x number of buy trades open.
I have some working code now see below. Hopefully this is helpful someone in the future.
// Conditions check before process hedge trade
if (Symbol.Spread / Symbol.PipSize <= MaxSpread)
{
if (Positions.Count(x => x.TradeType == TradeType.Buy && x.SymbolName == SymbolName && x.Label == ThiscBotLabel) == MaxOpenBuy)
ProcessBuyHedge();
}
private void ProcessBuyHedge()
{
if (BuyHedge == true)
{
if (Positions.Count(x => x.TradeType == TradeType.Sell && x.SymbolName == SymbolName && x.Label == "BuyHedge") < 1)
{
var lastBuyPosition = Positions.Where(position => position.TradeType == TradeType.Buy).OrderBy(position => position.EntryTime).LastOrDefault();
var lastBuyPositionEntryPrice = lastBuyPosition.EntryPrice;
if (Symbol.Bid <= lastBuyPosition.EntryPrice && Symbol.Bid >= lastBuyPosition.EntryPrice - 5 * Symbol.PipSize)
{
var buyTotalVolume = Positions.Where(x => x.TradeType == TradeType.Buy).Sum(x => x.VolumeInUnits);
ExecuteMarketOrder(TradeType.Sell, SymbolName, buyTotalVolume, "BuyHedge", null, 25, null);
LastSellTradeTime = Bars.OpenTimes.Last(0);
}
}
}
}
@nickbowes2020
nickbowes2020
03 Oct 2023, 19:44
( Updated at: 03 Oct 2023, 19:45 )
RE: RE: Execute sell when x number of buy trades open.
This is the above code cleaned and tested to be working. I plan to add features to this in the future as it works well for my strategy.
private void ProcessBuyHedge()
{
if (BuyHedge == true)
{
var BuyHedgePositions = Positions.FindAll("BuyHedge");
var lastBuyPosition = Positions.Where(position => position.TradeType == TradeType.Buy).OrderBy(position => position.EntryTime).LastOrDefault();
var lastBuyPositionEntryPrice = lastBuyPosition.EntryPrice;
var buyTotalVolume = Positions.Where(x => x.TradeType == TradeType.Buy).Sum(x => x.VolumeInUnits);
if (Symbol.Bid == lastBuyPosition.EntryPrice)
{
if (BuyHedgePositions.Length == 0)
{
ExecuteMarketOrder(TradeType.Sell, SymbolName, buyTotalVolume, "BuyHedge", null, 20, null);
LastSellTradeTime = Bars.OpenTimes.Last(0);
}
}
}
}
@nickbowes2020
nickbowes2020
29 Sep 2023, 15:01 ( Updated at: 29 Sep 2023, 19:06 )
ok please ignore the code pasted above, I've managed to get the basic concept working with some small additions (see below).
Now what happens is that when the last allowed buy order is executed, a sell order is also executed with a volume equal to all open buy positions. Thats great and exactly what I wanted. However, It doesn't stop at opening just one sell position, it opens a new sell position on every new tick after that.
My question - how can I stop the processHedge function from executing a sell order on every tick after the conditions in the below code have been met?
I'm guessing that I'll need to add an if statement that checks how many sell orders are open and if its equal to 1, don't process any more sell orders?
// Conditions check before process hedge trade
if (Symbol.Spread / Symbol.PipSize <= MaxSpread)
{
if (Positions.Count(x => x.TradeType == TradeType.Buy && x.SymbolName == SymbolName && x.Label == ThiscBotLabel) == MaxOpenBuy)
ProcessHedge();
}
// Calculate buy volume and execute sell order on execution of last allowed buy order
private void ProcessHedge()
{
var buyTotalVolume = Positions.Where(x => x.TradeType == TradeType.Buy).Sum(x => x.VolumeInUnits);
ExecuteMarketOrder(TradeType.Sell, SymbolName, buyTotalVolume, ThiscBotLabel, StopLossPips, null);
LastSellTradeTime = Bars.OpenTimes.Last(0);
}
@nickbowes2020