adding a take profit parameter
adding a take profit parameter
12 Feb 2019, 20:20
Hi guys,
Appreciate if anyone could help with adding a parameter for Take Profit in pips. I tried to learn developing it but actually couldn't.
This is a free cbot available for breakouts.
//+------------------------------------------------------------------+ //| Smart Kestrel.cBot | //| Version 7.4 | //| Copyright 2016, MD SAIF. | //| https://www.facebook.com/cls.fx | //+------------------------------------------------------------------+ using System; using System.Linq; using cAlgo.API; using cAlgo.API.Internals; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class HL : Robot { [Parameter("Safety Limit", DefaultValue = 0.0)] public double SafetyLimit { get; set; } [Parameter("Max Spread", DefaultValue = 3.0)] public double MaxSpread { get; set; } [Parameter("Risk Per Trade", DefaultValue = 0.0)] public double RiskPerTrade { get; set; } [Parameter("Lot Size", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)] public double LotSize { get; set; } [Parameter("Bars Count", DefaultValue = 12, MinValue = 1)] public int BarsCount { get; set; } [Parameter("Hour To Hour", DefaultValue = false)] public bool HourToHour { get; set; } [Parameter("Start Hour", DefaultValue = 8, MaxValue = 23)] public int StartHour { get; set; } [Parameter("Stop Hour", DefaultValue = 18, MaxValue = 23)] public int StopHour { get; set; } [Parameter("Primary SL", DefaultValue = 20.0)] public double PrimarySL { get; set; } [Parameter("Reversal SL", DefaultValue = true)] public bool ReversalSL { get; set; } [Parameter("Reversal Trailing", DefaultValue = true)] public bool ReversalTrailing { get; set; } [Parameter("Calculate By Pip", DefaultValue = true)] public bool CalculateByPip { get; set; } private string Label = "kestrel"; private bool st_45 = true; private double highest = 0.0; private double lowest = 0.0; private double spread = 0.0; private double pnt_3; private string stop_case = ""; private bool c_hour = true; private double primary_sl = 0.0; private bool safety_limit; //+------------------------------------------------------------------+ //| cBot initialization function | //+------------------------------------------------------------------+ protected override void OnStart() { if (CalculateByPip) { pnt_3 = Symbol.PipSize; primary_sl = PrimarySL; } else { pnt_3 = Symbol.TickSize; if (Symbol.Digits % 2 == 1) primary_sl = Math.Round(PrimarySL / 10.0, 1); else primary_sl = PrimarySL; } } //+------------------------------------------------------------------+ //| cBot tick function | //+------------------------------------------------------------------+ protected override void OnTick() { spread = Sz(Symbol.Ask, Symbol.Bid); safety_limit = Account.Balance > SafetyLimit && Account.Equity > SafetyLimit; RobotEngine(); c_hour = GetTradingHour(); if (spread <= MaxSpread && c_hour && st_45 && safety_limit) { var AllPos = Positions.FindAll(Label, Symbol); if (AllPos.Length == 0) SendOrder(); } var BuyPos = Positions.Find(Label, Symbol, TradeType.Buy); if (BuyPos != null) { if (PrimarySL > 0.0) BuyManager(2); if (ReversalSL || ReversalTrailing) BuyManager(3); } var SellPos = Positions.Find(Label, Symbol, TradeType.Sell); if (SellPos != null) { if (PrimarySL > 0.0) SellManager(2); if (ReversalSL || ReversalTrailing) SellManager(3); } string ld_10 = ChartComment(); ChartObjects.DrawText("pan", ld_10, StaticPosition.TopLeft, Colors.DeepPink); } //+------------------------------------------------------------------+ //| cBot Error Function | //+------------------------------------------------------------------+ protected override void OnError(Error error) { if (error.Code == ErrorCode.NoMoney) { Print("Order opening stopped because: not enough money"); stop_case = "Not enough money"; st_45 = false; } } //+------------------------------------------------------------------+ //| cBot deinitialization function | //+------------------------------------------------------------------+ protected override void OnStop() { ChartObjects.RemoveAllObjects(); } //+------------------------------------------------------------------+ //| Setup highest and lowest price of counted bars | //+------------------------------------------------------------------+ private void RobotEngine() { if (MarketSeries.Close.Count - 5 > BarsCount) { highest = MarketSeries.High.Maximum(BarsCount); lowest = MarketSeries.Low.Minimum(BarsCount); ChartObjects.DrawLine("hln", MarketSeries.OpenTime.Last(BarsCount), highest, MarketSeries.OpenTime.LastValue, highest, Colors.DeepPink, 1, LineStyle.Solid); ChartObjects.DrawLine("lln", MarketSeries.OpenTime.Last(BarsCount), lowest, MarketSeries.OpenTime.LastValue, lowest, Colors.DeepPink, 1, LineStyle.Solid); } else Print("Not enough bars loaded for bar_count function"); } //+------------------------------------------------------------------+ //| Trade setup function | //+------------------------------------------------------------------+ private void SendOrder() { bool sell_eng = lowest > 0.0 && Symbol.Bid <= lowest; bool buy_eng = highest > 0.0 && Symbol.Bid >= highest; if (sell_eng) { if (!OrderSend(TradeType.Sell, primary_sl).IsSuccessful) Print("Sell opening error at: ", Symbol.Bid, ", ", LastResult.Error); } else if (buy_eng) { if (!OrderSend(TradeType.Buy, primary_sl).IsSuccessful) Print("Buy opening error at: ", Symbol.Ask, ", ", LastResult.Error); } } //+------------------------------------------------------------------+ //| Order send command | //+------------------------------------------------------------------+ private TradeResult OrderSend(TradeType type, double sl) { long ivol = VolumeSetup(); return (ExecuteMarketOrder(type, Symbol, ivol, Label, sl, 0)); } //+------------------------------------------------------------------+ //| SLTP management of buy positions | //+------------------------------------------------------------------+ private void BuyManager(int id_m) { foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == TradeType.Buy) { switch (id_m) { case 2: { double li_16 = Nd(position.EntryPrice - PrimarySL * pnt_3); if (Symbol.Bid > li_16) { if (position.StopLoss < li_16 || position.StopLoss == null) { if (!ModifyPosition(position, li_16, position.TakeProfit).IsSuccessful) Print("Buy 'Primary SL' error at: ", li_16, ", ", LastResult.Error); } } break; } case 3: { double li_16 = Nd(lowest); if (Symbol.Bid > li_16) { if (position.StopLoss < li_16 || position.StopLoss == null) { if (!ModifyPosition(position, li_16, position.TakeProfit).IsSuccessful) Print("Buy 'Reversal SL/Reversal Trailing' error at: ", li_16, ", ", LastResult.Error); } } break; } } } } } } //+------------------------------------------------------------------+ //| SLTP management of sell positions | //+------------------------------------------------------------------+ private void SellManager(int id_m) { foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == TradeType.Sell) { switch (id_m) { case 2: { double li_16 = Nd(position.EntryPrice + PrimarySL * pnt_3); if (Symbol.Ask < li_16) { if (position.StopLoss > li_16 || position.StopLoss == null) { if (!ModifyPosition(position, li_16, position.TakeProfit).IsSuccessful) Print("Sell 'Primary SL' error at: ", li_16, ", ", LastResult.Error); } } break; } case 3: { double li_16 = Nd(highest); if (Symbol.Ask < li_16) { if (position.StopLoss > li_16 || position.StopLoss == null) { if (!ModifyPosition(position, li_16, position.TakeProfit).IsSuccessful) Print("Sell 'Reversal SL/Reversal Trailing' error at: ", li_16, ", ", LastResult.Error); } } break; } } } } } } //+------------------------------------------------------------------+ //| Volume setup function | //+------------------------------------------------------------------+ private long VolumeSetup() { long Lq_52 = Symbol.NormalizeVolume(Symbol.QuantityToVolume(LotSize), RoundingMode.ToNearest); if (RiskPerTrade > 0.0 && PrimarySL > 0.0) { double minb = Nd(Symbol.Bid - PrimarySL * pnt_3); double sl = Math.Round(Symbol.Bid / Symbol.TickSize) - Math.Round(minb / Symbol.TickSize); double TickValue = Symbol.TickValue; double tick_lot = RiskPerTrade / (sl * TickValue); Lq_52 = Symbol.NormalizeVolume(tick_lot, RoundingMode.ToNearest); } Lq_52 = Math.Max(Lq_52, Symbol.VolumeMin); Lq_52 = Math.Min(Lq_52, Symbol.VolumeMax); return (Lq_52); } //+------------------------------------------------------------------+ //| Get Trading hour | //+------------------------------------------------------------------+ private bool GetTradingHour() { bool h_res = true; if (HourToHour) { if (StartHour != StopHour) { if ((StopHour > StartHour && Time.Hour >= StartHour && Time.Hour < StopHour) || (StartHour > StopHour && (Time.Hour >= StartHour || Time.Hour < StopHour))) h_res = true; else h_res = false; } else { stop_case = "Start-hour and stop-hour must be different value\n"; st_45 = false; h_res = false; } } return (h_res); } //+------------------------------------------------------------------+ //| Normalize broker digits | //+------------------------------------------------------------------+ private double Nd(double par_a) { return (Math.Round(par_a, Symbol.Digits)); } //+------------------------------------------------------------------+ //| Size adjustment function | //+------------------------------------------------------------------+ double Sz(double ad_12, double ad_20) { return (Math.Round(ad_12 / pnt_3) - Math.Round(ad_20 / pnt_3)); } //+------------------------------------------------------------------+ //| Comments of chart | //+------------------------------------------------------------------+ private string ChartComment() { string ch_25 = "\nSMART KESTREL\nwww.fb.com/cls.fx\n"; if (!safety_limit) ch_25 = ch_25 + "Safety-limit exceeded\n"; if (spread > MaxSpread) ch_25 = ch_25 + "Max-spread exceeded\n"; if (!st_45) ch_25 = ch_25 + "Order opening stopped because: " + stop_case + "\n"; if (!c_hour) ch_25 = ch_25 + "Not trading hour\n"; if (RiskPerTrade > 0.0 && PrimarySL == 0.0) ch_25 = ch_25 + "Risk-per-trade will not works if primary-sl is zero\n"; return (ch_25); } //----------------------------THE END--------------------------------+ } }
Replies
Skypips
13 Feb 2019, 17:54
Thank you! You are amazing!
I was also thinking is it possible to add an extra offset of pips instead of counting highest / lowest, let the robot count highest + 5 pips / lowest + 5 pips
Would be grateful for your help.
//+------------------------------------------------------------------+ //| Setup highest and lowest price of counted bars | //+------------------------------------------------------------------+ private void RobotEngine() { if (MarketSeries.Close.Count - 5 > BarsCount) { highest = MarketSeries.High.Maximum(BarsCount); lowest = MarketSeries.Low.Minimum(BarsCount); ChartObjects.DrawLine("hln", MarketSeries.OpenTime.Last(BarsCount), highest, MarketSeries.OpenTime.LastValue, highest, Colors.DeepPink, 1, LineStyle.Solid); ChartObjects.DrawLine("lln", MarketSeries.OpenTime.Last(BarsCount), lowest, MarketSeries.OpenTime.LastValue, lowest, Colors.DeepPink, 1, LineStyle.Solid); } else Print("Not enough bars loaded for bar_count function"); }
@Skypips
Skypips
13 Feb 2019, 18:46
The only problem I am encountering now is that the robot is counting the Highest and Lowest (last bars). I want it to count the Highest and Lowest (last bar - 1 bar)
So, in that case, it will ignore counting the last bar, but it will count the previous range of bars.
Appreciate your help.
@Skypips
PanagiotisCharalampous
14 Feb 2019, 09:18
Hi sky pips,
In this case you should not use Mimimum and Maximum functions but perform the check yourself. See an example below
double maximum = MarketSeries.High.Last(1); for (int i = 2; i < BarCount; i++) { if (MarketSeries.High.Last(i) > maximum) maximum = MarketSeries.High.Last(i); }
Best Regards,
Panagiotis
@PanagiotisCharalampous
Skypips
15 Feb 2019, 15:38
This is such a great support community. Thank you.
I am now thinking of how to adding SMA but still couldnt figure out where
I want to add the condition to open buy trade only if the price is above SMA and open Sell trade only if the price is below SMA.
Appreciate the supoort
@Skypips
PanagiotisCharalampous
13 Feb 2019, 10:05
Hi sky pips,
thank you for posting in our forum. Take profit can be set in the following function
Just replace 0 with the Take Profit you want
Best Regards,
Panagiotis
@PanagiotisCharalampous