Topics
Replies
Forex19
19 Feb 2014, 20:26
( Updated at: 21 Dec 2023, 09:20 )
RE:
Spotware said:
Please look at the following example:
using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC)] public class Sample : Robot { const string Label = "My unique label"; protected override void OnTick() { var position = Positions.Find(Label); if (position == null) { //if there is no position with my label ExecuteMarketOrder(TradeType.Buy, Symbol, Symbol.VolumeMin, Label); } else { //if position exists //some actions with position object } } } }You need to specify the Label in trade operation and then find your position with Positions.Find method
Hi,
I tried to modify the code as suggested but the result is always this error:
The startup code that I tried to change for both cBots is similar to this:
using System; using cAlgo.API; namespace cAlgo.Robots { [Robot("RF")] public class RF : Robot { [Parameter(DefaultValue = 3000, MinValue = 1000)] 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 = 3000; protected override void OnStart() { RF_Label = "RF " + Symbol.Code + " - Diretto"; Positions.Opened += PositionsOnOpened; } protected override void OnTick() { double Bid = Symbol.Bid; double Ask = Symbol.Ask; double Point = Symbol.TickSize; if (Trade.IsExecuting) return; if (Positions.Count > 0 && RobotStopped) return; else RobotStopped = false; if (Positions.Count == 0) SendFirstOrder(FirstLot); else ControlSeries(); foreach (var position in 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) 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) 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: ExecuteMarketOrder(TradeType.Buy, Symbol, OrderVolume, RF_Label); break; case 1: ExecuteMarketOrder(TradeType.Sell, Symbol, OrderVolume, RF_Label); break; } } private void PositionsOnOpened(PositionOpenedEventArgs args) { Position position = args.Position; string emailBody = string.Format("Position {0} {1} Opened at {2}", position.Volume, position.TradeType, position.EntryPrice); string subject = string.Format("RF P{0}", Positions.Count); Notifications.SendEmail("cAlgoNotice@gmail.com", "forex19@email.it", subject, emailBody); double? StopLossPrice = null; double? TakeProfitPrice = null; if (Positions.Count == 1) { if (position.TradeType == TradeType.Buy) TakeProfitPrice = position.EntryPrice + TakeProfit * Symbol.TickSize; if (position.TradeType == TradeType.Sell) TakeProfitPrice = position.EntryPrice - TakeProfit * Symbol.TickSize; } else switch (GetPositionsSide()) { case 0: TakeProfitPrice = GetAveragePrice(TradeType.Buy) + TakeProfit * Symbol.TickSize; break; case 1: TakeProfitPrice = GetAveragePrice(TradeType.Sell) - TakeProfit * Symbol.TickSize; break; } for (int i = 0; i < Positions.Count; i++) { position = Positions[i]; if (StopLossPrice != null || TakeProfitPrice != null) ModifyPosition(position, position.StopLoss, TakeProfitPrice); } } protected override void OnPositionOpened(Position openedPosition) { } private double GetAveragePrice(TradeType TypeOfTrade) { double Result = Symbol.Bid; double AveragePrice = 0; long Count = 0; for (int i = 0; i < Positions.Count; i++) { position = 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 < Positions.Count; i++) { if (Positions[i].TradeType == TradeType.Buy) BuySide++; if (Positions[i].TradeType == TradeType.Sell) SellSide++; } if (BuySide == Positions.Count) Result = 0; if (SellSide == 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 (Positions.Count < MaxOrders) switch (GetPositionsSide()) { case 0: if (Symbol.Ask < FindLastPrice(TradeType.Buy) - _pipstep * Symbol.TickSize) { NewVolume = Math.DivRem((int)(FirstLot + FirstLot * Positions.Count), LotStep, out Rem) * LotStep; if (!(NewVolume < LotStep)) ExecuteMarketOrder(TradeType.Buy, Symbol, NewVolume, RF_Label); } break; case 1: if (Symbol.Bid > FindLastPrice(TradeType.Sell) + _pipstep * Symbol.TickSize) { NewVolume = Math.DivRem((int)(FirstLot + FirstLot * Positions.Count), LotStep, out Rem) * LotStep; if (!(NewVolume < LotStep)) ExecuteMarketOrder(TradeType.Sell, Symbol, NewVolume, RF_Label); } 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.TickSize / Del); return Result; } private double FindLastPrice(TradeType TypeOfTrade) { double LastPrice = 0; for (int i = 0; i < Positions.Count; i++) { position = 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; } } }
Can you tell me more about how and where to edit the code?
Thanks
@Forex19
Forex19
12 Feb 2014, 23:46
RE:
Spotware said:
The problem is that you use obsolete OnPositionOpened method with new ExecuteMarketOrder method. OnPositionOpened method works only if you create position using old trading API.
Instead of using OnPositionOpened method you need to subscribe to Positions.Opened event. But please keep in mind that it will be raised for all positions:
I modified the code and used PositionOnOpened, and it seems to work properly.
Thanks.
@Forex19
Forex19
10 Feb 2014, 13:47
RE:
Spotware said:
There are 4 places with Trade.Create...Order. Did you replace all? Please attach code of your cBot.
Here is the modified code
The barred lines are the ones that I have changed
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; private string RF_Label; protected override void OnStart() { RF_Label = "RF " + Symbol.Code; } 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: ExecuteMarketOrder(TradeType.Buy, Symbol, OrderVolume, RF_Label); //Trade.CreateBuyMarketOrder(Symbol, OrderVolume);break; case 1: ExecuteMarketOrder(TradeType.Sell, Symbol, OrderVolume, RF_Label); //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)) ExecuteMarketOrder(TradeType.Buy, Symbol, NewVolume, RF_Label); //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)) ExecuteMarketOrder(TradeType.Sell, Symbol, NewVolume, RF_Label); //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; } } }
@Forex19
Forex19
28 Jan 2014, 17:57
RE:
Spotware said:
private void PositionsOnOpened(PositionOpenedEventArgs args) { Position position = args.Position; string emailBody = string.Format("Position {0} {1} Opened at {2}",position.Volume, position.TradeType, position.EntryPrice); string subject = string.Format("RF P{0}", Positions.Count); Notifications.SendEmail("from@somewhere.com", "to@somewhere.com", subject, emailBody); }
Code added, so good.
It should however replace
string body
with
string emailBody
Thanks, good job.
@Forex19
Forex19
26 Jan 2014, 00:20
RE:
atrader said:
Hi,
Hope this helps: /algos/robots/show/391
Hi,
thanks for signaling, I had missed this.
I wanted to ask. if you could change the code so as to do manage mutiple instanced, so you can set different parameter values for the different currency pairs.
@Forex19
Forex19
27 Oct 2013, 13:19
RE:
facestockvn said:
I understand, but I want to be perfect cTrader. I want to have full on cTrader indicator as MT4 indicator. Because I want all my customers only user cTrader to trading. Not necessarily to use MT4 for analysis and then trading with cTrader.
I asked you the file. Mq4 because you can start with that code to convert cAlgo.
@Forex19
Forex19
27 Oct 2013, 12:53
RE:
facestockvn said:
Yes, I have. You can download here http://www.faceforex.vn/threads/kwan-zigzag-beta-mbfx-timing-indicators-chi-bao-xu-huong-thi-thuong.1230/
I wanted to say the file MBFX Timing.mq4
The file MBFX Timing.ex4, is already completed and it's not needed for the conversion in cAlgo
@Forex19
Forex19
22 Aug 2013, 18:07
( Updated at: 21 Dec 2023, 09:20 )
RE:
I show any screenshots for a better explain what I think is not exact and what could be implemented to improve the backtesting:
If I understand correctly, the graph of the equity and the balance is derived for points.
Given this. the graph of the equity and the balance does not allow us to observe the real operating performance.
I show another screenshot to another situation:
As you can see in the graph and info events are not shown clearly.
The two graphs have reported the same operation but in the second graph I increased the number of orders to overcome the negative equitiy shown in the case of the first graph.
In the second graph is not seen that from the operation 4 (where the equity starts to decrease) to the operation 18 (where the equity returns positive) the trend of the equity is very variable from negative to positive.
cAlgo_Development said:
I have read other threads about it, and your will to improve your backtesting to handle this situations.
If you keep losing positions, equity goes down. We consider this as a correct behavior. How would you suggest to handle it?
I think it would be important to have more information and settings for the equity.
I'd suggest increasing the options during the backtesting:
- In backtesting setting, be able to choose equity can be negative or not during simulation. Providing that the backtesting stops with equity <0 or even better less than some value that the user can sets.
- In backtesting setting, be able to choose whether to set the value of the margin call and the stop out level.
- On the "Report" to have an indication of the minimum and maximum value of equity and when it was reached.
I hope these tips can help you improve cAlgo which I think is very good but can be improved.
@Forex19
Forex19
21 Aug 2013, 15:22
RE: RE: RE:
Ti ho scritto, dalla mia email.
A presto, Roberto.
vins said:
Forex19 said: mandami una e-mail a questo indirizzo provvisoria162@libero.it poi ti rispondo dalla mia casella originale
ciao, Vincenzo
vins said:
hi to all people
I would like to know if exits already a robot script that runs the trailing stops (or create new one) immediately after a stop order (or a limit order) is activated
this is the reason of my request: in the evening, from my home, I set all trades using the stop order system; often, the next day I do not have any chance to ceck the status of the trades; it would be very comfortable set in advance the trailing stop with a robot
in my opinion are enought these fields: price of the stop order (buy entry or sell entry), trigger when gaining, trail for
someone thinks is it possible ?
thanks in adavance
Vincenzo from italy
Ciao Vincenzo,
finalmente un utente italiano. Hai una email o altro con cui poterci confrontare in generale più velocemente su CAlgo?
Bye, Roberto.
@Forex19
Forex19
20 Aug 2013, 18:58
RE:
vins said:
hi to all people
I would like to know if exits already a robot script that runs the trailing stops (or create new one) immediately after a stop order (or a limit order) is activated
this is the reason of my request: in the evening, from my home, I set all trades using the stop order system; often, the next day I do not have any chance to ceck the status of the trades; it would be very comfortable set in advance the trailing stop with a robot
in my opinion are enought these fields: price of the stop order (buy entry or sell entry), trigger when gaining, trail for
someone thinks is it possible ?
thanks in adavance
Vincenzo from italy
Ciao Vincenzo,
finalmente un utente italiano. Hai una email o altro con cui poterci confrontare in generale più velocemente su CAlgo?
Bye, Roberto.
@Forex19
Forex19
06 Aug 2013, 17:55
RE:
cAlgo_Fanatic said:
The parameter would be a type double property:
[Parameter] public double Price { get; set; }Then use this parameter in the methods that create the limit order requests instead of the calculation of the price based on the TakeProfitPips.
var request = new LimitOrderRequest(tradeType, Volume, Price)
It is recomended that you validate this input.
I changed that and it seems to work:
private void RequestLimitSell()
{
double targetPrice = Price;
// double targetPrice = Symbol.Bid + TargetPricePips * Symbol.PipSize; (old line)
var request = new LimitOrderRequest(TradeType.Sell, Volume, Price)
// var request = new LimitOrderRequest(TradeType.Sell, Volume, targetPrice) (old line)
and
private void RequestLimitBuy()
{
double targetPrice = Price;
// double targetPrice = Symbol.Ask - TargetPricePips * Symbol.PipSize; (old line)
var request = new LimitOrderRequest(TradeType.Buy, Volume, Price)
// var request = new LimitOrderRequest(TradeType.Buy, Volume, targetPrice) (old line)
@Forex19
Forex19
10 Jul 2013, 00:03
RE:
You can print the API Reference. There is a button on the top right.
The button on the top right, can print only the displayed page.
I would like to print all the API reference with one step, avoiding the very uncomfortable printing item by item.
I suppose you have a more comfortable to read and consult guide.
@Forex19
Forex19
20 Feb 2014, 11:31
RE:
Spotware said:
I tried your suggestion to filter my position by Label but the problem persists (as shown on the image that I previously uploaded).
I also tried to filter the positions in other parts of the code but does not change the result always the same error.
In addition to filtering the positions I have to edit anything else?
Where is the problem?
@Forex19