Untitled
using System; using System.Linq; using System.Reflection; using cAlgo.API; using cAlgo.API.Collections; using cAlgo.API.Indicators; using cAlgo.API.Internals; namespace cAlgo.Robots { [Robot(AccessRights = AccessRights.None, AddIndicators = true, TimeZone= TimeZones.EasternStandardTime)] public class Rush1030am : Robot { [Parameter("Look Back Hour", Group = "Box", DefaultValue = 10)] public int HourLookBack { get; set; } [Parameter("Look Back Minute", Group = "Box", DefaultValue = 30)] public int MinuteLookBack { get; set; } [Parameter("Hour", Group = "Opening Range", DefaultValue = 9)] public int OpeningRangeHour { get; set; } [Parameter("Minute", Group = "Opening Range", DefaultValue = 30)] public int OpeningRangeMinute { get; set; } [Parameter("Pre Day Hour", Group = "Opening Range", DefaultValue = 16)] public int PreDayHour { get; set; } [Parameter("Pre Day Minute", Group = "Opening Range", DefaultValue = 13)] public int PreDayMinute { get; set; } [Parameter("Min Deep Pips 10.30 ", Group = "Bias", DefaultValue = 700)] public int MinDeepPipsBias { get; set; } private double OpeningRangeHigh = double.NaN, OpeningRangeLow = double.NaN; private bool IsFormingOpeningRange = false; private double OpenPrice1030AM = double.NaN; private string BiasSide = "none"; private string swingName = "none"; private double LastSwingHigh = double.NaN, LastSwingLow = double.NaN, LastSwingHighPointOpenPrice = double.NaN, LastSwingLowPointOpenPrice = double.NaN, LastSwingHighPointClosePrice = double.NaN, LastSwingLowPointClosePrice = double.NaN; private double StoplossPip = 150; private double RR = 3; private double MaxHoldingPosition = 1; private bool OffTrade = false; // BIAS Dựa vào vị trí của OpeningRange Gap vs chùm nến từ (10h - 10h29) 30 nến , 80% nến nằm xa Opening Range Gap thì giá có xác suất hút về // 10 - 10h29 --> vị trí box phải xa hơn OpenRange gap 50% GAP // 10h30 - 11h29 --> tìm Structure shift của Swing(5) // Nếu box nằm dưới Opening Range Gap thì buy // Nếu box nằm trên Opening Range Gap thì sell // Giá break close Swing high // RR = 3 // SL = 15pip // Mở Bot lúc 10h để OnBar update Swing High Low // 17/12 : 10h30 Structshift luôn swing high protected override void OnStart() { } protected override void OnBar() { // Handle price updates here DateTime lastBarTime = Bars.OpenTimes.Last(1); UpdateSwingPoints(); // Period = 5 Chart.DrawStaticText("dashboard", $"Now ... {lastBarTime.Hour} : {lastBarTime.Minute} \n" + $"BiasSide: {BiasSide} \n" + $"Opening Range: H {OpeningRangeHigh} & L {OpeningRangeLow} \n" + $"IsSwingHigh: {LastSwingHigh} ... Open = {LastSwingHighPointOpenPrice} \n" + $"IsSwingLow: {LastSwingLow} ... Open = {LastSwingLowPointOpenPrice} \n" + $".... \n" , VerticalAlignment.Bottom, HorizontalAlignment.Left, API.Color.Yellow); if (lastBarTime.Hour == HourLookBack && lastBarTime.Minute == MinuteLookBack) { (OpeningRangeHigh, OpeningRangeLow) = GetOpeningRangeGap(); IsFormingOpeningRange = true; OpenPrice1030AM = Bars.OpenPrices.Last(1); } if (!IsFormingOpeningRange) return; if (CountExecutingPositions() + CountPendingOrders() >= MaxHoldingPosition) return; double DeepBiasPips = double.NaN; if (OpenPrice1030AM < OpeningRangeLow) { DeepBiasPips = this.convertToPips(OpeningRangeLow - OpenPrice1030AM); if (DeepBiasPips >= MinDeepPipsBias) { BiasSide = "bottom"; } } if (OpenPrice1030AM > OpeningRangeHigh) { DeepBiasPips = this.convertToPips(OpenPrice1030AM - OpeningRangeHigh); if (DeepBiasPips >= MinDeepPipsBias) { BiasSide = "top"; // Find } } if (double.IsNaN(DeepBiasPips) || DeepBiasPips < MinDeepPipsBias) return; if (OffTrade) return; if (BiasSide == "top" && isStructureShiftByClosePrice("breakLow")) { // BUY LIMIT AT Open of SWING HIGH PlaceLimitOrder( TradeType.Sell, SymbolName, Symbol.QuantityToVolumeInUnits(1), LastSwingLowPointClosePrice, "order-buy-" + Bars.Count, StoplossPip, StoplossPip * RR ); OffTrade = true; } if (BiasSide == "bottom" && isStructureShiftByClosePrice("breakHigh")) { // BUY LIMIT AT Open of SWING HIGH PlaceLimitOrder( TradeType.Buy, SymbolName, Symbol.QuantityToVolumeInUnits(1), LastSwingHighPointClosePrice, "order-sell-" + Bars.Count, StoplossPip, StoplossPip * RR ); OffTrade = true; } } protected override void OnStop() { // Handle cBot stop here } private double GetPreviousDayClosePrice(int index) { // Find the close price at 16:14 PM on the previous day DateTime previousDayTargetTime = MarketSeries.OpenTime[index].AddHours(PreDayHour).AddMinutes(PreDayMinute).AddDays(-1); Print("previous date ", previousDayTargetTime); for (int i = 0; i < MarketSeries.OpenTime.Count; i++) { if (MarketSeries.OpenTime[i] == previousDayTargetTime) return MarketSeries.Close[i]; } return double.NaN; // Return NaN if not found } public (double highestHigh, double lowestLow) GetOpeningRangeGap() { double preDayPrice = GetPreviousDayClosePrice(Bars.Count - 1); double openingPrice = 0; for (int ii = 1; ii < 65; ii++) { if (Bars.OpenTimes.Last(ii).Hour == OpeningRangeHour && Bars.OpenTimes.Last(ii).Minute == OpeningRangeMinute) { openingPrice = Bars.OpenPrices.Last(ii); break; } } return (Math.Max(openingPrice, preDayPrice), Math.Min(openingPrice, preDayPrice)); } private double convertToPips(double priceDif) { return Math.Round(Math.Abs(priceDif / Symbol.PipSize), 1); } private void UpdateSwingPoints() { UpdateSwingHigh(); UpdateSwingLow(); } // top | bottom private bool isStructureShiftByClosePrice(string type = "breakHigh") { if (type == "breakHigh" && Bars.ClosePrices.Last(1) > LastSwingHigh) { return true; } if (type == "breakLow" && Bars.ClosePrices.Last(1) < LastSwingLow) { return true; } return false; } private void UpdateSwingHigh() { bool checker = Bars.HighPrices.Last(3) > Math.Max(Bars.HighPrices.Last(2), Bars.HighPrices.Last(1)); checker = checker && Bars.HighPrices.Last(3) > Math.Max(Bars.HighPrices.Last(4), Bars.HighPrices.Last(5)); if(checker) { LastSwingHigh = Bars.HighPrices.Last(3); // Update the most recent Swing High LastSwingHighPointOpenPrice = Bars.OpenPrices.Last(3); LastSwingHighPointClosePrice = Bars.ClosePrices.Last(3); } } private void UpdateSwingLow() { bool checker = Bars.LowPrices.Last(3) < Math.Min(Bars.LowPrices.Last(2), Bars.LowPrices.Last(1)); checker = checker && Bars.LowPrices.Last(3) < Math.Min(Bars.LowPrices.Last(4), Bars.LowPrices.Last(5)); if (checker) { LastSwingLow = Bars.LowPrices.Last(3); // Update the most recent Swing High LastSwingLowPointOpenPrice = Bars.OpenPrices.Last(3); LastSwingLowPointClosePrice = Bars.ClosePrices.Last(3); } } private int CountExecutingPositions() { return Positions.Count(position => (position.TradeType == TradeType.Buy || position.TradeType == TradeType.Sell) && Symbol.Name == position.SymbolName); } private int CountPendingOrders() { return PendingOrders.Count(pod => Symbol.Name == pod.SymbolName); } } }
Leave a Comment