One way trend Sell - SmartGrid MA LimitStop Sell trend. For Gold sell trend. What are your ideas for improving the code after testing?
One way trend Sell - SmartGrid MA LimitStop Sell trend. For Gold sell trend. What are your ideas for improving the code after testing?
01 Oct 2019, 21:30
Hi.
Mod SmartGrid:
https://ctrader.com/algos/cbots/show/876
up 07.2020
SellSmartGrid - Only - Sell trend (parametr Buy is ignoring) with MA and one way trend LimitStop Sell H1 H4 - only Sell trend backtest date.
using System; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class oSGMASell : Robot { private bool _accountIsOutOfMoney; private int _openTradeResult; private readonly string Label = "SmartPSell"; private DateTime _lastBuyTradeTime; private DateTime _lastSellTradeTime; [Parameter("Source SMA_AO")] public DataSeries Source_SMA { get; set; } [Parameter("Buy", DefaultValue = false)] public bool Buy { get; set; } [Parameter("Sell", DefaultValue = true)] public bool Sell { get; set; } [Parameter("Pip Step", DefaultValue = 10, MinValue = 5)] public int PipStep { get; set; } [Parameter("First Volume", DefaultValue = 10, MinValue = 10, Step = 10)] public int FirstVolume { get; set; } [Parameter("Volume Exponent", DefaultValue = 1.0, MinValue = 0.1, MaxValue = 5.0)] public double VolumeExponent { get; set; } [Parameter("Max Spread", DefaultValue = 3.0)] public double MaxSpread { get; set; } [Parameter("Average TP", DefaultValue = 300, MinValue = 10)] public int AverageTakeProfit { get; set; } [Parameter("Stop Loss", DefaultValue = 0)] public int StopLoss { get; set; } private double CurrentSpread { get { return (Symbol.Ask - Symbol.Bid) / Symbol.PipSize; } } private SimpleMovingAverage _SMA_slow; private SimpleMovingAverage _SMA_Fast; protected override void OnStart() { } protected override void OnTick() { _SMA_slow = Indicators.SimpleMovingAverage(Source_SMA, 200); _SMA_Fast = Indicators.SimpleMovingAverage(Source_SMA, 50); if (_SMA_slow.Result.LastValue > _SMA_Fast.Result.LastValue && _SMA_slow.Result.LastValue > Symbol.Bid) { Buy = false; Sell = true; ChartObjects.DrawText("Sell", ("Vender"), StaticPosition.TopLeft, Colors.AliceBlue); } if (_SMA_slow.Result.LastValue < _SMA_Fast.Result.LastValue && _SMA_slow.Result.LastValue < Symbol.Ask) { Buy = false; Sell = true; ChartObjects.DrawText("buy", ("Comprar"), StaticPosition.TopLeft, Colors.AliceBlue); } if (CountOfTradesOfType(TradeType.Buy) > 0) AdjustBuyPositionTakeProfits(CalculateAveragePositionPrice(TradeType.Buy), AverageTakeProfit); if (CountOfTradesOfType(TradeType.Sell) > 0) AdjustSellPositionTakeProfits(CalculateAveragePositionPrice(TradeType.Sell), AverageTakeProfit); if (CurrentSpread <= MaxSpread && !_accountIsOutOfMoney) ProcessTrades(); if (!this.IsBacktesting) DisplayStatusOnChart(); } protected override void OnError(Error error) { if (error.Code == ErrorCode.NoMoney) { _accountIsOutOfMoney = true; Print("opening stopped because: not enough money"); } } protected override void OnBar() { RefreshData(); } protected override void OnStop() { ChartObjects.RemoveAllObjects(); } private void ProcessTrades() { if (Buy && CountOfTradesOfType(TradeType.Buy) == 0 && MarketSeries.Close.Last(1) > MarketSeries.Close.Last(2)) { _openTradeResult = OrderSend(TradeType.Buy, LimitVolume(FirstVolume)); if (_openTradeResult > 0) _lastBuyTradeTime = MarketSeries.OpenTime.Last(0); else Print("First BUY openning error at: ", Symbol.Ask, "Error Type: ", LastResult.Error); } if (Sell && CountOfTradesOfType(TradeType.Sell) == 0 && MarketSeries.Close.Last(2) > MarketSeries.Close.Last(1)) { _openTradeResult = OrderSend(TradeType.Sell, LimitVolume(FirstVolume)); if (_openTradeResult > 0) _lastSellTradeTime = MarketSeries.OpenTime.Last(0); else Print("First SELL opening error at: ", Symbol.Bid, "Error Type: ", LastResult.Error); } if (CountOfTradesOfType(TradeType.Buy) > 0) { if (Math.Round(Symbol.Ask, Symbol.Digits) < Math.Round(FindLowestPositionPrice(TradeType.Buy) - PipStep * Symbol.PipSize, Symbol.Digits) && _lastBuyTradeTime != MarketSeries.OpenTime.Last(0)) { var calculatedVolume = CalculateVolume(TradeType.Buy); _openTradeResult = OrderSend(TradeType.Buy, LimitVolume(calculatedVolume)); if (_openTradeResult > 0) _lastBuyTradeTime = MarketSeries.OpenTime.Last(0); else Print("Next BUY opening error at: ", Symbol.Ask, "Error Type: ", LastResult.Error); } } if (CountOfTradesOfType(TradeType.Sell) > 0) { if (Math.Round(Symbol.Bid, Symbol.Digits) > Math.Round(FindHighestPositionPrice(TradeType.Sell) + PipStep * Symbol.PipSize, Symbol.Digits) && _lastSellTradeTime != MarketSeries.OpenTime.Last(0)) { var calculatedVolume = CalculateVolume(TradeType.Sell); _openTradeResult = OrderSend(TradeType.Sell, LimitVolume(calculatedVolume)); if (_openTradeResult > 0) _lastSellTradeTime = MarketSeries.OpenTime.Last(0); else Print("Next SELL opening error at: ", Symbol.Bid, "Error Type: ", LastResult.Error); } } } private int OrderSend(TradeType tradeType, long volumeToUse) { var returnResult = 0; if (volumeToUse > 0) { var result = ExecuteMarketOrder(tradeType, Symbol, volumeToUse, Label, StopLoss, 0, 0, "smart_grid"); if (result.IsSuccessful) { Print(tradeType, "Opened at: ", result.Position.EntryPrice, result.Position.StopLoss); returnResult = 1; } else Print(tradeType, "Openning Error: ", result.Error); } else Print("Volume calculation error: Calculated Volume is: ", volumeToUse); return returnResult; } private void AdjustBuyPositionTakeProfits(double averageBuyPositionPrice, int averageTakeProfit) { foreach (var buyPosition in Positions) { if (buyPosition.Label == Label && buyPosition.SymbolCode == Symbol.Code) { if (buyPosition.TradeType == TradeType.Buy) { double? calculatedTakeProfit = Math.Round(averageBuyPositionPrice + averageTakeProfit * Symbol.PipSize, Symbol.Digits); if (buyPosition.TakeProfit != calculatedTakeProfit) ModifyPosition(buyPosition, buyPosition.StopLoss, calculatedTakeProfit); } } } } private void AdjustSellPositionTakeProfits(double averageSellPositionPrice, int averageTakeProfit) { foreach (var sellPosition in Positions) { if (sellPosition.Label == Label && sellPosition.SymbolCode == Symbol.Code) { if (sellPosition.TradeType == TradeType.Sell) { double? calculatedTakeProfit = Math.Round(averageSellPositionPrice - averageTakeProfit * Symbol.PipSize, Symbol.Digits); if (sellPosition.TakeProfit != calculatedTakeProfit) ModifyPosition(sellPosition, sellPosition.StopLoss, calculatedTakeProfit); } } } } private void DisplayStatusOnChart() { if (CountOfTradesOfType(TradeType.Buy) > 1) { var y = CalculateAveragePositionPrice(TradeType.Buy); ChartObjects.DrawHorizontalLine("bpoint", y, Colors.Yellow, 2, LineStyle.Dots); } else ChartObjects.RemoveObject("bpoint"); if (CountOfTradesOfType(TradeType.Sell) > 1) { var z = CalculateAveragePositionPrice(TradeType.Sell); ChartObjects.DrawHorizontalLine("spoint", z, Colors.HotPink, 2, LineStyle.Dots); } else ChartObjects.RemoveObject("spoint"); ChartObjects.DrawText("pan", GenerateStatusText(), StaticPosition.TopLeft, Colors.Tomato); } private string GenerateStatusText() { var statusText = ""; var buyPositions = ""; var sellPositions = ""; var spread = ""; var buyDistance = ""; var sellDistance = ""; spread = "\nSpread = " + Math.Round(CurrentSpread, 1); buyPositions = "\nBuy Positions = " + CountOfTradesOfType(TradeType.Buy); sellPositions = "\nSell Positions = " + CountOfTradesOfType(TradeType.Sell); if (CountOfTradesOfType(TradeType.Buy) > 0) { var averageBuyFromCurrent = Math.Round((CalculateAveragePositionPrice(TradeType.Buy) - Symbol.Bid) / Symbol.PipSize, 1); buyDistance = "\nBuy Target Away = " + averageBuyFromCurrent; } if (CountOfTradesOfType(TradeType.Sell) > 0) { var averageSellFromCurrent = Math.Round((Symbol.Ask - CalculateAveragePositionPrice(TradeType.Sell)) / Symbol.PipSize, 1); sellDistance = "\nSell Target Away = " + averageSellFromCurrent; } if (CurrentSpread > MaxSpread) statusText = "MAX SPREAD EXCEED"; else statusText = "Smart Grid" + buyPositions + spread + sellPositions + buyDistance + sellDistance; return (statusText); } private int CountOfTradesOfType(TradeType tradeType) { var tradeCount = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) tradeCount++; } } return tradeCount; } private double CalculateAveragePositionPrice(TradeType tradeType) { double result = 0; double averagePrice = 0; long count = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { averagePrice += position.EntryPrice * position.Volume; count += position.Volume; } } } if (averagePrice > 0 && count > 0) result = Math.Round(averagePrice / count, Symbol.Digits); return result; } private double FindLowestPositionPrice(TradeType tradeType) { double lowestPrice = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { if (lowestPrice == 0) { lowestPrice = position.EntryPrice; continue; } if (position.EntryPrice < lowestPrice) lowestPrice = position.EntryPrice; } } } return lowestPrice; } private double FindHighestPositionPrice(TradeType tradeType) { double highestPrice = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { if (highestPrice == 0) { highestPrice = position.EntryPrice; continue; } if (position.EntryPrice > highestPrice) highestPrice = position.EntryPrice; } } } return highestPrice; } private double FindPriceOfMostRecentPositionId(TradeType tradeType) { double price = 0; var highestPositionId = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { if (highestPositionId == 0 || highestPositionId > position.Id) { price = position.EntryPrice; highestPositionId = position.Id; } } } } return price; } private long GetMostRecentPositionVolume(TradeType tradeType) { long mostRecentVolume = 0; var highestPositionId = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { if (highestPositionId == 0 || highestPositionId > position.Id) { mostRecentVolume = position.Volume; highestPositionId = position.Id; } } } } return mostRecentVolume; } private int CountNumberOfPositionsOfType(TradeType tradeType) { var mostRecentPrice = FindPriceOfMostRecentPositionId(tradeType); var numberOfPositionsOfType = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType && tradeType == TradeType.Buy) { if (Math.Round(position.EntryPrice, Symbol.Digits) <= Math.Round(mostRecentPrice, Symbol.Digits)) numberOfPositionsOfType++; } if (position.TradeType == tradeType && tradeType == TradeType.Sell) { if (Math.Round(position.EntryPrice, Symbol.Digits) >= Math.Round(mostRecentPrice, Symbol.Digits)) numberOfPositionsOfType++; } } } return (numberOfPositionsOfType); } private long CalculateVolume(TradeType tradeType) { var numberOfPositions = CountNumberOfPositionsOfType(tradeType); var mostRecentVolume = GetMostRecentPositionVolume(tradeType); var calculatedVolume = Symbol.NormalizeVolume(mostRecentVolume * Math.Pow(VolumeExponent, numberOfPositions)); return (calculatedVolume); } private long LimitVolume(long volumeIn) { var symbolVolumeMin = Symbol.VolumeMin; var symbolVolumeMax = Symbol.VolumeMax; var result = volumeIn; if (result < symbolVolumeMin) result = symbolVolumeMin; if (result > symbolVolumeMax) result = symbolVolumeMax; return (result); } } }
up 07.2020
What are your ideas for improving the code after testing - for Sell trend in xauusd, xagusd, majors etc ?
SellSmartGrid - improving ?!
How 1. cTrader demo to live ctrader, mt4/mt5 Trade Copier ?
How 2. mt4/mt5 demo to live ctrader, mt4/mt5 Trade Copier ?
Replies
PanagiotisCharalampous
18 Oct 2019, 08:14
Hi tgjobscv,
You can access all your orders via PendingOrders and modify them accodingly. See example below
PendingOrders[0].ModifyVolume(1000);
Best Regards,
Panagiotis
@PanagiotisCharalampous
Mr4x
23 Nov 2019, 06:41
Great Concept, a few bugs
Hi tgjobscv,
Your code works a treat when selling XAUUSD over the past 3 months of this year, however if you try to do a back-test on a $10,000 account over the past year (22-11-18 to 22-11-19) you do get 100% draw-down during December 2018. Might need to tweak the code a bit?
Anyway the feature that is broken is the ability to use this as "buy only". If you set "buy" to yes and "sell" to no then try and back-test, the cbot still places sell side orders. I'm looking at running a hedge-type situation using a buy with XAUEUR side-by-side with sell XAUUSD, so if you could fix the cbot and then maybe play around with that idea of mine too and see what you think.
Cheers,
Mr4x
@Mr4x
tgjobscv
26 Jul 2020, 17:56
RE: Great Concept, a few bugs
Mr4x said:
Hi tgjobscv,
Your code works a treat when selling XAUUSD over the past 3 months of this year, however if you try to do a back-test on a $10,000 account over the past year (22-11-18 to 22-11-19) you do get 100% draw-down during December 2018. Might need to tweak the code a bit?
Anyway the feature that is broken is the ability to use this as "buy only". If you set "buy" to yes and "sell" to no then try and back-test, the cbot still places sell side orders. I'm looking at running a hedge-type situation using a buy with XAUEUR side-by-side with sell XAUUSD, so if you could fix the cbot and then maybe play around with that idea of mine too and see what you think.
Cheers,
Mr4x
up 07.2020
SellSmartGrid - Only - Sell trend (parametr Buy is ignoring) with MA and one way trend LimitStop Sell H1 H4 - only Sell trend backtest date.
What are your ideas for improving the code after testing - for Sell trend in xauusd, xagusd, majors etc ?
SellSmartGrid - improving ?!
How 1. cTrader demo to live ctrader, mt4/mt5 Trade Copier ?
How 2. mt4/mt5 demo to live ctrader, mt4/mt5 Trade Copier ?
@tgjobscv
tgjobscv
01 Oct 2019, 21:44
How limit max sell position in code ?
Code for library.
How put limit max sell position in code ?
@tgjobscv