backtesting différent
backtesting différent
13 Nov 2021, 18:25
I want to create a multy symbol robot ...
in my simple example I chose a symbol different from my graph, I get the desired symbol,whatever the symbol of the chart (in my example it is EURUSD).
the problem is that the backtests are all different.
if I choose the symbol of the chart identical to my choice, all is well I have the right result but if I choose other symbols on the chart for example GBPUSD or GER40 or US30..etc the backtest
is never the same.
I have tried many solutions without being able to find the right one.
thank you for your precious help.
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class MultyTraDinG : Robot
{
////////////////////////////////////////////////////////////////////////////////////////
[Parameter("__________________________", DefaultValue = "___________")]
public string Separator { get; set; }
[Parameter("Volume", DefaultValue = 5000, MinValue = 0)]
public double Volume { get; set; }
[Parameter("SL ", DefaultValue = 147)]
public double SL { get; set; }
[Parameter("TP ", DefaultValue = 57)]
public double TP { get; set; }
[Parameter("MA_period", DefaultValue = 24)]
public int MA_period { get; set; }
[Parameter("MAType", DefaultValue = MovingAverageType.VIDYA)]
public MovingAverageType MAType { get; set; }
[Parameter("MACD LongCycle", DefaultValue = 26, MinValue = 1)]
public int LongCycle { get; set; }
[Parameter("MACD ShortCycle", DefaultValue = 12, MinValue = 1)]
public int ShortCycle { get; set; }
[Parameter("MACD Period", DefaultValue = 9, MinValue = 1)]
public int MACDPeriod { get; set; }
private MovingAverage MA;
private MacdHistogram _macd;
/////////////////////////////////////////////////////////////////////////////////////////////////////////
protected override void OnStart()
{
MA = Indicators.MovingAverage(Bars.ClosePrices, MA_period, MAType);
_macd = Indicators.MacdHistogram(LongCycle, ShortCycle, MACDPeriod);
}
protected override void OnBar()
{
ManagePositions1();
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void ManagePositions1()
{
var symbol = Symbols.GetSymbol("EURUSD");
var longPosition = Positions.FindAll("sample", symbol, TradeType.Buy);
var shortPosition = Positions.FindAll("sample", symbol, TradeType.Sell);
{
if (longPosition.Length == 0 && MA.Result.IsRising() && _macd.Signal.IsRising())
{
ExecuteMarketOrder(TradeType.Buy, symbol, Volume, "sample", SL, TP);
{
if (shortPosition.Length == 0 && MA.Result.IsFalling() && _macd.Signal.IsFalling())
{
ExecuteMarketOrder(TradeType.Sell, symbol, Volume, "sample", SL, TP);
}
}
}
}
}
}
}
Replies
MATRIXTRADER
15 Nov 2021, 13:32
RE:
PanagiotisCharalampous said:
Hi MATRIXTRADER,
As far as I can see, you are using the current chart symbol for your indicators.
MA = Indicators.MovingAverage(Bars.ClosePrices, MA_period, MAType); _macd = Indicators.MacdHistogram(LongCycle, ShortCycle, MACDPeriod);
So for every symbol the indicators will be different. Why do you expect the results to be the same?
Best Regards,
Panagiotis
Hello
thank you for your reply
I misspoke
so I give you another example to make me understand.
if I have several instances with different symbols in the same robot then necessarily the graphic symbol will be different for some instances.
for my example I built a simplified robot with 2 identical indicators but 3 different symbols (or 4 ... or 10 ...) because I want to multiply the opportunities with the same robot, necessarily 2 instances will be disconnected from the symbol of the graph.
the backtesting corresponds to reality only for the instance which opens with the correct graphic, but it is false for the 2 other instances which do not open with the graphic which should correspond to their symbol.
and if you interchange the chart or if you choose 1 symbol different from the robot's choice you will never have the same backtesting.
so I think that something important is missing from my code to create a robot with symbols that work independently of each other. (and a backtesting that corresponds for each of the symbols since we cannot open a chart at the same time to each)
thanks in advance.
// ROBOT TRADERMATRIX
//
// \ /
// \ /
// \ /
// (0)!(0)
// --------(@)--------
// / \
// / \
// / \
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Diagnostics;
using Microsoft.Win32;
using cAlgo.API.Requests;
using System.Text;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class MultyTraDinGPro : Robot
{
[Parameter("Use CHOOSE 1", DefaultValue = true)]
public bool useCHOOSE1 { get; set; }
[Parameter("CHOOSE SYMBOL 1", DefaultValue = "GER40")]
public string Symbol1 { get; set; }
[Parameter("Another Timeframe", DefaultValue = "HOUR")]
public TimeFrame AnotherTimeFrame1 { get; set; }
[Parameter("Label 1", DefaultValue = "dax")]
public string RobotID1 { get; set; }
[Parameter("Volume", DefaultValue = 0.6, MinValue = 0)]
public double Volume1 { get; set; }
[Parameter("SL ", DefaultValue = 60)]
public double SL1 { get; set; }
[Parameter("TP ", DefaultValue = 10)]
public double TP1 { get; set; }
[Parameter("MA_period", DefaultValue = 24)]
public int MA_period1 { get; set; }
[Parameter("MAType", DefaultValue = MovingAverageType.VIDYA)]
public MovingAverageType MAType1 { get; set; }
[Parameter("--------MACD-----------------", DefaultValue = "MACD")]
public string Separator6 { get; set; }
[Parameter("MACD LongCycle", DefaultValue = 30, MinValue = 1)]
public int LongCycle1 { get; set; }
[Parameter("MACD ShortCycle", DefaultValue = 2, MinValue = 1)]
public int ShortCycle1 { get; set; }
[Parameter("MACD Period", DefaultValue = 20, MinValue = 1)]
public int MACDPeriod1 { get; set; }
[Parameter("__________________________", DefaultValue = "___________")]
public string Separator1 { get; set; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////
[Parameter("Use CHOOSE 2", DefaultValue = true)]
public bool useCHOOSE2 { get; set; }
[Parameter("CHOOSE SYMBOL 2", DefaultValue = "GBPUSD")]
public string Symbol2 { get; set; }
[Parameter("Another Timeframe", DefaultValue = "HOUR")]
public TimeFrame AnotherTimeFrame2 { get; set; }
[Parameter("Label 1", DefaultValue = "gbp")]
public string RobotID2 { get; set; }
[Parameter("Volume", DefaultValue = 5000, MinValue = 0)]
public double Volume2 { get; set; }
[Parameter("SL ", DefaultValue = 110)]
public double SL2 { get; set; }
[Parameter("TP ", DefaultValue = 20)]
public double TP2 { get; set; }
[Parameter("MA_period", DefaultValue = 100)]
public int MA_period2 { get; set; }
[Parameter("MAType", DefaultValue = MovingAverageType.Simple)]
public MovingAverageType MAType2 { get; set; }
[Parameter("MACD LongCycle", DefaultValue = 21, MinValue = 1)]
public int LongCycle2 { get; set; }
[Parameter("MACD ShortCycle", DefaultValue = 12, MinValue = 1)]
public int ShortCycle2 { get; set; }
[Parameter("MACD Period", DefaultValue = 9, MinValue = 1)]
public int MACDPeriod2 { get; set; }
[Parameter("__________________________", DefaultValue = "___________")]
public string Separator2 { get; set; }
//////////////////////////////////////////////////////////////////////////////////////////////////////
[Parameter("Use CHOOSE 3", DefaultValue = true)]
public bool useCHOOSE3 { get; set; }
[Parameter("CHOOSE SYMBOL 3", DefaultValue = "XAUUSD")]
public string Symbol3 { get; set; }
[Parameter("Another Timeframe", DefaultValue = "HOUR")]
public TimeFrame AnotherTimeFrame3 { get; set; }
[Parameter("Label 3", DefaultValue = "gold")]
public string RobotID3 { get; set; }
[Parameter("Volume", DefaultValue = 3, MinValue = 0)]
public double Volume3 { get; set; }
[Parameter("SL ", DefaultValue = 120)]
public double SL3 { get; set; }
[Parameter("TP ", DefaultValue = 15)]
public double TP3 { get; set; }
[Parameter("MA_period", DefaultValue = 200)]
public int MA_period3 { get; set; }
[Parameter("MAType", DefaultValue = MovingAverageType.Exponential)]
public MovingAverageType MAType3 { get; set; }
[Parameter("MACD LongCycle", DefaultValue = 32, MinValue = 1)]
public int LongCycle3 { get; set; }
[Parameter("MACD ShortCycle", DefaultValue = 14, MinValue = 1)]
public int ShortCycle3 { get; set; }
[Parameter("MACD Period", DefaultValue = 30, MinValue = 1)]
public int MACDPeriod3 { get; set; }
[Parameter("__________________________", DefaultValue = "___________")]
public string Separator20E { get; set; }
private MovingAverage MA1;
private MacdHistogram _macd1;
private MovingAverage MA2;
private MacdHistogram _macd2;
private MovingAverage MA3;
private MacdHistogram _macd3;
private Symbol _symbol1;
private Symbol _symbol2;
private Symbol _symbol3;
/////////////////////////////////////////////////////////////////////////////////////////////////////////
private void InitializeSeries(string symbolCode)
{
_symbol1 = Symbols.GetSymbol(Symbol1);
_symbol2 = Symbols.GetSymbol(Symbol2);
_symbol3 = Symbols.GetSymbol(Symbol3);
}
protected override void OnStart()
{
InitializeSeries(Symbol1);
InitializeSeries(Symbol2);
InitializeSeries(Symbol3);
{
var Series1 = MarketData.GetSeries(_symbol1, AnotherTimeFrame1);
MA1 = Indicators.MovingAverage(Series1.Close, MA_period1, MAType1);
_macd1 = Indicators.MacdHistogram(Series1.Close, LongCycle1, ShortCycle1, MACDPeriod1);
var Series2 = MarketData.GetSeries(_symbol2, AnotherTimeFrame2);
MA2 = Indicators.MovingAverage(Series2.Close, MA_period2, MAType2);
_macd2 = Indicators.MacdHistogram(Series2.Close, LongCycle2, ShortCycle2, MACDPeriod2);
var Series3 = MarketData.GetSeries(_symbol3, AnotherTimeFrame3);
MA3 = Indicators.MovingAverage(Series3.Close, MA_period3, MAType3);
_macd3 = Indicators.MacdHistogram(Series3.Close, LongCycle3, ShortCycle3, MACDPeriod3);
}
}
protected override void OnBar()
{
ManagePositions1();
ManagePositions2();
ManagePositions3();
}
private void ManagePositions1()
{
if (useCHOOSE1 == true)
{
var cBotPositions = Positions.FindAll(RobotID1);
if (cBotPositions.Length >= 1)
return;
{
if (MA1.Result.IsRising() && _macd1.Signal.IsRising())
{
ExecuteMarketOrder(TradeType.Buy, _symbol1, Volume1, RobotID1, SL1, TP1);
{
if (MA1.Result.IsFalling() && _macd1.Signal.IsFalling())
{
ExecuteMarketOrder(TradeType.Sell, Symbol1, Volume1, RobotID1, SL1, TP1);
}
}
}
}
}
}
//////////////////////////////////////////////////////////////////
private void ManagePositions2()
{
if (useCHOOSE2)
{
var cBotPositions = Positions.FindAll(RobotID2);
if (cBotPositions.Length >= 1)
return;
{
if (MA2.Result.IsRising() && _macd2.Signal.IsRising())
{
ExecuteMarketOrder(TradeType.Buy, _symbol2, Volume2, RobotID2, SL2, TP2);
{
if (MA2.Result.IsFalling() && _macd2.Signal.IsFalling())
{
ExecuteMarketOrder(TradeType.Sell, _symbol2, Volume2, RobotID2, SL2, TP2);
}
}
}
}
}
}
//////////////////////////////////////////////////////////////////
private void ManagePositions3()
{
//
if (useCHOOSE3 == true)
{
var cBotPositions = Positions.FindAll(RobotID3);
if (cBotPositions.Length >= 1)
return;
{
if (MA3.Result.IsRising() && _macd3.Signal.IsRising())
{
ExecuteMarketOrder(TradeType.Buy, _symbol3, Volume3, RobotID3, SL3, TP3);
{
if (MA3.Result.IsFalling() && _macd3.Signal.IsFalling())
{
ExecuteMarketOrder(TradeType.Sell, _symbol3, Volume3, RobotID3, SL3, TP3);
}
}
}
}
}
}
}
}
@MATRIXTRADER
MATRIXTRADER
16 Nov 2021, 14:22
RE: RE:
MATRIXTRADER said
Hello
does anyone have an answer regarding the difference
backtesting (Tick mode) when changing chart symbol.
where is the error in my code?
Regards
@MATRIXTRADER
amusleh
17 Nov 2021, 07:55
Hi,
I didn't understood your issue, but If you are not using multiple symbols data for taking trading decision then there is no need to use multiple symbols on your cBot.
Just create a new instance of your cBot for each symbol you want to trade.
That way you keep your cBot code simple.
@amusleh
PanagiotisCharalampous
17 Nov 2021, 08:01
Hi MATRIXTRADER,
One of the improvements you can make to the code is to execute the logic of the cBot on each symbol's BarOpened event. OnBar is executed differently for each symbol and this can cause discrepancies to the results.
Best Regards,
Panagiotis
Join us on Telegram and Facebook
@PanagiotisCharalampous
MATRIXTRADER
18 Nov 2021, 15:13
RE:
PanagiotisCharalampous said:
Hi MATRIXTRADER,
One of the improvements you can make to the code is to execute the logic of the cBot on each symbol's BarOpened event. OnBar is executed differently for each symbol and this can cause discrepancies to the results.
Best Regards,
Panagiotis
Thank you very much for your answer
I think this must be the right solution.
unfortunately I looked in the API and looked in the forum and I did not find a concrete example to make my task easier.
Do you have if possible a piece of code to execute the logic on the BarOpened event of a symbol
with many thanks.
@MATRIXTRADER
PanagiotisCharalampous
18 Nov 2021, 15:21
Hi MATRIXTRADER,
See your modified strategy, using BarOpened instead, below
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Diagnostics;
using Microsoft.Win32;
using cAlgo.API.Requests;
using System.Text;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
public class MultyTraDinGPro : Robot
{
[Parameter("Use CHOOSE 1", DefaultValue = true)]
public bool useCHOOSE1 { get; set; }
[Parameter("CHOOSE SYMBOL 1", DefaultValue = "GER40")]
public string Symbol1 { get; set; }
[Parameter("Another Timeframe", DefaultValue = "HOUR")]
public TimeFrame AnotherTimeFrame1 { get; set; }
[Parameter("Label 1", DefaultValue = "dax")]
public string RobotID1 { get; set; }
[Parameter("Volume", DefaultValue = 0.6, MinValue = 0)]
public double Volume1 { get; set; }
[Parameter("SL ", DefaultValue = 60)]
public double SL1 { get; set; }
[Parameter("TP ", DefaultValue = 10)]
public double TP1 { get; set; }
[Parameter("MA_period", DefaultValue = 24)]
public int MA_period1 { get; set; }
[Parameter("MAType", DefaultValue = MovingAverageType.VIDYA)]
public MovingAverageType MAType1 { get; set; }
[Parameter("--------MACD-----------------", DefaultValue = "MACD")]
public string Separator6 { get; set; }
[Parameter("MACD LongCycle", DefaultValue = 30, MinValue = 1)]
public int LongCycle1 { get; set; }
[Parameter("MACD ShortCycle", DefaultValue = 2, MinValue = 1)]
public int ShortCycle1 { get; set; }
[Parameter("MACD Period", DefaultValue = 20, MinValue = 1)]
public int MACDPeriod1 { get; set; }
[Parameter("__________________________", DefaultValue = "___________")]
public string Separator1 { get; set; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////
[Parameter("Use CHOOSE 2", DefaultValue = true)]
public bool useCHOOSE2 { get; set; }
[Parameter("CHOOSE SYMBOL 2", DefaultValue = "GBPUSD")]
public string Symbol2 { get; set; }
[Parameter("Another Timeframe", DefaultValue = "HOUR")]
public TimeFrame AnotherTimeFrame2 { get; set; }
[Parameter("Label 1", DefaultValue = "gbp")]
public string RobotID2 { get; set; }
[Parameter("Volume", DefaultValue = 5000, MinValue = 0)]
public double Volume2 { get; set; }
[Parameter("SL ", DefaultValue = 110)]
public double SL2 { get; set; }
[Parameter("TP ", DefaultValue = 20)]
public double TP2 { get; set; }
[Parameter("MA_period", DefaultValue = 100)]
public int MA_period2 { get; set; }
[Parameter("MAType", DefaultValue = MovingAverageType.Simple)]
public MovingAverageType MAType2 { get; set; }
[Parameter("MACD LongCycle", DefaultValue = 21, MinValue = 1)]
public int LongCycle2 { get; set; }
[Parameter("MACD ShortCycle", DefaultValue = 12, MinValue = 1)]
public int ShortCycle2 { get; set; }
[Parameter("MACD Period", DefaultValue = 9, MinValue = 1)]
public int MACDPeriod2 { get; set; }
[Parameter("__________________________", DefaultValue = "___________")]
public string Separator2 { get; set; }
//////////////////////////////////////////////////////////////////////////////////////////////////////
[Parameter("Use CHOOSE 3", DefaultValue = true)]
public bool useCHOOSE3 { get; set; }
[Parameter("CHOOSE SYMBOL 3", DefaultValue = "XAUUSD")]
public string Symbol3 { get; set; }
[Parameter("Another Timeframe", DefaultValue = "HOUR")]
public TimeFrame AnotherTimeFrame3 { get; set; }
[Parameter("Label 3", DefaultValue = "gold")]
public string RobotID3 { get; set; }
[Parameter("Volume", DefaultValue = 3, MinValue = 0)]
public double Volume3 { get; set; }
[Parameter("SL ", DefaultValue = 120)]
public double SL3 { get; set; }
[Parameter("TP ", DefaultValue = 15)]
public double TP3 { get; set; }
[Parameter("MA_period", DefaultValue = 200)]
public int MA_period3 { get; set; }
[Parameter("MAType", DefaultValue = MovingAverageType.Exponential)]
public MovingAverageType MAType3 { get; set; }
[Parameter("MACD LongCycle", DefaultValue = 32, MinValue = 1)]
public int LongCycle3 { get; set; }
[Parameter("MACD ShortCycle", DefaultValue = 14, MinValue = 1)]
public int ShortCycle3 { get; set; }
[Parameter("MACD Period", DefaultValue = 30, MinValue = 1)]
public int MACDPeriod3 { get; set; }
[Parameter("__________________________", DefaultValue = "___________")]
public string Separator20E { get; set; }
private MovingAverage MA1;
private MacdHistogram _macd1;
private MovingAverage MA2;
private MacdHistogram _macd2;
private MovingAverage MA3;
private MacdHistogram _macd3;
private Symbol _symbol1;
private Symbol _symbol2;
private Symbol _symbol3;
/////////////////////////////////////////////////////////////////////////////////////////////////////////
private void InitializeSeries(string symbolCode)
{
_symbol1 = Symbols.GetSymbol(Symbol1);
_symbol2 = Symbols.GetSymbol(Symbol2);
_symbol3 = Symbols.GetSymbol(Symbol3);
}
protected override void OnStart()
{
InitializeSeries(Symbol1);
InitializeSeries(Symbol2);
InitializeSeries(Symbol3);
{
var bars = MarketData.GetBars(AnotherTimeFrame1, Symbol1);
bars.BarOpened += Bars_BarOpened;
MA1 = Indicators.MovingAverage(bars.ClosePrices, MA_period1, MAType1);
_macd1 = Indicators.MacdHistogram(bars.ClosePrices, LongCycle1, ShortCycle1, MACDPeriod1);
var bars2 = MarketData.GetBars(AnotherTimeFrame2, Symbol2);
bars.BarOpened += Bars_BarOpened1;
MA2 = Indicators.MovingAverage(bars2.ClosePrices, MA_period2, MAType2);
_macd2 = Indicators.MacdHistogram(bars2.ClosePrices, LongCycle2, ShortCycle2, MACDPeriod2);
var bars3 = MarketData.GetBars(AnotherTimeFrame3, Symbol3);
bars3.BarOpened += Bars3_BarOpened;
MA3 = Indicators.MovingAverage(bars3.ClosePrices, MA_period3, MAType3);
_macd3 = Indicators.MacdHistogram(bars3.ClosePrices, LongCycle3, ShortCycle3, MACDPeriod3);
}
}
private void Bars3_BarOpened(BarOpenedEventArgs obj)
{
ManagePositions3();
}
private void Bars_BarOpened1(BarOpenedEventArgs obj)
{
ManagePositions2();
}
private void Bars_BarOpened(BarOpenedEventArgs obj)
{
ManagePositions1();
}
private void ManagePositions1()
{
if (useCHOOSE1 == true)
{
var cBotPositions = Positions.FindAll(RobotID1);
if (cBotPositions.Length >= 1)
return;
{
if (MA1.Result.IsRising() && _macd1.Signal.IsRising())
{
ExecuteMarketOrder(TradeType.Buy, _symbol1, Volume1, RobotID1, SL1, TP1);
{
if (MA1.Result.IsFalling() && _macd1.Signal.IsFalling())
{
ExecuteMarketOrder(TradeType.Sell, Symbol1, Volume1, RobotID1, SL1, TP1);
}
}
}
}
}
}
//////////////////////////////////////////////////////////////////
private void ManagePositions2()
{
if (useCHOOSE2)
{
var cBotPositions = Positions.FindAll(RobotID2);
if (cBotPositions.Length >= 1)
return;
{
if (MA2.Result.IsRising() && _macd2.Signal.IsRising())
{
ExecuteMarketOrder(TradeType.Buy, _symbol2, Volume2, RobotID2, SL2, TP2);
{
if (MA2.Result.IsFalling() && _macd2.Signal.IsFalling())
{
ExecuteMarketOrder(TradeType.Sell, _symbol2, Volume2, RobotID2, SL2, TP2);
}
}
}
}
}
}
//////////////////////////////////////////////////////////////////
private void ManagePositions3()
{
//
if (useCHOOSE3 == true)
{
var cBotPositions = Positions.FindAll(RobotID3);
if (cBotPositions.Length >= 1)
return;
{
if (MA3.Result.IsRising() && _macd3.Signal.IsRising())
{
ExecuteMarketOrder(TradeType.Buy, _symbol3, Volume3, RobotID3, SL3, TP3);
{
if (MA3.Result.IsFalling() && _macd3.Signal.IsFalling())
{
ExecuteMarketOrder(TradeType.Sell, _symbol3, Volume3, RobotID3, SL3, TP3);
}
}
}
}
}
}
}
}
Best Regards,
Panagiotis
Join us on Telegram and Facebook
@PanagiotisCharalampous
MATRIXTRADER
18 Nov 2021, 16:10
RE:
you are great
thanks to you it works perfectly, I will be able to continue to develop my strategy
Thank you for you precious help
Matrix
@MATRIXTRADER
PanagiotisCharalampous
15 Nov 2021, 08:17
Hi MATRIXTRADER,
As far as I can see, you are using the current chart symbol for your indicators.
So for every symbol the indicators will be different. Why do you expect the results to be the same?
Best Regards,
Panagiotis
Join us on Telegram and Facebook
@PanagiotisCharalampous