CustomSymbols
interface cAlgo.API Since 5.3
DesktopCLICloud
Represents collection of custom symbols.
Environment behaviour
CLI — not supported. Available to plugins only, and plugins cannot run in the CLI.
Cloud — not supported. Available to plugins only, and plugins cannot run in the cloud.
Definition
public interface CustomSymbols
Namespace: cAlgo.API · Group: Custom
Examples
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using System.Linq;
namespace cAlgo.Plugins;
public partial class CustomSymbolTest : Plugin
{
private const string InitialDescription = "This is custom symbol initial description";
private const string ChangedDescription = "This is custom symbol changed description";
private bool _isLoadMoreEnabled = true;
private CustomSymbol _customSymbol;
private CustomBars _customBars;
protected override void OnStart()
{
var panel = new StackPanel();
var addCustomSymbolWithBaseButton = new Button { Text = "Add custom symbol with Base Symbol" };
addCustomSymbolWithBaseButton.Click += OnAddCustomSymbolWithBaseButtonClick;
panel.AddChild(addCustomSymbolWithBaseButton);
var addCustomSymbolWithoutBaseButton = new Button { Text = "Add custom symbol without Base Symbol" };
addCustomSymbolWithoutBaseButton.Click += OnAddCustomSymbolWithoutBaseButtonClick;
panel.AddChild(addCustomSymbolWithoutBaseButton);
var removeCustomSymbolButton = new Button { Text = "Remove custom symbol" };
removeCustomSymbolButton.Click += OnRemoveCustomSymbolButtonClick;
panel.AddChild(removeCustomSymbolButton);
var displayChartInfoButton = new Button { Text = "Display Charts Info" };
displayChartInfoButton.Click += OnDisplayChartInfoButtonClick;
panel.AddChild(displayChartInfoButton);
var changeDescriptionButton = new Button { Text = "Change Description" };
changeDescriptionButton.Click += OnChangeDescriptionButtonClick;
panel.AddChild(changeDescriptionButton);
var updateSymbolPropertiesButton = new Button { Text = "Update Symbol Properties" };
updateSymbolPropertiesButton.Click += OnUpdateSymbolPropertiesButtonClick;
panel.AddChild(updateSymbolPropertiesButton);
var updateSymbolBaseAssetButton = new Button { Text = "Update Symbol Base Asset" };
updateSymbolBaseAssetButton.Click += OnUpdateSymbolBaseAssetButtonClick;
panel.AddChild(updateSymbolBaseAssetButton);
var updateSymbolQuoteAssetButton = new Button { Text = "Update Symbol Quote Asset" };
updateSymbolQuoteAssetButton.Click += OnUpdateSymbolQuoteAssetButtonClick;
panel.AddChild(updateSymbolQuoteAssetButton);
var showSymbolPropertiesButton = new Button { Text = "Show Symbol Properties" };
showSymbolPropertiesButton.Click += args => ShowSymbolProperties();
panel.AddChild(showSymbolPropertiesButton);
var showSymbolAssetsButton = new Button { Text = "Show Symbol Assets" };
showSymbolAssetsButton.Click += args => ShowSymbolAssets();
panel.AddChild(showSymbolAssetsButton);
var pauseOrResumeLoadMoreButton = new Button { Text = "Pause / Resume Load More" };
pauseOrResumeLoadMoreButton.Click += OnPauseOrResumeLoadMoreButtonClick;
panel.AddChild(pauseOrResumeLoadMoreButton);
var showRegularBarsInfoButton = new Button { Text = "Show Regular Bars Info" };
showRegularBarsInfoButton.Click += OnShowRegularBarsInfoButtonClick;
panel.AddChild(showRegularBarsInfoButton);
var addBarsButton = new Button { Text = "Add Bars For Active Chart Symbol" };
addBarsButton.Click += OnAddBarsButtonClick;
panel.AddChild(addBarsButton);
var removeBarsButton = new Button { Text = "Remove Bars For Active Chart Symbol" };
removeBarsButton.Click += OnRemoveBarsButtonClick;
panel.AddChild(removeBarsButton);
var updateLastBarButton = new Button { Text = "Update Last Bar" };
updateLastBarButton.Click += OnUpdateLastBarButtonClick;
panel.AddChild(updateLastBarButton);
var updateSymbolSentimentButton = new Button { Text = "Update Symbol Sentiment" };
updateSymbolSentimentButton.Click += OnUpdateSymbolSentimentButtonClick;
panel.AddChild(updateSymbolSentimentButton);
var showSymbolSentimentButton = new Button { Text = "Show Symbol Sentiment" };
showSymbolSentimentButton.Click += _ => ShowSymbolSentiment();
panel.AddChild(showSymbolSentimentButton);
var updateSymbolDynamicLeverageButton = new Button { Text = "Update Symbol Dynamic Leverage" };
updateSymbolDynamicLeverageButton.Click += OnUpdateSymbolDynamicLeverageButtonClick;
panel.AddChild(updateSymbolDynamicLeverageButton);
var showSymbolDynamicLeverageButton = new Button { Text = "Show Symbol Dynamic Leverage" };
showSymbolDynamicLeverageButton.Click += _ => ShowSymbolDynamicLeverage();
panel.AddChild(showSymbolDynamicLeverageButton);
var updateSymbolHolidaysButton = new Button { Text = "Update Symbol Holidays" };
updateSymbolHolidaysButton.Click += OnUpdateSymbolHolidaysButtonClick;
panel.AddChild(updateSymbolHolidaysButton);
var showSymbolHolidaysButton = new Button { Text = "Show Symbol Holidays" };
showSymbolHolidaysButton.Click += OnShowSymbolHolidaysButtonClick;
panel.AddChild(showSymbolHolidaysButton);
var updateSymbolSessionsButton = new Button { Text = "Update Symbol Sessions" };
updateSymbolSessionsButton.Click += OnUpdateSymbolSessionsButtonClick;
panel.AddChild(updateSymbolSessionsButton);
var showSymbolSessionsButton = new Button { Text = "Show Symbol Sessions" };
showSymbolSessionsButton.Click += OnShowSymbolSessionsButtonClick;
panel.AddChild(showSymbolSessionsButton);
var updateSymbolFuturesSettingsButton = new Button { Text = "Update Symbol Futures Settings" };
updateSymbolFuturesSettingsButton.Click += OnUpdateSymbolFuturesSettingsButtonClick;
panel.AddChild(updateSymbolFuturesSettingsButton);
var showSymbolFuturesSettingsButton = new Button { Text = "Show Symbol Futures Settings" };
showSymbolFuturesSettingsButton.Click += OnShowSymbolFuturesSettingsButtonClick;
panel.AddChild(showSymbolFuturesSettingsButton);
var block = Asp.SymbolTab.AddBlock("Custom symbol Test");
block.Child = panel;
block.Height = 550;
ChartManager.FramesAdded += OnChartManagerFramesAdded;
Symbols.Added += OnSymbolAdded;
Symbols.Removed += OnSymbolRemoved;
}
private void OnShowSymbolFuturesSettingsButtonClick(ButtonClickEventArgs obj)
{
Print($"Last Trade Time: {_customSymbol.Symbol.FuturesSettings.LastTradeTime} | Expiration Time: {_customSymbol.Symbol.FuturesSettings.ExpirationTime} | Maintenance Margin: {_customSymbol.Symbol.FuturesSettings.MaintenanceMargin}");
}
private void OnUpdateSymbolFuturesSettingsButtonClick(ButtonClickEventArgs obj)
{
_customSymbol.FuturesSettings = new CustomSymbolFuturesSettings(Server.Time, Server.Time.AddMonths(Random.Shared.Next(1, 10)), Random.Shared.NextDouble() * 100 + 1000);
}
private void OnShowSymbolSessionsButtonClick(ButtonClickEventArgs obj)
{
Print($"Sessions Count: {_customSymbol.Symbol.MarketHours.Sessions.Count}");
foreach (var session in _customSymbol.Symbol.MarketHours.Sessions)
{
Print($"Start Day: {session.StartDay} | End Day: {session.EndDay} | Start Time: {session.StartTime} | End Time: {session.EndTime}");
}
}
private void OnUpdateSymbolSessionsButtonClick(ButtonClickEventArgs obj)
{
var startDay = (DayOfWeek)Random.Shared.Next(0, 6);
var endDay = (DayOfWeek)((int)startDay + 1);
var startTime = TimeSpan.FromHours(Random.Shared.Next(0, 22));
var endTime = startTime.Add(TimeSpan.FromHours(1));
_customSymbol.MarketHours.Sessions.Add(new CustomSymbolTradingSession(startDay, endDay, startTime, endTime));
}
private void OnShowSymbolHolidaysButtonClick(ButtonClickEventArgs obj)
{
Print($"Holidays Count: {_customSymbol.Symbol.MarketHours.Holidays.Count}");
foreach (var holiday in _customSymbol.Symbol.MarketHours.Holidays)
{
Print($"Name: {holiday.Name} | Start: {holiday.StartTime:o} | End: {holiday.EndTime:o} | Is Recurring: {holiday.IsRecurring}");
}
}
private void OnUpdateSymbolHolidaysButtonClick(ButtonClickEventArgs obj)
{
var startTime = Server.Time.AddMonths(Random.Shared.Next(1, 3));
var endTime = startTime.AddDays(1);
var isRecurring = Random.Shared.Next(0, 1) > 0;
_customSymbol.MarketHours.Holidays.Add(new CustomSymbolTradingHoliday("Test " + Random.Shared.Next().ToString(), startTime, endTime, isRecurring));
}
private void ShowSymbolDynamicLeverage()
{
Print($"Dynamic Leverage Count: {_customSymbol.Symbol.DynamicLeverage.Count}");
foreach (var leverage in _customSymbol.Symbol.DynamicLeverage)
{
Print($"Volume: {leverage.Volume} | Leverage: {leverage.Leverage}");
}
}
private void OnUpdateSymbolDynamicLeverageButtonClick(ButtonClickEventArgs obj)
{
_customSymbol.DynamicLeverage.Add(new CustomSymbolLeverageTier(Random.Shared.NextDouble() * 100 + 1000, 100 + Random.Shared.Next(0, 100)));
}
private void OnUpdateSymbolSentimentButtonClick(ButtonClickEventArgs obj)
{
_customSymbol.Sentiment.BuyPercentage = _customSymbol.Sentiment.BuyPercentage < 99 ? _customSymbol.Sentiment.BuyPercentage + 1 : _customSymbol.Sentiment.BuyPercentage - 1;
}
private void ShowSymbolSentiment()
{
Print($"Buy: {_customSymbol.Symbol.Sentiment.BuyPercentage} | Sell: {_customSymbol.Symbol.Sentiment.SellPercentage}");
}
private void OnSymbolAdded(SymbolAddedEventArgs args)
{
Print($"Symbol Added: {args.SymbolName}");
}
private void OnSymbolRemoved(SymbolRemovedEventArgs args)
{
Print($"Symbol Removed: {args.SymbolName}");
}
private void OnChartManagerFramesAdded(FramesAddedEventArgs obj)
{
if (obj.AddedFrames[0] is not ChartFrame chartFrame)
return;
Print($"New chart frame added, {chartFrame.Symbol.Name} {chartFrame.TimeFrame.Name}");
}
private void OnUpdateLastBarButtonClick(ButtonClickEventArgs obj)
{
var changeAmount = (_customBars.Bars.LastBar.High - _customBars.Bars.LastBar.Low) * (Random.Shared.NextDouble() + 0.5) * 2;
Print($"Changing Last Bar: {_customBars.Bars.LastBar} | change: {changeAmount}");
_customBars.UpdateLastBar(_customBars.Bars.LastBar.Open, _customBars.Bars.LastBar.Open + changeAmount, _customBars.Bars.LastBar.Open - changeAmount, _customBars.Bars.LastBar.Close + changeAmount, (int)_customBars.Bars.LastBar.TickVolume + 1);
}
private void OnRemoveCustomSymbolButtonClick(ButtonClickEventArgs obj)
{
if (!CustomSymbols.Remove(_customSymbol))
return;
Print($"custom symbol '{_customSymbol.Name}' has been removed.");
_customSymbol = null;
}
private void OnUpdateSymbolBaseAssetButtonClick(ButtonClickEventArgs obj)
{
_customSymbol.BaseAsset = Assets.GetAsset(Assets.First(a => a != _customSymbol.BaseAsset.Name && a != _customSymbol.QuoteAsset.Name));
ShowSymbolAssets();
}
private void OnUpdateSymbolQuoteAssetButtonClick(ButtonClickEventArgs obj)
{
_customSymbol.QuoteAsset = Assets.GetAsset(Assets.First(a => a != _customSymbol.BaseAsset.Name && a != _customSymbol.QuoteAsset.Name));
ShowSymbolAssets();
}
private void ShowSymbolAssets()
{
Print($"Base Asset: {_customSymbol.Symbol.BaseAsset.Name} | Quote Asset: {_customSymbol.Symbol.QuoteAsset.Name}");
}
private void OnDisplayChartInfoButtonClick(ButtonClickEventArgs obj)
{
foreach (var frame in ChartManager)
{
if (frame is not ChartFrame chartFrame)
continue;
Print($"Chart, {chartFrame.Symbol.Name} {chartFrame.TimeFrame.Name}");
}
}
private void OnChangeDescriptionButtonClick(ButtonClickEventArgs obj)
{
_customSymbol.Description = _customSymbol.Description == InitialDescription ? ChangedDescription : InitialDescription;
Print($"Changed description to: {_customSymbol.Description}");
}
private void OnUpdateSymbolPropertiesButtonClick(ButtonClickEventArgs obj)
{
_customSymbol.PipDigits = _customSymbol.PipDigits + 1;
_customSymbol.TickDigits = _customSymbol.TickDigits + 1;
_customSymbol.VolumeInUnitsMin = _customSymbol.VolumeInUnitsMin - 10;
_customSymbol.VolumeInUnitsStep = _customSymbol.VolumeInUnitsStep + 10;
_customSymbol.VolumeInUnitsMax = _customSymbol.VolumeInUnitsMax + 10;
_customSymbol.Commission = _customSymbol.Commission + 1;
_customSymbol.GracePeriod = _customSymbol.GracePeriod + 1;
_customSymbol.LotSize = _customSymbol.LotSize * 2;
_customSymbol.PnLConversionFeeRate = _customSymbol.PnLConversionFeeRate + 1;
_customSymbol.CommissionType = SymbolCommissionType.PercentageOfTradingVolume;
_customSymbol.MinCommission = _customSymbol.MinCommission + 1;
_customSymbol.MinCommissionType = SymbolMinCommissionType.QuoteAsset;
_customSymbol.AdministrativeCharge3DaysRollover = DayOfWeek.Thursday;
_customSymbol.AdministrativeCharge = _customSymbol.AdministrativeCharge + 1;
_customSymbol.SwapPeriod = _customSymbol.SwapPeriod + 1;
_customSymbol.WeekendSwaps = !_customSymbol.WeekendSwaps;
_customSymbol.SwapLong = _customSymbol.SwapLong + 1;
_customSymbol.SwapShort = _customSymbol.SwapShort + 1;
_customSymbol.SwapTimeInMinutes = _customSymbol.SwapTimeInMinutes + 1;
_customSymbol.Swap3DaysRollover = DayOfWeek.Tuesday;
_customSymbol.SwapCalculationType = SymbolSwapCalculationType.Percentage;
_customSymbol.MinDistanceType = SymbolMinDistanceType.Pips;
_customSymbol.MinTakeProfitDistance = _customSymbol.MinTakeProfitDistance + 1;
_customSymbol.MinStopLossDistance = _customSymbol.MinStopLossDistance + 1;
ShowSymbolProperties();
}
private void ShowSymbolProperties()
{
foreach (var property in _customSymbol.Symbol.GetType().GetProperties())
{
Print($"{property.Name}: {property.GetValue(_customSymbol.Symbol)}");
}
}
private void OnPauseOrResumeLoadMoreButtonClick(ButtonClickEventArgs obj)
{
_isLoadMoreEnabled = !_isLoadMoreEnabled;
}
private void OnAddBarsButtonClick(ButtonClickEventArgs obj)
{
if (ChartManager.ActiveFrame is not ChartFrame { Chart: var chart })
return;
var bars = _customSymbol.AddBars(chart.TimeFrame);
Print($"Added Bars, Count: {bars.Bars.Count}, Get: {bars == _customSymbol.GetBars(chart.TimeFrame)}");
}
private void OnRemoveBarsButtonClick(ButtonClickEventArgs obj)
{
if (ChartManager.ActiveFrame is not ChartFrame { Chart: var chart })
return;
var result = _customSymbol.RemoveBars(chart.TimeFrame);
Print($"Removed Bars, Result: {result}, Get is null: {_customSymbol.GetBars(chart.TimeFrame) == null}");
}
private void OnShowRegularBarsInfoButtonClick(ButtonClickEventArgs obj)
{
Print($"Regular Bars, Count: {_customBars.Bars.Count}, LastBar: {_customBars.Bars.LastBar}, FirstBar: {_customBars.Bars[0]}");
}
private void OnAddCustomSymbolWithBaseButtonClick(ButtonClickEventArgs obj)
{
var baseSymbol = Symbols.GetSymbol("EURUSD");
_customSymbol = CustomSymbols.Add("Custom Symbol With Base", baseSymbol);
_customSymbol.Symbol.Sentiment.Updated += OnSymbolSentimentUpdated;
_customSymbol.Description = InitialDescription;
_customSymbol.BarsNeeded = OnCustomSymbolBarsNeeded;
baseSymbol.Tick += OnBaseSymbolTick;
_customSymbol.UpdateQuote(baseSymbol.Bid, baseSymbol.Ask);
Print($"custom symbol '{_customSymbol.Name}' has been added.");
}
private void OnAddCustomSymbolWithoutBaseButtonClick(ButtonClickEventArgs obj)
{
var baseAsset = Account.Asset;
var quoteAsset = Assets.GetAsset(Assets.FirstOrDefault(assetName => assetName != baseAsset.Name));
_customSymbol = CustomSymbols.Add("Custom Symbol Without Base", baseAsset, quoteAsset);
_customSymbol.Symbol.Sentiment.Updated += OnSymbolSentimentUpdated;
_customSymbol.Description = InitialDescription;
_customSymbol.BarsNeeded = OnCustomSymbolBarsNeeded;
var trackingSymbol = Symbols.GetSymbol("EURUSD");
trackingSymbol.Tick += OnBaseSymbolTick;
_customSymbol.UpdateQuote(trackingSymbol.Bid, trackingSymbol.Ask);
Print($"custom symbol '{_customSymbol.Name}' has been added.");
}
private void OnSymbolSentimentUpdated(SymbolSentimentUpdatedEventArgs args)
{
Print($"SentimentUpdated, Buy: {args.Sentiment.BuyPercentage} | Sell: {args.Sentiment.SellPercentage}");
}
private void OnBaseSymbolTick(SymbolTickEventArgs args)
{
if (_customSymbol is null)
{
args.Symbol.Tick -= OnBaseSymbolTick;
return;
}
_customSymbol.UpdateQuote(args.Symbol.Bid, args.Symbol.Ask);
}
private void OnCustomSymbolBarsNeeded(CustomSymbolBarsNeededArgs args)
{
Print($"Bars Needed for custom symbol, Symbol: {args.CustomBars.Symbol}, Name: {args.CustomSymbol.Name}");
_customBars = args.CustomBars;
MarketData.GetBarsAsync(args.CustomBars.TimeFrame, "EURUSD", bars =>
{
Print($"Bars Loaded: {bars.Count}");
Sleep(TimeSpan.FromSeconds(2));
args.CustomBars.AppendBars(bars.Select(bar => new CustomBar(bar.OpenTime, bar.Open, bar.High, bar.Low, bar.Close, (int)bar.TickVolume)));
args.CustomBars.NeedsMore += _ =>
{
if (!_isLoadMoreEnabled)
{
Print("Needs more requested but load more is disabled");
return;
}
Print($"Bars NeedsMore");
bars.LoadMoreHistoryAsync(loadedMoreArgs =>
{
Print($"Bars Loaded more: {loadedMoreArgs.Count}");
if (loadedMoreArgs.Count == 0)
return;
Sleep(TimeSpan.FromSeconds(2));
args.CustomBars.PrependBars(bars.Take(loadedMoreArgs.Count).Select(bar => new CustomBar(bar.OpenTime, bar.Open, bar.High, bar.Low, bar.Close, (int)bar.TickVolume)));
});
};
bars.BarOpened += _ =>
{
if (_customSymbol is null)
return;
args.CustomBars.AppendBar(new CustomBar(bars.LastBar.OpenTime, bars.LastBar.Open, bars.LastBar.High, bars.LastBar.Low, bars.LastBar.Close, bars.LastBar.TickVolume));
};
bars.Tick += _ =>
{
if (_customSymbol is null)
return;
args.CustomBars.UpdateLastBar(bars.LastBar.Open, bars.LastBar.High, bars.LastBar.Low, bars.LastBar.Close, bars.LastBar.TickVolume);
};
});
}
}
import clr
clr.AddReference("cAlgo.API")
from cAlgo.API import *
from System import Action, TimeSpan, Array, DayOfWeek
import random
class Test():
InitialDescription = "This is custom symbol initial description"
ChangedDescription = "This is custom symbol changed description"
def on_start(self):
self.isLoadMoreEnabled = True
self.customSymbol = None
panel = StackPanel()
addCustomSymbolWithBaseButton = Button()
addCustomSymbolWithBaseButton.Text = "Add custom symbol with Base Symbol"
addCustomSymbolWithBaseButton.Click += self.on_add_custom_symbol_with_base_button_click
panel.AddChild(addCustomSymbolWithBaseButton)
addCustomSymbolWithoutBaseButton = Button()
addCustomSymbolWithoutBaseButton.Text = "Add custom symbol without Base Symbol"
addCustomSymbolWithoutBaseButton.Click += self.on_add_custom_symbol_without_base_button_click
panel.AddChild(addCustomSymbolWithoutBaseButton)
removeCustomSymbolButton = Button()
removeCustomSymbolButton.Text = "Remove custom symbol"
removeCustomSymbolButton.Click += self.on_remove_custom_symbol_button_click
panel.AddChild(removeCustomSymbolButton)
displayChartInfoButton = Button()
displayChartInfoButton.Text = "Display Charts Info"
displayChartInfoButton.Click += self.on_display_chart_info_button_click
panel.AddChild(displayChartInfoButton)
changeDescriptionButton = Button()
changeDescriptionButton.Text = "Change Description"
changeDescriptionButton.Click += self.on_change_description_button_click
panel.AddChild(changeDescriptionButton)
updateSymbolPropertiesButton = Button()
updateSymbolPropertiesButton.Text = "Update Symbol Properties"
updateSymbolPropertiesButton.Click += self.on_update_symbol_properties_button_click
panel.AddChild(updateSymbolPropertiesButton)
updateSymbolBaseAssetButton = Button()
updateSymbolBaseAssetButton.Text = "Update Symbol Base Asset"
updateSymbolBaseAssetButton.Click += self.on_update_symbol_base_asset_button_click
panel.AddChild(updateSymbolBaseAssetButton)
updateSymbolQuoteAssetButton = Button()
updateSymbolQuoteAssetButton.Text = "Update Symbol Quote Asset"
updateSymbolQuoteAssetButton.Click += self.on_update_symbol_quote_asset_button_click
panel.AddChild(updateSymbolQuoteAssetButton)
showSymbolPropertiesButton = Button()
showSymbolPropertiesButton.Text = "Show Symbol Properties"
showSymbolPropertiesButton.Click += lambda _: self.show_symbol_properties()
panel.AddChild(showSymbolPropertiesButton)
showSymbolAssetsButton = Button()
showSymbolAssetsButton.Text = "Show Symbol Assets"
showSymbolAssetsButton.Click += lambda _: self.show_symbol_assets()
panel.AddChild(showSymbolAssetsButton)
pauseOrResumeLoadMoreButton = Button()
pauseOrResumeLoadMoreButton.Text = "Pause / Resume Load More"
pauseOrResumeLoadMoreButton.Click += self.on_pause_or_resume_load_more_button_click
panel.AddChild(pauseOrResumeLoadMoreButton)
showRegularBarsInfoButton = Button()
showRegularBarsInfoButton.Text = "Show Regular Bars Info"
showRegularBarsInfoButton.Click += self.on_show_regular_bars_info_button_click
panel.AddChild(showRegularBarsInfoButton)
addBarsButton = Button()
addBarsButton.Text = "Add Bars For Active Chart Symbol"
addBarsButton.Click += self.on_add_bars_button_click
panel.AddChild(addBarsButton)
removeBarsButton = Button()
removeBarsButton.Text = "Remove Bars For Active Chart Symbol"
removeBarsButton.Click += self.on_remove_bars_button_click
panel.AddChild(removeBarsButton)
updateLastBarButton = Button()
updateLastBarButton.Text = "Update Last Bar"
updateLastBarButton.Click += self.on_update_last_bar_button_click
panel.AddChild(updateLastBarButton)
updateSymbolSentimentButton = Button()
updateSymbolSentimentButton.Text = "Update Symbol Sentiment"
updateSymbolSentimentButton.Click += self.on_update_symbol_sentiment_button_click
panel.AddChild(updateSymbolSentimentButton)
showSymbolSentimentButton = Button()
showSymbolSentimentButton.Text = "Show Symbol Sentiment"
showSymbolSentimentButton.Click += lambda _: self.show_symbol_sentiment()
panel.AddChild(showSymbolSentimentButton)
updateSymbolDynamicLeverageButton = Button()
updateSymbolDynamicLeverageButton.Text = "Update Symbol Dynamic Leverage"
updateSymbolDynamicLeverageButton.Click += self.on_update_symbol_dynamic_leverage_button_click
panel.AddChild(updateSymbolDynamicLeverageButton)
showSymbolDynamicLeverageButton = Button()
showSymbolDynamicLeverageButton.Text = "Show Symbol Dynamic Leverage"
showSymbolDynamicLeverageButton.Click += lambda _: self.show_symbol_dynamic_leverage()
panel.AddChild(showSymbolDynamicLeverageButton)
updateSymbolHolidaysButton = Button()
updateSymbolHolidaysButton.Text = "Update Symbol Holidays"
updateSymbolHolidaysButton.Click += self.on_update_symbol_holidays_button_click
panel.AddChild(updateSymbolHolidaysButton)
showSymbolHolidaysButton = Button()
showSymbolHolidaysButton.Text = "Show Symbol Holidays"
showSymbolHolidaysButton.Click += self.on_show_symbol_holidays_button_click
panel.AddChild(showSymbolHolidaysButton)
updateSymbolSessionsButton = Button()
updateSymbolSessionsButton.Text = "Update Symbol Sessions"
updateSymbolSessionsButton.Click += self.on_update_symbol_sessions_button_click
panel.AddChild(updateSymbolSessionsButton)
showSymbolSessionsButton = Button()
showSymbolSessionsButton.Text = "Show Symbol Sessions"
showSymbolSessionsButton.Click += self.on_show_symbol_sessions_button_click
panel.AddChild(showSymbolSessionsButton)
updateSymbolFuturesSettingsButton = Button()
updateSymbolFuturesSettingsButton.Text = "Update Symbol Futures Settings"
updateSymbolFuturesSettingsButton.Click += self.on_update_symbol_futures_settings_button_click
panel.AddChild(updateSymbolFuturesSettingsButton)
showSymbolFuturesSettingsButton = Button()
showSymbolFuturesSettingsButton.Text = "Show Symbol Futures Settings"
showSymbolFuturesSettingsButton.Click += self.on_show_symbol_futures_settings_button_click
panel.AddChild(showSymbolFuturesSettingsButton)
block = api.Asp.SymbolTab.AddBlock("Custom symbol Test")
block.Child = panel
block.Height = 550
api.ChartManager.FramesAdded += self.on_chart_manager_frames_addded
api.Symbols.Added += self.on_symbol_added
api.Symbols.Removed += self.on_symbol_removed
def on_add_custom_symbol_with_base_button_click(self, args):
baseSymbol = api.Symbols.GetSymbol("EURUSD")
self.customSymbol = api.CustomSymbols.Add("Custom Symbol With Base", baseSymbol)
self.customSymbol.Symbol.Sentiment.Updated += self.on_symbol_sentiment_updated
self.customSymbol.Description = self.InitialDescription
self.customSymbol.BarsNeeded = Action[CustomSymbolBarsNeededArgs](self.on_custom_symbol_bars_needed)
baseSymbol.Tick += self.on_base_symbol_tick
self.customSymbol.UpdateQuote(baseSymbol.Bid, baseSymbol.Ask)
print(f"custom symbol '{self.customSymbol.Name}' has been added.")
def on_add_custom_symbol_without_base_button_click(self, args):
baseAsset = api.Account.Asset
quoteAsset = api.Assets.GetAsset(next((assetName for assetName in api.Assets if assetName != baseAsset.Name)))
self.customSymbol = api.CustomSymbols.Add("Custom Symbol Without Base", baseAsset, quoteAsset)
self.customSymbol.Symbol.Sentiment.Updated += self.on_symbol_sentiment_updated
self.customSymbol.Description = self.InitialDescription
self.customSymbol.BarsNeeded = Action[CustomSymbolBarsNeededArgs](self.on_custom_symbol_bars_needed)
trackingSymbol = api.Symbols.GetSymbol("EURUSD")
trackingSymbol.Tick += self.on_base_symbol_tick
self.customSymbol.UpdateQuote(trackingSymbol.Bid, trackingSymbol.Ask)
print(f"custom symbol '{self.customSymbol.Name}' has been added.")
def on_symbol_sentiment_updated(self, args):
print(f"SentimentUpdated, Buy: {args.Sentiment.BuyPercentage} | Sell: {args.Sentiment.SellPercentage}")
def on_custom_symbol_bars_needed(self, args):
print(f"Bars Needed for custom symbol, Symbol: {args.CustomBars.Symbol}, Name: {args.CustomSymbol.Name}")
self.customBars = args.CustomBars
api.MarketData.GetBarsAsync(args.CustomBars.TimeFrame, "EURUSD", Action[Bars](self.on_bars_received))
def on_bars_received(self, bars):
print(f"Bars Loaded: {bars.Count}")
api.Sleep(2000)
self.customBars.AppendBars(self.to_array([CustomBar(bar.OpenTime, bar.Open, bar.High, bar.Low, bar.Close, int(bar.TickVolume)) for bar in bars], CustomBar))
self.customBars.NeedsMore += lambda args: self.on_custom_bars_needs_more(bars, args.CustomBars)
bars.BarOpened += lambda args: self.on_bar_opened(self.customBars, args.Bars)
bars.Tick += lambda args: self.on_tick(self.customBars, args.Bars)
def on_custom_bars_needs_more(self, bars, customBars):
if self.isLoadMoreEnabled is False:
print("Needs more requested but load more is disabled")
return
print("Bars NeedsMore")
bars.LoadMoreHistoryAsync(Action[BarsHistoryLoadedEventArgs](lambda args: self.on_bars_more_history_loaded(customBars, bars, args.Count)))
def on_bars_more_history_loaded(self, customBars, bars, loadedCount):
print(f"Bars Loaded more: {loadedCount}")
if loadedCount == 0:
return
api.Sleep(2000)
loadedBars = []
for i, bar in enumerate(bars):
if i >= loadedCount:
break
loadedBars.append(CustomBar(bar.OpenTime, bar.Open, bar.High, bar.Low, bar.Close, int(bar.TickVolume)))
customBars.PrependBars(self.to_array(loadedBars, CustomBar))
def on_bar_opened(self, customBars, bars):
if self.customSymbol is None:
return
customBars.AppendBar(CustomBar(bars.LastBar.OpenTime, bars.LastBar.Open, bars.LastBar.High, bars.LastBar.Low, bars.LastBar.Close, bars.LastBar.TickVolume))
def on_tick(self, customBars, bars):
if self.customSymbol is None:
return
customBars.UpdateLastBar(bars.LastBar.Open, bars.LastBar.High, bars.LastBar.Low, bars.LastBar.Close, bars.LastBar.TickVolume)
def on_base_symbol_tick(self, args):
if self.customSymbol is None:
args.Symbol.Tick -= self.on_base_symbol_tick
return
self.customSymbol.UpdateQuote(args.Symbol.Bid, args.Symbol.Ask)
def on_remove_custom_symbol_button_click(self, args):
if api.CustomSymbols.Remove(self.customSymbol):
return
print(f"custom symbol '{self.customSymbol.Name}' has been removed.")
self.customSymbol = None
def on_display_chart_info_button_click(self, args):
for frame in api.ChartManager:
if isinstance(frame.__implementation__, ChartFrame) == False:
continue
chartFrame = ChartFrame(frame)
print(f"Chart, {chartFrame.Symbol.Name} {chartFrame.TimeFrame.Name}")
def on_change_description_button_click(self, args):
self.customSymbol.Description = self.ChangedDescription if self.customSymbol.Description == self.InitialDescription else self.InitialDescription
print(f"Changed description to: {self.customSymbol.Description}")
def on_update_symbol_properties_button_click(self, args):
self.customSymbol.PipDigits = self.customSymbol.PipDigits + 1
self.customSymbol.TickDigits = self.customSymbol.TickDigits + 1
self.customSymbol.VolumeInUnitsMin = self.customSymbol.VolumeInUnitsMin - 10
self.customSymbol.VolumeInUnitsStep = self.customSymbol.VolumeInUnitsStep + 10
self.customSymbol.VolumeInUnitsMax = self.customSymbol.VolumeInUnitsMax + 10
self.customSymbol.Commission = self.customSymbol.Commission + 1
self.customSymbol.GracePeriod = self.customSymbol.GracePeriod + 1
self.customSymbol.LotSize = self.customSymbol.LotSize * 2
self.customSymbol.PnLConversionFeeRate = self.customSymbol.PnLConversionFeeRate + 1
self.customSymbol.CommissionType = SymbolCommissionType.PercentageOfTradingVolume
self.customSymbol.MinCommission = self.customSymbol.MinCommission + 1
self.customSymbol.MinCommissionType = SymbolMinCommissionType.QuoteAsset
self.customSymbol.AdministrativeCharge3DaysRollover = DayOfWeek.Thursday
self.customSymbol.AdministrativeCharge = self.customSymbol.AdministrativeCharge + 1
self.customSymbol.SwapPeriod = self.customSymbol.SwapPeriod + 1
self.customSymbol.WeekendSwaps = not self.customSymbol.WeekendSwaps
self.customSymbol.SwapLong = self.customSymbol.SwapLong + 1
self.customSymbol.SwapShort = self.customSymbol.SwapShort + 1
self.customSymbol.SwapTimeInMinutes = self.customSymbol.SwapTimeInMinutes + 1
self.customSymbol.Swap3DaysRollover = DayOfWeek.Tuesday
self.customSymbol.SwapCalculationType = SymbolSwapCalculationType.Percentage
self.customSymbol.MinDistanceType = SymbolMinDistanceType.Pips
self.customSymbol.MinTakeProfitDistance = self.customSymbol.MinTakeProfitDistance + 1
self.customSymbol.MinStopLossDistance = self.customSymbol.MinStopLossDistance + 1
self.show_symbol_properties()
def to_array(self, iterable, itemType):
length = len(iterable)
array = Array[itemType](length)
for i in range(length):
array[i] = iterable[i]
return array
def show_symbol_properties(self):
for propertyInfo in self.customSymbol.Symbol.GetType().GetProperties():
print(f"{propertyInfo.Name}: {propertyInfo.GetValue(self.customSymbol.Symbol)}")
def on_update_symbol_base_asset_button_click(self, args):
self.customSymbol.BaseAsset = api.Assets.GetAsset(next((assetName for assetName in api.Assets if assetName != self.customSymbol.BaseAsset.Name and assetName != self.customSymbol.QuoteAsset.Name)))
self.show_symbol_assets()
def on_update_symbol_quote_asset_button_click(self, args):
self.customSymbol.QuoteAsset = api.Assets.GetAsset(next((assetName for assetName in api.Assets if assetName != self.customSymbol.BaseAsset.Name and assetName != self.customSymbol.QuoteAsset.Name)))
self.show_symbol_assets()
def show_symbol_assets(self):
print(f"Base Asset: {self.customSymbol.Symbol.BaseAsset.Name} | Quote Asset: {self.customSymbol.Symbol.QuoteAsset.Name}")
def on_pause_or_resume_load_more_button_click(self, args):
self.isLoadMoreEnabled = not self.isLoadMoreEnabled
def on_show_regular_bars_info_button_click(self, args):
print(f"Regular Bars, Count: {self.customBars.Bars.Count}, LastBar: {self.customBars.Bars.LastBar}, FirstBar: {self.customBars.Bars[0]}")
def on_add_bars_button_click(self, args):
if isinstance(api.ChartManager.ActiveFrame.__implementation__, ChartFrame) == False:
return
chart = ChartFrame(api.ChartManager.ActiveFrame).Chart
bars = self.customSymbol.AddBars(chart.TimeFrame)
print(f"Added Bars, Count: {bars.Bars.Count}, Get: {bars == self.customSymbol.GetBars(chart.TimeFrame)}")
def on_remove_bars_button_click(self, args):
if isinstance(api.ChartManager.ActiveFrame.__implementation__, ChartFrame) == False:
return
chart = ChartFrame(api.ChartManager.ActiveFrame).Chart
result = self.customSymbol.RemoveBars(chart.TimeFrame)
print(f"Removed Bars, Result: {result}, Get is None: {self.customSymbol.GetBars(chart.TimeFrame) is None}")
def on_update_last_bar_button_click(self, args):
changeAmount = (self.customBars.Bars.LastBar.High - self.customBars.Bars.LastBar.Low) * (random.random() + 0.5) * 2
print(f"Changing Last Bar: {self.customBars.Bars.LastBar} | change: {changeAmount}")
bars = self.customBars.Bars
self.customBars.UpdateLastBar(bars.LastBar.Open, bars.LastBar.Open + changeAmount, bars.LastBar.Open - changeAmount, bars.LastBar.Close + changeAmount, int(bars.LastBar.TickVolume + 1))
def on_update_symbol_sentiment_button_click(self, args):
self.customSymbol.Sentiment.BuyPercentage = self.customSymbol.Sentiment.BuyPercentage + 1 if self.customSymbol.Sentiment.BuyPercentage < 99 else self.customSymbol.Sentiment.BuyPercentage - 1
def show_symbol_sentiment(self):
print(f"Buy: {self.customSymbol.Symbol.Sentiment.BuyPercentage} | Sell: {self.customSymbol.Symbol.Sentiment.SellPercentage}")
def on_update_symbol_dynamic_leverage_button_click(self, args):
self.customSymbol.DynamicLeverage.Add(CustomSymbolLeverageTier(random.random() * 100 + 1000, 100 + random.randint(0, 100)))
def show_symbol_dynamic_leverage(self):
print(f"Dynamic Leverage Count: {self.customSymbol.Symbol.DynamicLeverage.Count}")
for leverage in self.customSymbol.Symbol.DynamicLeverage:
print(f"Volume: {leverage.Volume} | Leverage: {leverage.Leverage}")
def on_update_symbol_holidays_button_click(self, args):
startTime = api.Server.Time.AddMonths(random.randint(1, 3))
endTime = startTime.AddDays(1)
isRecurring = random.randint(0, 1) > 0
self.customSymbol.MarketHours.Holidays.Add(CustomSymbolTradingHoliday(f"Test {self.customSymbol.MarketHours.Holidays.Count}", startTime, endTime, isRecurring))
def on_show_symbol_holidays_button_click(self, args):
print(f"Holidays Count: {self.customSymbol.Symbol.MarketHours.Holidays.Count}")
for holiday in self.customSymbol.Symbol.MarketHours.Holidays:
print(f"Name: {holiday.Name} | Start: {holiday.StartTime} | End: {holiday.EndTime} | Is Recurring: {holiday.IsRecurring}")
def on_update_symbol_sessions_button_click(self, args):
startDay = DayOfWeek(random.randint(0, 6))
endDay = DayOfWeek(int(startDay) + 1)
startTime = TimeSpan.FromHours(random.randint(0, 22))
endTime = startTime.Add(TimeSpan.FromHours(1))
self.customSymbol.MarketHours.Sessions.Add(CustomSymbolTradingSession(startDay, endDay, startTime, endTime))
def on_show_symbol_sessions_button_click(self, args):
print(f"Sessions Count: {self.customSymbol.Symbol.MarketHours.Sessions.Count}")
for session in self.customSymbol.Symbol.MarketHours.Sessions:
print(f"Start Day: {session.StartDay} | End Day: {session.EndDay} | Start Time: {session.StartTime} | End Time: {session.EndTime}")
def on_update_symbol_futures_settings_button_click(self, args):
self.customSymbol.FuturesSettings = CustomSymbolFuturesSettings(api.Server.Time, api.Server.Time.AddMonths(random.randint(1, 10)), random.random() * 100 + 1000)
def on_show_symbol_futures_settings_button_click(self, args):
symbol = self.customSymbol.Symbol
print(f"Last Trade Time: {symbol.FuturesSettings.LastTradeTime} | Expiration Time: {symbol.FuturesSettings.ExpirationTime} | Maintenance Margin: {symbol.FuturesSettings.MaintenanceMargin}")
def on_chart_manager_frames_addded(self, args):
for frame in args.AddedFrames:
if isinstance(frame.__implementation__, ChartFrame) == False:
continue
chartFrame = ChartFrame(frame)
print(f"New chart frame added, {chartFrame.Symbol.Name} {chartFrame.TimeFrame.Name}")
def on_symbol_added(self, args):
print(f"Symbol Added: {args.SymbolName}")
def on_symbol_removed(self, args):
print(f"Symbol Removed: {args.SymbolName}")
{
"AccessRights": "None"
}
Methods
| Name | Description |
|---|---|
Add 2 overloadsDesktopCLICloudCustomSymbol | Adds a new custom symbol. |
GetDesktopCLICloudCustomSymbol | Returns a custom symbol by it's name. |
RemoveDesktopCLICloudbool | Removes a custom symbol. |