Unrealized P&L
Unrealized P&L
08 May 2013, 16:29
Is it possible to develop a robot which can close multiple position based on total current 'Unrealized P&L'?
i.e. the bot is running on multile pairs. I would like the bot to close all active trading once the total 'Unrealized P&L' is USD30
Replies
damon153058
21 May 2013, 18:46
How to combine?
var netProfit = 0.0; foreach (var openedPosition in Account.Positions) { netProfit += openedPosition.NetProfit; } if(netProfit <= 100.0) { foreach (var openedPosition in Account.Positions) { Trade.Close(openedPosition); } Stop(); // Stop the robot }
using System; using cAlgo.API; namespace cAlgo.Robots { [Robot("Robot Forex")] public class RobotForex : Robot { [Parameter(DefaultValue = 10000, MinValue = 10000)] public int FirstLot { get; set; } [Parameter("Take_Profit", DefaultValue = 180, MinValue = 10)] public int TakeProfit { get; set; } [Parameter("Tral_Start", DefaultValue = 50)] public int Tral_Start { get; set; } [Parameter("Tral_Stop", DefaultValue = 50)] public int Tral_Stop { get; set; } [Parameter(DefaultValue = 300)] public int PipStep { get; set; } [Parameter(DefaultValue = 5, MinValue = 2)] public int MaxOrders { get; set; } private Position position; private bool RobotStopped; private int LotStep=10000; protected override void OnStart() { } protected override void OnTick() { double Bid=Symbol.Bid; double Ask=Symbol.Ask; double Point=Symbol.PointSize; if(Trade.IsExecuting) return; if(Account.Positions.Count > 0 && RobotStopped) return; else RobotStopped = false; if(Account.Positions.Count == 0) SendFirstOrder(FirstLot); else ControlSeries(); foreach (var position in Account.Positions) { if(position.SymbolCode == Symbol.Code) { if(position.TradeType == TradeType.Buy) { if (Bid-GetAveragePrice(TradeType.Buy)>=Tral_Start*Point) if (Bid-Tral_Stop*Point>=position.StopLoss) Trade.ModifyPosition(position, Bid-Tral_Stop*Point, position.TakeProfit); } if(position.TradeType == TradeType.Sell) { if (GetAveragePrice(TradeType.Sell)-Ask>=Tral_Start*Point) if (Ask+Tral_Stop*Point<=position.StopLoss || position.StopLoss==0) Trade.ModifyPosition(position, Ask+Tral_Stop*Point, position.TakeProfit); } } } } protected override void OnError(Error CodeOfError) { if(CodeOfError.Code == ErrorCode.NoMoney) { RobotStopped = true; Print("ERROR!!! No money for order open, robot is stopped!"); } else if(CodeOfError.Code == ErrorCode.BadVolume) { RobotStopped = true; Print("ERROR!!! Bad volume for order open, robot is stopped!"); } } private void SendFirstOrder(int OrderVolume) { int Signal = GetStdIlanSignal(); if(!(Signal < 0)) switch(Signal) { case 0: Trade.CreateBuyMarketOrder(Symbol, OrderVolume); break; case 1: Trade.CreateSellMarketOrder(Symbol, OrderVolume); break; } } protected override void OnPositionOpened(Position openedPosition) { double? StopLossPrice = null; double? TakeProfitPrice = null; if(Account.Positions.Count == 1) { position = openedPosition; if( position.TradeType == TradeType.Buy) TakeProfitPrice = position.EntryPrice + TakeProfit * Symbol.PointSize; if( position.TradeType == TradeType.Sell) TakeProfitPrice = position.EntryPrice - TakeProfit * Symbol.PointSize; } else switch(GetPositionsSide()) { case 0: TakeProfitPrice = GetAveragePrice(TradeType.Buy) + TakeProfit * Symbol.PointSize; break; case 1: TakeProfitPrice = GetAveragePrice(TradeType.Sell) - TakeProfit * Symbol.PointSize; break; } for(int i = 0; i < Account.Positions.Count; i++) { position = Account.Positions[i]; if(StopLossPrice != null || TakeProfitPrice != null) Trade.ModifyPosition(position, position.StopLoss, TakeProfitPrice); } } private double GetAveragePrice(TradeType TypeOfTrade) { double Result = Symbol.Bid; double AveragePrice = 0; long Count = 0; for(int i = 0; i < Account.Positions.Count; i++) { position = Account.Positions[i]; if(position.TradeType == TypeOfTrade) { AveragePrice += position.EntryPrice * position.Volume; Count += position.Volume; } } if(AveragePrice > 0 && Count > 0) Result = AveragePrice / Count; return Result; } private int GetPositionsSide() { int Result = -1; int i, BuySide = 0, SellSide = 0; for(i = 0; i < Account.Positions.Count; i++) { if(Account.Positions[i].TradeType == TradeType.Buy) BuySide++; if(Account.Positions[i].TradeType == TradeType.Sell) SellSide++; } if(BuySide == Account.Positions.Count) Result = 0; if(SellSide == Account.Positions.Count) Result = 1; return Result; } private void ControlSeries() { int _pipstep, NewVolume, Rem; int BarCount = 25; int Del = MaxOrders - 1; if(PipStep == 0) _pipstep = GetDynamicPipstep(BarCount, Del); else _pipstep = PipStep; if(Account.Positions.Count < MaxOrders) switch(GetPositionsSide()) { case 0: if(Symbol.Ask < FindLastPrice(TradeType.Buy) - _pipstep * Symbol.PointSize) { NewVolume = Math.DivRem((int)(FirstLot + FirstLot*Account.Positions.Count), LotStep, out Rem) * LotStep; if(!(NewVolume < LotStep)) Trade.CreateBuyMarketOrder(Symbol, NewVolume); } break; case 1: if(Symbol.Bid > FindLastPrice(TradeType.Sell) + _pipstep * Symbol.PointSize) { NewVolume = Math.DivRem((int)(FirstLot + FirstLot*Account.Positions.Count), LotStep, out Rem) * LotStep; if(!(NewVolume < LotStep)) Trade.CreateSellMarketOrder(Symbol, NewVolume); } break; } } private int GetDynamicPipstep(int CountOfBars, int Del) { int Result; double HighestPrice = 0, LowestPrice = 0; int StartBar = MarketSeries.Close.Count - 2 - CountOfBars; int EndBar = MarketSeries.Close.Count - 2; for(int i = StartBar; i < EndBar; i++) { if(HighestPrice == 0 && LowestPrice == 0) { HighestPrice = MarketSeries.High[i]; LowestPrice = MarketSeries.Low[i]; continue; } if(MarketSeries.High[i] > HighestPrice) HighestPrice = MarketSeries.High[i]; if(MarketSeries.Low[i] < LowestPrice) LowestPrice = MarketSeries.Low[i]; } Result = (int)((HighestPrice - LowestPrice) / Symbol.PointSize / Del); return Result; } private double FindLastPrice(TradeType TypeOfTrade) { double LastPrice = 0; for(int i = 0; i < Account.Positions.Count; i++) { position = Account.Positions[i]; if(TypeOfTrade == TradeType.Buy) if(position.TradeType == TypeOfTrade) { if(LastPrice == 0) { LastPrice = position.EntryPrice; continue; } if(position.EntryPrice < LastPrice) LastPrice = position.EntryPrice; } if(TypeOfTrade == TradeType.Sell) if(position.TradeType == TypeOfTrade) { if(LastPrice == 0) { LastPrice = position.EntryPrice; continue; } if(position.EntryPrice > LastPrice) LastPrice = position.EntryPrice; } } return LastPrice; } private int GetStdIlanSignal() { int Result = -1; int LastBarIndex = MarketSeries.Close.Count - 2; int PrevBarIndex = LastBarIndex - 1; if(MarketSeries.Close[LastBarIndex] > MarketSeries.Open[LastBarIndex]) if(MarketSeries.Close[PrevBarIndex] > MarketSeries.Open[PrevBarIndex]) Result = 0; if(MarketSeries.Close[LastBarIndex] < MarketSeries.Open[LastBarIndex]) if(MarketSeries.Close[PrevBarIndex] < MarketSeries.Open[PrevBarIndex]) Result = 1; return Result; } } }
@damon153058
cAlgo_Fanatic
22 May 2013, 17:41
RE:
thanks... but i must admit im learning the coding from scratch and cant figure out the error
would be great if somebody dont mind to give full coding for the above as start
You can post the error message and we will help you out with the code.
@cAlgo_Fanatic
cAlgo_Fanatic
22 May 2013, 17:43
To combine the above code, place the first in the OnTick event of the second.
@cAlgo_Fanatic
damon153058
22 May 2013, 18:28
RE:
To combine the above code, place the first in the OnTick event of the second.
I still do not know how to combine two kinds of code?
Please help
@damon153058
cAlgo_Fanatic
23 May 2013, 09:23
In cAlgo click on New in the Robots list. A new code file will be created in the text editor with some initial code. You need to copy and paste the code provided in the second post in the OnTick method where it says:
protected override void OnTick() { // Put your core logic here }
Paste the code within the curly brackets {}.
Please see these help pages to get started:
http://help.spotware.com/calgo
http://help.spotware.com/calgo/cbots/create-edit
http://help.spotware.com/calgo/videos
@cAlgo_Fanatic
damon153058
23 May 2013, 10:27
RE:
In cAlgo click on New in the Robots list. A new code file will be created in the text editor with some initial code. You need to copy and paste the code provided in the second post in the OnTick method where it says:
protected override void OnTick() { // Put your core logic here }Paste the code within the curly brackets {}.
Please see these help pages to get started:
http://help.spotware.com/calgo
You misunderstood what I meant
I need to insert in my program, both for
@damon153058
valizario
11 Jun 2013, 20:41
Please help!
Hi. Thanks a lot for this topic!
It really helped me. The robot works very well. It closes multiple positions based on total current 'Unrealized P&L'.
But please help - what command should I add to the code so the robot also cancel all stop orders left???
Thank you
@valizario
cAlgo_Fanatic
12 Jun 2013, 10:05
RE: Please help!
Hi. Thanks a lot for this topic!
It really helped me. The robot works very well. It closes multiple positions based on total current 'Unrealized P&L'.
But please help - what command should I add to the code so the robot also cancel all stop orders left???
Thank you
To delete pending orders you can loop through Account.PendingOrders in a similar way and delete.
foreach (var pendingOrder in Account.PendingOrders) { Trade.DeletePendingOrder(pendingOrder); }
@cAlgo_Fanatic
7023423
09 Aug 2013, 08:41
RE:
cAlgo_Fanatic said:
Yes, given that the currency of your account is in USD. You can calculate the profit of all positions of the account as well as close all positions of the account:
var netProfit = 0.0; foreach (var openedPosition in Account.Positions) { netProfit += openedPosition.NetProfit; } if(netProfit >= 30.0) { foreach (var openedPosition in Account.Positions) { Trade.Close(openedPosition); } }
Hi cAlgo Fanatic,
I saw this conversation and it works good, but due to the commission which will be applied after the close, final netProfit amount becomes less than what I set up.
So how can I solve this problem by applying the commission on the exit?
Thank you for your help in advance.
@7023423
cAlgo_Fanatic
09 Aug 2013, 11:59
RE: RE:
Hi cAlgo Fanatic,I saw this conversation and it works good, but due to the commission which will be applied after the close, final netProfit amount becomes less than what I set up.
So how can I solve this problem by applying the commission on the exit?
Thank you for your help in advance.
Please clarify your question. The net profit is equal to the gross profit minus the commission.
If you like to close the positions on the event that the robot stops you can add the code to the OnStop() method.
@cAlgo_Fanatic
7023423
09 Aug 2013, 19:02
RE: RE: RE:
cAlgo_Fanatic said:
Hi cAlgo Fanatic,I saw this conversation and it works good, but due to the commission which will be applied after the close, final netProfit amount becomes less than what I set up.
So how can I solve this problem by applying the commission on the exit?
Thank you for your help in advance.
Please clarify your question. The net profit is equal to the gross profit minus the commission.
If you like to close the positions on the event that the robot stops you can add the code to the OnStop() method.
I mean for example if(netProfit >= 30.0) if I setup like this, robot close all opened position when total sum of unrealized P&L equal or greater than $30.
so I expected to have $30 net profit, but because of the commission when robot close the position, my actual net profit becomes $30 minus one side commission(closing).
I think unrealized P&L does already deduct the commission when I open the position(one side), but not including the upcoming commission from the closing the trades.
Thank you,
@7023423
cAlgo_Fanatic
13 Aug 2013, 09:21
You need to change the code in the foreach loop to this:
netProfit += openedPosition.NetProfit + openedPosition.Commissions;
@cAlgo_Fanatic
7023423
14 Aug 2013, 12:12
RE:
cAlgo_Fanatic said:
You need to change the code in the foreach loop to this:
netProfit += openedPosition.NetProfit + openedPosition.Commissions;
Hi cAlgo Fanatic,
Thank you for the reply and I changed the code
netProfit += openedPosition.NetProfit; --> netProfit += openedPosition.NetProfit + openedPosition.Commissions;
but then result was even worse than before. If I setup to close all positions when my unrealized P&L equal or greater than $100, my actual net profit after the closing all my positions, it becomes $100 minus my full commission(round trip commission),
Is it because commission is negative number?
It will be great if you can help me again.
Thank you.
@7023423
7023423
15 Aug 2013, 02:21
RE:
cAlgo_Fanatic said:
Could you give an example of what you need?
Hi cAlgo Fanatic,
I want to close all my multiple open positions all together at the same time when my total unrealized P&L meets my profit or stop loss targets.
For example, when I open or have 100k EUR/USD buy, 100k GBP/USD buy, and 100K USD/JPY sell now, I want to close all of my open positions when unrealized P&L from all three positions become either $300 or -$300.
Below is my coding, but below coding is only for the profit target and also when I setup for $300 for example, my net profit after the closing becomes $300 minus one side commissions.
It will be great if you can add the function for the stop loss target and solve the commission issue.
Thank you so much for your help.
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Requests;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC)]
public class AAC : Robot
{
protected override void OnStart()
{
// Put your initialization logic here
}
protected override void OnTick()
{
var netProfit = 0.0;
foreach (var openedPosition in Account.Positions)
{
netProfit += openedPosition.NetProfit;
}
if(netProfit >= 300.0)
{
foreach (var openedPosition in Account.Positions)
{
Trade.Close(openedPosition);
}
}
}
protected override void OnStop()
{
// Put your deinitialization logic here
}
}
}
@7023423
cAlgo_Fanatic
16 Aug 2013, 16:04
( Updated at: 21 Dec 2023, 09:20 )
When the number circled in red, which is equal to the net profit minus the commission (23.16 -15 =11.16) will be greater than 300 or less than -300, then the position will close.
protected override void OnTick() { var netProfit = 0.0; foreach (var openedPosition in Account.Positions) { netProfit += openedPosition.NetProfit + openedPosition.Commissions; } ChartObjects.DrawText("a", netProfit.ToString(), StaticPosition.BottomLeft); if (Math.Abs(netProfit) >= 300.0) { foreach (var openedPosition in Account.Positions) { Trade.Close(openedPosition); } } }
@cAlgo_Fanatic
7023423
22 Aug 2013, 12:04
( Updated at: 21 Dec 2023, 09:20 )
RE:
cAlgo_Fanatic said:
When the number circled in red, which is equal to the net profit minus the commission (23.16 -15 =11.16) will be greater than 300 or less than -300, then the position will close.
protected override void OnTick() { var netProfit = 0.0; foreach (var openedPosition in Account.Positions) { netProfit += openedPosition.NetProfit + openedPosition.Commissions; } ChartObjects.DrawText("a", netProfit.ToString(), StaticPosition.BottomLeft); if (Math.Abs(netProfit) >= 300.0) { foreach (var openedPosition in Account.Positions) { Trade.Close(openedPosition); } } }
Hi cAlgo Support,
Thank you for the reply. This one works perfect.
Just one more question (or request), what if I want to set up different amount for the profit side and stop loss side?
I simply added one more if phrase....if (NetProfit <= -200) but didn't work.
Please help me.
@7023423
tradermatrix
22 Aug 2013, 16:32
( Updated at: 21 Dec 2023, 09:20 )
RE: RE:
coolutm said:
cAlgo_Fanatic said:
When the number circled in red, which is equal to the net profit minus the commission (23.16 -15 =11.16) will be greater than 300 or less than -300, then the position will close.
protected override void OnTick() { var netProfit = 0.0; foreach (var openedPosition in Account.Positions) { netProfit += openedPosition.NetProfit + openedPosition.Commissions; } ChartObjects.DrawText("a", netProfit.ToString(), StaticPosition.BottomLeft); if (Math.Abs(netProfit) >= 300.0) { foreach (var openedPosition in Account.Positions) { Trade.Close(openedPosition); } } }
Hi cAlgo Support,
Thank you for the reply. This one works perfect.
Just one more question (or request), what if I want to set up different amount for the profit side and stop loss side?
I simply added one more if phrase....if (NetProfit <= -200) but didn't work.
Please help me.
{
var netProfit = 0.0;
foreach (var openedPosition in Account.Positions)
{
netProfit += openedPosition.NetProfit + openedPosition.Commissions;
}
ChartObjects.DrawText("a", netProfit.ToString(), StaticPosition.BottomLeft);
if ((Math.Abs(netProfit) >= 200.0) || (Math.Abs(netProfit) <= -200))
{
foreach (var openedPosition in Account.Positions)
{
Trade.Close(openedPosition);
}
}
}
@tradermatrix
tradermatrix
22 Aug 2013, 17:16
excusez moi ,mais il me semble que cette méthode est plus juste:
protected override void OnTick()
{
var netProfit = 0.0;
foreach (var openedPosition in Account.Positions)
{
netProfit += openedPosition.NetProfit + openedPosition.Commissions;
}
ChartObjects.DrawText("a", netProfit.ToString(), StaticPosition.BottomLeft);
{
if (Account.Equity - Account.Balance > 300 || Account.Equity - Account.Balance < - 200)
{
foreach (var position in Account.Positions)
{
Trade.Close(position);
}
}
}
}
}
}
@tradermatrix
atrader
29 Aug 2013, 15:41
( Updated at: 21 Dec 2023, 09:20 )
RE: RE: RE:
tradermatrix said:
coolutm said:
cAlgo_Fanatic said:
When the number circled in red, which is equal to the net profit minus the commission (23.16 -15 =11.16) will be greater than 300 or less than -300, then the position will close.
protected override void OnTick() { var netProfit = 0.0; foreach (var openedPosition in Account.Positions) { netProfit += openedPosition.NetProfit + openedPosition.Commissions; } ChartObjects.DrawText("a", netProfit.ToString(), StaticPosition.BottomLeft); if (Math.Abs(netProfit) >= 300.0) { foreach (var openedPosition in Account.Positions) { Trade.Close(openedPosition); } } }
Hi cAlgo Support,
Thank you for the reply. This one works perfect.
Just one more question (or request), what if I want to set up different amount for the profit side and stop loss side?
I simply added one more if phrase....if (NetProfit <= -200) but didn't work.
Please help me.
{
var netProfit = 0.0;
foreach (var openedPosition in Account.Positions)
{
netProfit += openedPosition.NetProfit + openedPosition.Commissions;
}
ChartObjects.DrawText("a", netProfit.ToString(), StaticPosition.BottomLeft);
if ((Math.Abs(netProfit) >= 200.0) || (Math.Abs(netProfit) <= -200))
{
foreach (var openedPosition in Account.Positions)
{
Trade.Close(openedPosition);
}
}
}
Math.Abs() means the absolute or positive value. Therefore the second part of the condition
if ((Math.Abs(netProfit) >= 200.0) || (Math.Abs(netProfit) <= -200))
will always be false.
@atrader
cAlgo_Fanatic
29 Aug 2013, 15:52
RE: RE:
coolutm said:
Support,
Thank you for the reply. This one works perfect.
Just one more question (or request), what if I want to set up different amount for the profit side and stop loss side?
I simply added one more if phrase....if (NetProfit <= -200) but didn't work.
Please help me.
if ( netProfit >= 300.0) || netProfit <= -200 )
@cAlgo_Fanatic
renerpz
18 Sep 2014, 23:06
RE: Please help!
hello friend can you send me the code already modify i ve been having problems with the errors ill appreciate the help
Hi. Thanks a lot for this topic!
It really helped me. The robot works very well. It closes multiple positions based on total current 'Unrealized P&L'.
But please help - what command should I add to the code so the robot also cancel all stop orders left???
Thank you
@renerpz
cAlgo_Fanatic
09 May 2013, 17:04
Yes, given that the currency of your account is in USD. You can calculate the profit of all positions of the account as well as close all positions of the account:
@cAlgo_Fanatic