Description
Jk ct bot trading
using System.Collections.Generic;
using System.Linq;
using cAlgo.API;
namespace cAlgo.Plugins
{
[Plugin(AccessRights = AccessRights.None)]
public class CurrencyStrengthBoard : Plugin
{
#region Fields
private const double ScaleMin = 1;
private const double ScaleMax = 500;
private readonly List<string> _symbolNames = new();
private readonly List<Bars> _symbolBars = new();
private readonly Dictionary<string, double> _currencyStrength = new();
private readonly List<HorizontalBar> _orderedStrengthBars = new();
private readonly List<string> _bestLongSymbols = new();
private readonly List<string> _bestShortSymbols = new();
private readonly HashSet<string> _currencies = new()
{
"EUR",
"USD",
"GBP",
"AUD",
"CAD",
"NZD",
"JPY",
"CHF",
"TRY",
"SGD",
"BTC",
"MXN"
};
private StackPanel _strengthBoardPanel;
private ComboBox _timeFramesComboBox;
private TextBlock _loadingTextBlock;
private CustomFrame _frame;
private TextBox _periodsTextBox;
private StackPanel _bestLongSymbolsPanel;
private StackPanel _bestShortSymbolsPanel;
private Grid _mainPanel;
#endregion Fields
#region Parameters
public int Periods
{
get => int.Parse(LocalStorage.GetString(nameof(Periods)) ?? 20.ToString());
set => LocalStorage.SetString(nameof(Periods), value.ToString());
}
public TimeFrame BarsTimeFrame
{
get => TimeFrame.Parse(LocalStorage.GetString(nameof(BarsTimeFrame)) ?? TimeFrame.Daily.ToString());
set => LocalStorage.SetString(nameof(BarsTimeFrame), value.ToString());
}
#endregion Parameters
#region Overridden methods
protected override void OnStart()
{
ChartManager.FramesRemoved += OnChartManagerFramesRemoved;
Start();
}
private void OnChartManagerFramesRemoved(FramesRemovedEventArgs obj)
{
if (_frame is null)
return;
if (!obj.RemovedFrames.Contains(_frame))
return;
Start();
}
private void Start()
{
CreateFrame();
Loading();
BeginInvokeOnMainThread(() =>
{
AddSymbolsNames();
AddCurrenciesStrength();
RefreshBoard();
});
}
private void CreateBestShortSymbolsPanel()
{
_bestShortSymbolsPanel = new StackPanel();
_bestShortSymbolsPanel.AddChild(new TextBlock
{
Text = "Best Symbols To Short",
FontWeight = FontWeight.Bold,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(5, 10, 5, 5),
FontSize = 14
});
var count = _bestShortSymbols.Count > 10 ? 10 : _bestShortSymbols.Count;
for (var i = 0; i < count; i++)
{
_bestShortSymbolsPanel.AddChild(new TextBlock
{
Margin = 5,
Text = $"#{i + 1}: {_bestShortSymbols[i]}",
FontWeight = FontWeight.Bold,
});
}
}
private void CreateBestLongSymbolsPanel()
{
_bestLongSymbolsPanel = new StackPanel();
_bestLongSymbolsPanel.AddChild(new TextBlock
{
Text = "Best Symbols To Long",
FontWeight = FontWeight.Bold,
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness(5, 5, 5, 10),
FontSize = 14
});
var count = _bestLongSymbols.Count > 10 ? 10 : _bestLongSymbols.Count;
for (var i = 0; i < count; i++)
{
_bestLongSymbolsPanel.AddChild(new TextBlock
{
Margin = 5,
Text = $"#{i + 1}: {_bestLongSymbols[i]}",
FontWeight = FontWeight.Bold,
});
}
}
private void Loading()
{
CreateLoadingTextBlock();
_frame.Child = new ScrollViewer {Content = _loadingTextBlock};
}
private void Show()
{
_mainPanel = new Grid(1, 2);
_mainPanel.AddChild(_strengthBoardPanel, 0, 0);
_mainPanel.Columns[0].SetWidthInStars(1);
_mainPanel.Columns[1].SetWidthToAuto();
var bestSymbolsPanel = new StackPanel() {Orientation = Orientation.Vertical, Margin = 20};
bestSymbolsPanel.AddChild(_bestLongSymbolsPanel);
bestSymbolsPanel.AddChild(_bestShortSymbolsPanel);
_mainPanel.AddChild(bestSymbolsPanel, 0, 1);
_frame.Child = new ScrollViewer {Content = _mainPanel};
}
private void CreateFrame()
{
_frame = ChartManager.AddCustomFrame("Currency Strength Board");
}
private void CreateLoadingTextBlock()
{
_loadingTextBlock = new TextBlock
{
Text = "Loading...",
FontWeight = FontWeight.ExtraBold,
FontSize = 16,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Margin = 10
};
}
private void UpdateAllCurrenciesStrength()
{
foreach (var currency in _currencies) UpdateCurrencyStrength(currency);
}
private void CreateStrengthBoard()
{
_strengthBoardPanel = new StackPanel {Orientation = Orientation.Vertical};
var titleTextBlock = new TextBlock
{
Text = $"Currency Strength Board ({ScaleMin} - {ScaleMax})",
Margin = 20,
FontWeight = FontWeight.Bold,
FontSize = 14,
HorizontalAlignment = HorizontalAlignment.Center
};
_strengthBoardPanel.AddChild(titleTextBlock);
var timeFramesTextBox = new TextBlock
{
Margin = 20,
Text = "Timeframe",
FontWeight = FontWeight.Bold
};
_timeFramesComboBox = new ComboBox
{
Margin = 20,
HorizontalAlignment = HorizontalAlignment.Left,
MinWidth = 80,
FontWeight = FontWeight.Bold,
};
PopulateTimeFrames();
_timeFramesComboBox.SelectedItemChanged += OnTimeFramesComboBoxSelectedItemChanged;
var periodsTextBlock = new TextBlock
{
Margin = 20,
Text = "Periods",
FontWeight = FontWeight.Bold
};
_periodsTextBox = new TextBox
{
Text = Periods.ToString(),
Margin = 20,
FontWeight = FontWeight.Bold,
MinWidth = 80
};
_periodsTextBox.TextChanged += OnPeriodsTextBoxTextChanged;
var settingsPanel = new StackPanel {Orientation = Orientation.Horizontal};
settingsPanel.AddChild(timeFramesTextBox);
settingsPanel.AddChild(_timeFramesComboBox);
settingsPanel.AddChild(periodsTextBlock);
settingsPanel.AddChild(_periodsTextBox);
_strengthBoardPanel.AddChild(settingsPanel);
_orderedStrengthBars.Clear();
for (var i = 0; i < _currencies.Count; i++)
{
var bar = new HorizontalBar {Margin = 20};
_strengthBoardPanel.AddChild(bar);
_orderedStrengthBars.Add(bar);
}
}
private void OnPeriodsTextBoxTextChanged(TextChangedEventArgs obj)
{
Periods = int.Parse(obj.TextBox.Text);
RefreshBoard();
}
private void OnTimeFramesComboBoxSelectedItemChanged(ComboBoxSelectedItemChangedEventArgs args)
{
BarsTimeFrame = TimeFrame.Parse(args.SelectedItem);
RefreshBoard();
}
private void RefreshBoard()
{
Loading();
BeginInvokeOnMainThread(() =>
{
UnsubscribeFromBars();
AddBars();
UpdateAllCurrenciesStrength();
CreateStrengthBoard();
UpdateStrengthBoard();
UpdateBestLongShortSymbols();
CreateBestLongSymbolsPanel();
CreateBestShortSymbolsPanel();
Show();
});
}
private void PopulateTimeFrames()
{
foreach (var fieldInfo in typeof(TimeFrame).GetFields())
{
_timeFramesComboBox.AddItem(fieldInfo.Name);
}
_timeFramesComboBox.SelectedItem = BarsTimeFrame.ToString();
}
private void AddBars()
{
_symbolBars.Clear();
foreach (var symbolName in _symbolNames)
{
var bars = MarketData.GetBars(BarsTimeFrame, symbolName);
_symbolBars.Add(bars);
bars.BarOpened += OnBarOpened;
}
}
private void UnsubscribeFromBars()
{
if (_symbolBars is null)
return;
foreach (var bars in _symbolBars)
{
bars.BarOpened -= OnBarOpened;
}
}
private void OnBarOpened(BarOpenedEventArgs args)
{
var symbol = Symbols.GetSymbol(args.Bars.SymbolName);
if (_currencies.TryGetValue(symbol.BaseAsset.Name.ToUpperInvariant(), out var baseCurrency))
UpdateCurrencyStrength(baseCurrency);
if (_currencies.TryGetValue(symbol.QuoteAsset.Name.ToUpperInvariant(), out var quoteCurrency))
UpdateCurrencyStrength(quoteCurrency);
UpdateStrengthBoard();
UpdateBestLongShortSymbols();
}
private void UpdateStrengthBoard()
{
var valueMax = _currencyStrength.Values.Max();
var valueMin = _currencyStrength.Values.Min();
var barIndex = 0;
foreach (var (currency, strength) in _currencyStrength.OrderByDescending(i => i.Value))
{
var bar = _orderedStrengthBars[barIndex];
bar.Label = currency;
bar.Value = MinMax(strength, valueMin, valueMax, ScaleMin, ScaleMax);
barIndex++;
}
}
private static double MinMax(double number, double min, double max, double minAllowedNumber,
double maxAllowedNumber)
{
var b = max - min != 0 ? max - min : 1 / max;
var uninterpolate = (number - min) / b;
var result = minAllowedNumber * (1 - uninterpolate) + maxAllowedNumber * uninterpolate;
return result;
}
private void AddCurrenciesStrength()
{
_currencyStrength.Clear();
foreach (var currency in _currencies) _currencyStrength.Add(currency, 0);
}
#endregion Overridden methods
#region Other methods
private void UpdateCurrencyStrength(string currency)
{
double symbolPercentage = 0;
var seriesCounter = 0;
foreach (var bars in _symbolBars)
{
var symbol = Symbols.GetSymbol(bars.SymbolName);
var impact = 0;
if (symbol.BaseAsset.Name == currency)
impact = 1;
else if ((symbol.QuoteAsset.Name == currency))
impact = -1;
if (impact == 0)
continue;
var index = bars.Count - 1;
seriesCounter++;
double seriesResult = 0;
for (var i = index - Periods; i <= index; i++) seriesResult += GetPercentageChange(bars, i);
symbolPercentage += seriesResult * impact;
}
_currencyStrength[currency] = symbolPercentage / seriesCounter;
}
private void UpdateBestLongShortSymbols()
{
_bestLongSymbols.Clear();
_bestShortSymbols.Clear();
var orderedCurrenciesStrength = _currencyStrength
.OrderByDescending(kv => kv.Value)
.ToArray();
for (var i = 0; i < orderedCurrenciesStrength.Length; i++)
{
var strongCurrency = orderedCurrenciesStrength[i].Key;
for (var j = orderedCurrenciesStrength.Length - 1; j > i; j--)
{
var weakCurrency = orderedCurrenciesStrength[j].Key;
foreach (var symbolName in Symbols)
{
var symbol = Symbols.GetSymbol(symbolName);
if (symbol.BaseAsset.Name == strongCurrency && symbol.QuoteAsset.Name == weakCurrency)
{
_bestLongSymbols.Add(symbolName);
}
else if (symbol.BaseAsset.Name == weakCurrency && symbol.QuoteAsset.Name == strongCurrency)
{
_bestShortSymbols.Add(symbolName);
}
}
}
}
}
private void AddSymbolsNames()
{
_symbolNames.Clear();
foreach (var symbolName in Symbols)
{
var symbol = Symbols.GetSymbol(symbolName);
var baseAssetName = symbol.BaseAsset.Name;
var quoteAssetName = symbol.QuoteAsset.Name;
if (!IsInCurrencies(baseAssetName) || !IsInCurrencies(quoteAssetName) ||
baseAssetName == quoteAssetName)
continue;
_symbolNames.Add(symbolName);
}
}
private bool IsInCurrencies(string currency) => _currencies.Contains(currency.ToUpperInvariant());
private static double GetPercentageChange(Bars bars, int index)
{
return -((bars.OpenPrices[index] - bars.ClosePrices[index]) / bars.OpenPrices[index]) * 100;
}
#endregion Other methods
}
}
HA
hajovi5474
Joined on 06.08.2024
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: Currency Strength Board_withSourceCode.algo.txt
- Rating: 0
- Installs: 270
- Modified: 06/08/2024 20:11
Warning! Running cBots downloaded from this section may lead to financial losses. Use them at your own risk.
Note that publishing copyrighted material is strictly prohibited. If you believe there is copyrighted material in this section, please use the Copyright Infringement Notification form to submit a claim.
Comments
Log in to add a comment.
excellent work - some would say it's a close copy of the plugin called Currency Strength Board
well done for thinking this one out and making it available as a bot, never mind a plugin!!