1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351 | using System;
using cAlgo.API;
using cAlgo.API.Internals;
using System.Linq;
namespace cAlgo.Plugins;
[Plugin(AccessRights = AccessRights.None)]
public 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 block = Asp.SymbolTab.AddBlock("custom symbol Test");
var updateSymbolHolidaysButton = new Button { Text = "Update Symbol Holidays" };
updateSymbolHolidaysButton.Click += OnUpdateSymbolHolidaysButtonClick;
panel.AddChild(updateSymbolHolidaysButton);
var showSymbolHolidaysButton = new Button { Text = "Show Symbol Holidays" };
showSymbolHolidaysButton.Click += _ => ShowSymbolHolidays();
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 += _ => ShowSymbolSessions();
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 += _ => ShowSymbolFuturesSettings();
panel.AddChild(showSymbolFuturesSettingsButton);
block.Child = panel;
block.Height = 550;
ChartManager.FramesAdded += OnChartManagerFramesAdded;
Symbols.Added += OnSymbolAdded;
Symbols.Removed += OnSymbolRemoved;
}
private void ShowSymbolFuturesSettings()
{
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 ShowSymbolSessions()
{
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 ShowSymbolHolidays()
{
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 ? true : false;
_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)
{
DisplayChartsInfo();
}
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", Symbols.GetSymbol("EURUSD"));
_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 DisplayChartsInfo()
{
foreach (var frame in ChartManager)
{
if (frame is not ChartFrame chartFrame)
continue;
Print($"Chart, {chartFrame.Symbol.Name} {chartFrame.TimeFrame.Name}");
}
}
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, Symbols.GetSymbol("EURUSD").Name, 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);
};
});
}
}
|