Skip to content

Commit d39dfaa

Browse files
committed
Stream
1 parent 789cc65 commit d39dfaa

File tree

17 files changed

+72
-67
lines changed

17 files changed

+72
-67
lines changed

Core/Core/Conventions/Gateway.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Core.Enums;
22
using Core.Models;
33
using Orleans;
4-
using Orleans.Streams;
54
using System;
65
using System.Linq;
76
using System.Threading.Tasks;
@@ -23,13 +22,13 @@ public interface ITradeObserver : IGrainObserver
2322
/// Price message
2423
/// </summary>
2524
/// <param name="instrument"></param>
26-
void StreamPrice(Instrument instrument);
25+
Task StreamView(Instrument instrument);
2726

2827
/// <summary>
2928
/// Price message
3029
/// </summary>
3130
/// <param name="instrument"></param>
32-
Task StreamInstrument(Instrument instrument);
31+
Task StreamTrade(Instrument instrument);
3332
}
3433

3534
public interface IGateway
@@ -47,12 +46,12 @@ public interface IGateway
4746
/// <summary>
4847
/// Price message
4948
/// </summary>
50-
Action<Instrument> OnPrice { get; set; }
49+
Func<Instrument, Task> OnView { get; set; }
5150

5251
/// <summary>
5352
/// Trade message
5453
/// </summary>
55-
Func<Instrument, Task> OnInstrument { get; set; }
54+
Func<Instrument, Task> OnTrade { get; set; }
5655

5756
/// <summary>
5857
/// Connect
@@ -166,12 +165,12 @@ public abstract class Gateway : IGateway, ITradeObserver
166165
/// <summary>
167166
/// Price message
168167
/// </summary>
169-
public virtual Action<Instrument> OnPrice { get; set; } = o => { };
168+
public virtual Func<Instrument, Task> OnView { get; set; } = o => Task.CompletedTask;
170169

171170
/// <summary>
172171
/// Trade message
173172
/// </summary>
174-
public virtual Func<Instrument, Task> OnInstrument { get; set; } = o => Task.CompletedTask;
173+
public virtual Func<Instrument, Task> OnTrade { get; set; } = o => Task.CompletedTask;
175174

176175
/// <summary>
177176
/// Order message
@@ -183,13 +182,13 @@ public abstract class Gateway : IGateway, ITradeObserver
183182
/// Price message
184183
/// </summary>
185184
/// <param name="instrument"></param>
186-
public virtual void StreamPrice(Instrument instrument) => OnPrice(instrument);
185+
public virtual Task StreamView(Instrument instrument) => OnView(instrument);
187186

188187
/// <summary>
189188
/// Price message
190189
/// </summary>
191190
/// <param name="instrument"></param>
192-
public virtual Task StreamInstrument(Instrument instrument) => OnInstrument(instrument);
191+
public virtual Task StreamTrade(Instrument instrument) => OnTrade(instrument);
193192

194193
/// <summary>
195194
/// Connect

Dashboard/Dashboard/Pages/BasePage.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ protected override async Task OnAfterRenderAsync(bool setup)
6464

6565
foreach (var adapter in Adapters.Values)
6666
{
67-
adapter.OnPrice = OnViewUpdate;
68-
adapter.OnInstrument = OnTradeUpdate;
67+
adapter.OnView = OnViewUpdate;
68+
adapter.OnTrade = OnTradeUpdate;
6969
}
7070
}
7171
});
@@ -79,7 +79,7 @@ protected override async Task OnAfterRenderAsync(bool setup)
7979
/// </summary>
8080
protected virtual Task OnView() => Task.CompletedTask;
8181
protected virtual Task OnTrade() => Task.CompletedTask;
82-
protected virtual void OnViewUpdate(Instrument instrument) { }
82+
protected virtual Task OnViewUpdate(Instrument instrument) => Task.CompletedTask;
8383
protected virtual Task OnTradeUpdate(Instrument instrument) => Task.CompletedTask;
8484

8585
/// <summary>

Dashboard/Dashboard/Pages/Futures/Covariance.razor.cs

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@
1313

1414
namespace Dashboard.Pages.Futures
1515
{
16+
public class Indexer : List<(long, double)>
17+
{
18+
public new void Add((long, double) item)
19+
{
20+
if (Count is 0 || item.Item1 > this[^1].Item1)
21+
{
22+
base.Add(item);
23+
}
24+
25+
this[^1] = item;
26+
}
27+
}
28+
1629
public partial class Covariance
1730
{
1831
ControlsComponent View { get; set; }
@@ -27,13 +40,18 @@ public partial class Covariance
2740
PerformanceIndicator Performance { get; set; }
2841
Dictionary<string, ScaleIndicator> Scales { get; set; }
2942

43+
int Direction { get; set; } = 0;
3044
double Deviation { get; set; } = 2;
45+
Indexer Scores { get; set; } = new();
3146
AverageService AverageService { get; set; } = new();
3247

48+
const string nameX = "ESU25";
49+
const string nameY = "NQU25";
50+
3351
Dictionary<string, Instrument> Instruments = new()
3452
{
35-
["ESU25"] = new() { Name = "ESU25", StepValue = 12.50, StepSize = 0.25, Leverage = 50, Commission = 3.65, TimeFrame = TimeSpan.FromSeconds(1) },
36-
["NQU25"] = new() { Name = "NQU25", StepValue = 5, StepSize = 0.25, Leverage = 20, Commission = 3.65, TimeFrame = TimeSpan.FromSeconds(1) },
53+
[nameX] = new() { Name = nameX, StepValue = 12.50, StepSize = 0.25, Leverage = 50, Commission = 3.65 },
54+
[nameY] = new() { Name = nameY, StepValue = 5, StepSize = 0.25, Leverage = 20, Commission = 3.65 },
3755
};
3856

3957
protected override async Task OnView()
@@ -74,16 +92,16 @@ protected override Task OnTrade()
7492
return base.OnTrade();
7593
}
7694

77-
protected override async void OnViewUpdate(Instrument instrument)
95+
protected override async Task OnViewUpdate(Instrument instrument)
7896
{
7997
var adapter = Adapter;
8098
var account = adapter.Account;
8199
var price = instrument.Price;
82100
var index = price.Bar.Time.Value;
83-
var assetX = account.Instruments["ESU25"];
84-
var assetY = account.Instruments["NQU25"];
85-
var seriesX = (await adapter.GetPriceGroups(new Criteria { Count = 100, Instrument = assetX })).Data;
86-
var seriesY = (await adapter.GetPriceGroups(new Criteria { Count = 100, Instrument = assetY })).Data;
101+
var assetX = account.Instruments[nameX];
102+
var assetY = account.Instruments[nameY];
103+
var seriesX = (await adapter.GetPrices(new() { Count = 100, Instrument = assetX })).Data;
104+
var seriesY = (await adapter.GetPrices(new() { Count = 100, Instrument = assetY })).Data;
87105

88106
if (seriesX.Count is 0 || seriesY.Count is 0)
89107
{
@@ -113,18 +131,18 @@ protected override async void OnViewUpdate(Instrument instrument)
113131

114132
protected override async Task OnTradeUpdate(Instrument instrument)
115133
{
116-
if (Equals(instrument.Name, "ESU25") is false)
134+
if (Equals(instrument.Name, nameX) is false)
117135
{
118136
return;
119137
}
120138

121139
var price = instrument.Price;
122140
var adapter = Adapter;
123141
var account = adapter.Account;
124-
var assetX = account.Instruments["ESU25"];
125-
var assetY = account.Instruments["NQU25"];
126-
var seriesX = (await adapter.GetPrices(new Criteria { Count = 100, Instrument = assetX })).Data;
127-
var seriesY = (await adapter.GetPrices(new Criteria { Count = 100, Instrument = assetY })).Data;
142+
var assetX = account.Instruments[nameX];
143+
var assetY = account.Instruments[nameY];
144+
var seriesX = (await adapter.GetPrices(new() { Count = 100, Instrument = assetX })).Data;
145+
var seriesY = (await adapter.GetPrices(new() { Count = 100, Instrument = assetY })).Data;
128146

129147
if (seriesX.Count is 0 || seriesY.Count is 0)
130148
{
@@ -142,30 +160,24 @@ protected override async Task OnTradeUpdate(Instrument instrument)
142160
var retSeriesY = seriesY.Select(o => o.Last.Value * assetY.Leverage.Value).ToArray();
143161
var beta = CalculateHedgeRatio(retSeriesX, retSeriesY);
144162
var score = CalculateZScore(retSeriesX, retSeriesY, beta, (priceX.Last * assetX.Leverage.Value - beta * priceY.Last * assetY.Leverage.Value).Value);
145-
var isLong = score < -Deviation;
146-
var isShort = score > Deviation;
147163

148-
if (Equals(price.Bar.Time, scores.LastOrDefault().Item1))
149-
{
150-
scores[scores.Count - 1] = (price.Bar.Time.Value, score);
151-
}
152-
else
153-
{
154-
scores.Add((price.Bar.Time.Value, score));
155-
}
164+
Scores.Add((price.Bar.Time.Value, score));
156165

157-
var prevScore = scores.ElementAtOrDefault(scores.Count - 2).Item2;
166+
var isLong = score < -Deviation;
167+
var isShort = score > Deviation;
158168

159169
if (positions.Count is 0)
160170
{
161171
switch (true)
162172
{
163173
case true when isLong:
174+
Direction = 1;
164175
await OpenPosition(adapter, assetX, OrderSideEnum.Long);
165176
await OpenPosition(adapter, assetY, OrderSideEnum.Short);
166177
break;
167178

168179
case true when isShort:
180+
Direction = -1;
169181
await OpenPosition(adapter, assetX, OrderSideEnum.Short);
170182
await OpenPosition(adapter, assetY, OrderSideEnum.Long);
171183
break;
@@ -174,9 +186,9 @@ protected override async Task OnTradeUpdate(Instrument instrument)
174186

175187
if (positions.Count is not 0)
176188
{
177-
var pos = positions.First();
178-
var closeLong = pos.Side is OrderSideEnum.Long && prevScore > 0;
179-
var closeShort = pos.Side is OrderSideEnum.Short && prevScore < 0;
189+
var prevScore = Scores.ElementAtOrDefault(Scores.Count - 1).Item2;
190+
var closeLong = Direction is 1 && prevScore > 0;
191+
var closeShort = Direction is -1 && prevScore < 0;
180192

181193
if (closeLong || closeShort)
182194
{
@@ -186,8 +198,6 @@ protected override async Task OnTradeUpdate(Instrument instrument)
186198
}
187199
}
188200

189-
List<(long, double)> scores = new();
190-
191201
/// <summary>
192202
/// Calculates the Hedge Ratio (Beta) between two time series (Y vs X) using simple linear regression.
193203
/// This should be calculated over a long look-back window (e.g., 252 daily bars).

Dashboard/Dashboard/Pages/Futures/Leads.razor.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public partial class Leads
2626
PerformanceIndicator Performance { get; set; }
2727
Dictionary<string, ScaleIndicator> Scales { get; set; }
2828

29+
double ActionableSpread { get; set; } = 0.1;
2930
Price PreviousLeader { get; set; }
3031
Price PreviousFollower { get; set; }
3132

@@ -73,15 +74,15 @@ protected override Task OnTrade()
7374
return base.OnTrade();
7475
}
7576

76-
protected override async void OnViewUpdate(Instrument instrument)
77+
protected override async Task OnViewUpdate(Instrument instrument)
7778
{
7879
var price = instrument.Price;
7980
var adapter = Adapter;
8081
var account = adapter.Account;
8182
var assetX = account.Instruments["ESU25"];
8283
var assetY = account.Instruments["NQU25"];
83-
var seriesX = (await adapter.GetPrices(new Criteria { Count = 1, Instrument = assetX })).Data;
84-
var seriesY = (await adapter.GetPrices(new Criteria { Count = 1, Instrument = assetY })).Data;
84+
var seriesX = (await adapter.GetPrices(new() { Count = 1, Instrument = assetX })).Data;
85+
var seriesY = (await adapter.GetPrices(new() { Count = 1, Instrument = assetY })).Data;
8586

8687
if (seriesX.Count is 0 || seriesY.Count is 0)
8788
{
@@ -137,7 +138,7 @@ protected override async Task OnTradeUpdate(Instrument instrument)
137138

138139
if (orders.Count is 0)
139140
{
140-
if (PreviousLeader is not null && positions.Count is 0 && spread > 0.1)
141+
if (PreviousLeader is not null && positions.Count is 0 && spread > ActionableSpread)
141142
{
142143
var isLong = scaleX.Response.Last > PreviousLeader.Last && scaleX.Response.Last > scaleY.Response.Last;
143144
var isShort = scaleX.Response.Last < PreviousLeader.Last && scaleX.Response.Last < scaleY.Response.Last;

Dashboard/Dashboard/Pages/Gateways/CoinDemo.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ protected override Task OnTrade()
6060
return base.OnTrade();
6161
}
6262

63-
protected override async void OnViewUpdate(Instrument instrument)
63+
protected override async Task OnViewUpdate(Instrument instrument)
6464
{
6565
var adapter = Adapter;
6666
var price = instrument.Price;

Dashboard/Dashboard/Pages/Gateways/InterBrokerDemo.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ protected override Task OnTrade()
5858
return base.OnTrade();
5959
}
6060

61-
protected override async void OnViewUpdate(Instrument instrument)
61+
protected override async Task OnViewUpdate(Instrument instrument)
6262
{
6363
var adapter = Adapter;
6464
var price = instrument.Price;

Dashboard/Dashboard/Pages/Options/BreakProtection.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ protected override Task OnTrade()
9797
return base.OnTrade();
9898
}
9999

100-
protected override async void OnViewUpdate(Instrument instrument)
100+
protected override async Task OnViewUpdate(Instrument instrument)
101101
{
102102
var adapter = Adapter;
103103
var price = instrument.Price;

Dashboard/Dashboard/Pages/Options/ShortDelta.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ protected override Task OnTrade()
6060
return base.OnTrade();
6161
}
6262

63-
protected override async void OnViewUpdate(Instrument instrument)
63+
protected override async Task OnViewUpdate(Instrument instrument)
6464
{
6565
var price = instrument.Price;
6666
var adapter = Adapter;

Dashboard/Dashboard/Pages/Shares/Convex.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ protected override Task OnTrade()
6363
return base.OnTrade();
6464
}
6565

66-
protected override async void OnViewUpdate(Instrument instrument)
66+
protected override async Task OnViewUpdate(Instrument instrument)
6767
{
6868
if (instrument.Name == AssetY)
6969
{

Dashboard/Dashboard/Pages/Shares/ConvexFade.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ protected override Task OnTrade()
5858
return base.OnTrade();
5959
}
6060

61-
protected override async void OnViewUpdate(Instrument instrument)
61+
protected override async Task OnViewUpdate(Instrument instrument)
6262
{
6363
var price = instrument.Price;
6464
var account = Adapter.Account;

0 commit comments

Comments
 (0)