Skip to content

Commit

Permalink
when starting call reference service to get prices before subscriptio…
Browse files Browse the repository at this point in the history
…ns kick in
  • Loading branch information
mpisanko committed Sep 3, 2024
1 parent 54e2d5a commit a08ed03
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 54 deletions.
10 changes: 9 additions & 1 deletion web-front-end/angular/main/app/service/symbols.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import { environment } from 'main/environments/environment';
})
export class SymbolService {
private stocksUrl = `${environment.referenceServiceUrl}/stocks`;
private priceUrl = `${environment.referenceServiceUrl}/price/`;
private priceUrl = `${environment.referenceServiceUrl}/price`;
private pricesUrl = `${environment.referenceServiceUrl}/prices`;
private createTicketUrl = `${environment.tradesUrl}`;
constructor(private http: HttpClient) { }

Expand All @@ -35,6 +36,13 @@ export class SymbolService {
);
}

getAccountPrices(accountId: number): Observable<StockPrice[]> {
return this.http.get<StockPrice[]>(`${this.pricesUrl}/${accountId}`).pipe(
retry(2),
catchError(this.handleError)
);
}

private handleError(error: HttpErrorResponse) {
console.error(error);
return throwError(() => error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('PositionBlotterComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(ClosedPositionBlotterComponent);
component = fixture.componentInstance;
component.filteredPositions = positions;
component.positions = positions;
fixture.detectChanges();
});

Expand All @@ -46,8 +46,8 @@ describe('PositionBlotterComponent', () => {
expect(columns.length).toEqual(2);
expect(rows.length).toEqual(2);
const firstRow = rows[0];
expect(firstRow.children[0].innerText).toEqual(component.filteredPositions[0].security);
expect(firstRow.children[1].innerText).toEqual(component.filteredPositions[0].value.toString());
expect(firstRow.children[0].innerText).toEqual(component.positions[0].security);
expect(firstRow.children[1].innerText).toEqual(component.positions[0].value.toString());
});

});
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/
import { Account } from 'main/app/model/account.model';
import { Position, StockPrice } from 'main/app/model/trade.model';
import { PositionService } from 'main/app/service/position.service';
import { SymbolService } from 'main/app/service/symbols.service';
import { Observable } from 'rxjs';
import { TradeFeedService } from 'main/app/service/trade-feed.service';

Expand All @@ -14,10 +15,8 @@ import { TradeFeedService } from 'main/app/service/trade-feed.service';
export class ClosedPositionBlotterComponent implements OnChanges, OnDestroy {
@Input() account?: Account;
positions$: Observable<Position[]>;
filteredPositions: any = [];
positions: any = [];
gridApi: GridApi;
pendingPosition: any[] = [];
isPending = true;
socketUnSubscribeFn: Function;
marketValueUnSubscribeFn: Function;
title = 'Closed Positions';
Expand All @@ -39,28 +38,35 @@ export class ClosedPositionBlotterComponent implements OnChanges, OnDestroy {
];

constructor(private tradeService: PositionService,
private tradeFeed: TradeFeedService) { }
private tradeFeed: TradeFeedService,
private symbolService: SymbolService) { }

ngOnChanges(change: SimpleChanges) {
console.log('Position blotter changes...', change);
if (change.account?.currentValue && change.account.currentValue !== change.account.previousValue) {
const accountId = change.account.currentValue.id;
this.isPending = true;

this.tradeService.getPositions(accountId).subscribe((positions: Position[]) => {
console.log('Closed Position blotter tradeService feed...', positions);
this.filteredPositions = positions.filter((p: Position) => p.quantity === 0);
this.processPendingPositions();
}, () => {
this.isPending = false;
this.positions = positions.filter((p: Position) => p.quantity === 0);
this.symbolService.getAccountPrices(accountId).subscribe((prices: StockPrice[]) => {
prices.forEach((price) => {
let position = this.positions.find((p: Position) =>
p.security === price.ticker);
if (position) {
position = Object.assign(position, { unitPrice: price.price });
this.update(position);
}
});
});
});


this.socketUnSubscribeFn?.();
this.socketUnSubscribeFn = this.tradeFeed.subscribe(`/accounts/${accountId}/positions`, (data: any) => {
console.log('Position blotter websocket feed...', data);
if (data.quantity === 0) {
this.updatePosition(data);
this.update(data);
}
});

Expand All @@ -72,20 +78,6 @@ export class ClosedPositionBlotterComponent implements OnChanges, OnDestroy {
}
}

processPendingPositions() {
this.pendingPosition.forEach((position) => this.update(position));
this.pendingPosition = [];
this.isPending = false;
}

updatePosition(data: any) {
if (this.isPending) {
this.pendingPosition.push(data);
} else {
this.update(data);
}
}

update(data: any) {
const row = this.gridApi.getRowNode(data.security);
let positionData;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<h5>{{title}}</h5>

<ag-grid-angular #agGrid style="width: 100%; height: 350px;" id="myGrid" class="ag-theme-alpine"
[columnDefs]="columnDefs" [rowData]="filteredPositions" (gridReady)="onGridReady($event)" [getRowNodeId]="getRowNodeId">
[columnDefs]="columnDefs" [rowData]="positions" (gridReady)="onGridReady($event)" [getRowNodeId]="getRowNodeId">
</ag-grid-angular>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/
import { Account } from 'main/app/model/account.model';
import { Position, StockPrice } from 'main/app/model/trade.model';
import { PositionService } from 'main/app/service/position.service';
import { SymbolService } from 'main/app/service/symbols.service';
import { Observable } from 'rxjs';
import { TradeFeedService } from 'main/app/service/trade-feed.service';

Expand All @@ -15,10 +16,7 @@ export class PositionBlotterComponent implements OnChanges, OnDestroy {
@Input() account?: Account;
positions$: Observable<Position[]>;
positions: any = [];
filteredPositions: any = [];
gridApi: GridApi;
pendingPosition: any[] = [];
isPending = true;
socketUnSubscribeFn: Function;
marketValueUnSubscribeFn: Function;
title = 'Positions';
Expand All @@ -45,28 +43,35 @@ export class PositionBlotterComponent implements OnChanges, OnDestroy {
];

constructor(private tradeService: PositionService,
private tradeFeed: TradeFeedService) { }
private tradeFeed: TradeFeedService,
private symbolService: SymbolService) { }

ngOnChanges(change: SimpleChanges) {
console.log('Position blotter changes...', change);
if (change.account?.currentValue && change.account.currentValue !== change.account.previousValue) {
const accountId = change.account.currentValue.id;
this.isPending = true;

this.tradeService.getPositions(accountId).subscribe((positions: Position[]) => {
console.log('Position blotter tradeService feed...', positions);
this.positions = positions;
this.filteredPositions = positions.filter((p) => p.quantity > 0);
this.processPendingPositions();
}, () => {
this.isPending = false;
this.positions = positions.filter((p) => p.quantity > 0);
this.symbolService.getAccountPrices(accountId).subscribe((prices: StockPrice[]) => {
prices.forEach((price) => {
let position = this.positions.find((p: Position) =>
p.security === price.ticker);
if (position) {
position = Object.assign(position, { marketValue: Math.abs(position.quantity * price.price) });
this.update(position);
}

});
});
});


this.socketUnSubscribeFn?.();
this.socketUnSubscribeFn = this.tradeFeed.subscribe(`/accounts/${accountId}/positions`, (data: any) => {
console.log('Position blotter websocket feed...', data);
this.updatePosition(data);
this.update(data);
});

this.marketValueUnSubscribeFn?.();
Expand All @@ -77,20 +82,6 @@ export class PositionBlotterComponent implements OnChanges, OnDestroy {
}
}

processPendingPositions() {
this.pendingPosition.forEach((position) => this.update(position));
this.pendingPosition = [];
this.isPending = false;
}

updatePosition(data: any) {
if (this.isPending) {
this.pendingPosition.push(data);
} else {
this.update(data);
}
}

update(data: any) {
const row = this.gridApi.getRowNode(data.security);
let positionData;
Expand Down

0 comments on commit a08ed03

Please sign in to comment.