Untitled
unknown
plain_text
a year ago
7.2 kB
3
Indexable
Never
using cAlgo.API; using cAlgo.API.Indicators; using System; using System.Collections.Generic; namespace BTCUSDbot { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class BTCUSDbot : Robot { private TimeFrame higherTimeframe = TimeFrame.Weekly; private double higherTimeframeThreshold = 0.5; private double lotSize; private MovingAverage fastMA; private MovingAverage slowMA; private DateTime lastBarTime; private Color regularStopLossColor = Color.Red; private Color trailingStopLossColor = Color.Blue; private Color currentStopLossColor; private double trailingStopDistanceInPips = 10000; private double minProfitForTrailing = 10000; // Minimum profit in pips before trailing stop becomes active private RelativeStrengthIndex rsi; private double _volumeInUnits; private AverageDirectionalMovementIndexRating _averageDirectionalMovementIndexRating; [Parameter("Volume (Lots)", DefaultValue = 0.01)] public double VolumeInLots { get; set; } [Parameter("Label", DefaultValue = "Sample")] public string Label { get; set; } private int lookbackPeriod = 100; double lowestLow; double highestHigh; bool calculateHighestHigh = false; public Position[] BotPositions { get { return Positions.FindAll(Label); } } protected override void OnStart() { int fastMAPeriod = 50; int slowMAPeriod = 200; int rsiPeriod = 14; rsi = Indicators.RelativeStrengthIndex(Bars.ClosePrices, rsiPeriod); fastMA = Indicators.MovingAverage(Bars.ClosePrices, fastMAPeriod, MovingAverageType.Simple); slowMA = Indicators.MovingAverage(Bars.ClosePrices, slowMAPeriod, MovingAverageType.Simple); lastBarTime = Bars.OpenTimes.LastValue; _volumeInUnits = Symbol.QuantityToVolumeInUnits(VolumeInLots); _averageDirectionalMovementIndexRating = Indicators.AverageDirectionalMovementIndexRating(25); lowestLow = MarketSeries.Low.Minimum(lookbackPeriod); highestHigh = MarketSeries.High.Maximum(lookbackPeriod); } protected override void OnBar() { if(calculateHighestHigh == true) { highestHigh = MarketSeries.High.Maximum(lookbackPeriod); calculateHighestHigh = false; } if(Symbol.Bid < lowestLow){ highestHigh = lowestLow; lowestLow = MarketSeries.Low.Minimum(lookbackPeriod); Chart.DrawHorizontalLine("resistance line", highestHigh, Color.Gold, 1, LineStyle.LinesDots); Chart.DrawHorizontalLine("support line", lowestLow, Color.White, 1, LineStyle.LinesDots); } if (Bars.OpenTimes.LastValue > lastBarTime) { lastBarTime = Bars.OpenTimes.LastValue; int index = Bars.ClosePrices.Count - 2; // Index of the last closed bar bool isHigherTimeframeUptrend = IsHigherTimeframeUptrend(); foreach (var position in Positions) { double unrealizedProfitInPips = position.Pips; if (unrealizedProfitInPips >= minProfitForTrailing) { string lineName = $"StopLossLine_{position.Id}"; double trailingStopPrice = Symbol.Bid - trailingStopDistanceInPips * Symbol.PipSize; ModifyPosition(position, trailingStopPrice, position.TakeProfit); currentStopLossColor = trailingStopLossColor; Chart.RemoveObject(lineName);//for sl/tp lines Chart.RemoveAllObjects();//for support/resistance // Draw Stop Loss Line if it exists if (position.StopLoss.HasValue) { double stopLossPrice = position.StopLoss.Value; Chart.DrawHorizontalLine(lineName, stopLossPrice, currentStopLossColor, 1, LineStyle.Solid); } } if(!isHigherTimeframeUptrend && Positions.Count > 0) { ClosePosition(position); Chart.RemoveAllObjects(); } } if(Symbol.Bid < highestHigh) Chart.DrawHorizontalLine("support line", lowestLow, Color.White, 1, LineStyle.LinesDots); Chart.DrawHorizontalLine("resistance line", highestHigh, Color.Gold, 1, LineStyle.LinesDots); if(Symbol.Bid > highestHigh && fastMA.Result.HasCrossedAbove(slowMA.Result, index)&& isHigherTimeframeUptrend) { ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.NormalizeVolumeInUnits(Symbol.LotSize), "Buy Order", 20000, 20000, null ); lowestLow = highestHigh; calculateHighestHigh = true; } } } private void ClosePosition(TradeResult position) { ClosePosition(position); } private void ClosePositions(TradeType tradeType) { foreach (var position in BotPositions) { if (position.TradeType != tradeType) continue; ClosePosition(position); } } private bool IsHigherTimeframeUptrend() { // Calculate moving averages on the higher timeframe double[] higherTimeframeFastMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, higherTimeframe, 50); double[] higherTimeframeSlowMASeries = CalculateSimpleMovingAverage(Bars.ClosePrices, higherTimeframe, 200); int lastIndex = Bars.ClosePrices.Count - 1; // Check if the slow MA on higher timeframe is below the fast MA, indicating a potential downtrend return higherTimeframeSlowMASeries[lastIndex] < higherTimeframeFastMASeries[lastIndex]; } private double[] CalculateSimpleMovingAverage(DataSeries source, TimeFrame timeframe, int period) { double[] smaValues = new double[source.Count]; for (int i = 0; i < source.Count; i++) { if (i >= period - 1) { double sum = 0; for (int j = i - period + 1; j <= i; j++) { sum += source[j]; } smaValues[i] = sum / period; } else { smaValues[i] = source[i]; } } return smaValues; } } }