Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save carloswm85/c1d2c4ef097bb6b59f9d9596a3b46bdf to your computer and use it in GitHub Desktop.
Save carloswm85/c1d2c4ef097bb6b59f9d9596a3b46bdf to your computer and use it in GitHub Desktop.
<mat-card class="mb4">
<mat-list>
<mat-list-item>
<span class="underline-and-strong">ERC</span>:
<span class="low-ranking">LR-1</span>
<span class="low-ranking">LR-2</span>
<span class="medium-low-ranking">MLR-1</span>
<span class="medium-low-ranking border-bottom">MLR-2</span>
<span class="medium-high-ranking">MHR-1</span>
<span class="medium-high-ranking">MHR-2</span>
<span class="high-ranking">HR-1</span>
<span class="high-ranking">HR-2</span>
<span class="">
<i>MLR-2 seems to be the best analysis starting point.</i>
</span>
</mat-list-item>
</mat-list>
</mat-card>
<app-progress-bar *ngIf="isLoading"></app-progress-bar>
<ng-container *ngIf="!isLoading">
<div>
<!-- BUTTONS -->
<!-- <div class="buttons">
<span class="buttons-title">EMAc Ranking Filtering:</span>
<button mat-flat-button class="low-ranking-button">Low: 0-50</button>
<button mat-flat-button class="medium-low-ranking-button">Medium-low: 50-100</button>
<button mat-flat-button class="medium-high-ranking-button">Medium-high: 100-150</button>
<button mat-flat-button class="high-ranking-button">High: 150-200</button>
</div> -->
<!-- Filters and Actions -->
<mat-card class="mb4">
<mat-list>
<mat-list-item>
Server Time: <strong> {{ emacDescription?.serverTime }} </strong>
Request Duration: <strong> {{ emacDescription?.requestDuration }} </strong>
Symbols Count: <strong> {{ emacDescription?.symbolsCount }} </strong>
Requests Count: <strong> {{ emacDescription?.requestsMadeCount }} </strong>
EMAc Positions Data Errors: <strong> {{ emacDescription?.errorsCount }} </strong>
EMA Length: <strong> {{ emacDescription?.emaLength }} </strong>
</mat-list-item>
</mat-list>
</mat-card>
<!-- Search/Filter -->
<mat-card class="mb4">
<mat-card-content>
<!-- FIELD -->
<mat-form-field appearance="outline" ngClass="mr4">
<mat-label>Search or Filter</mat-label>
<input matInput (input)="applyFilter($event)" placeholder="Type to filter data" #input>
<mat-icon matSuffix>search</mat-icon>
</mat-form-field>
<!-- FIELD -->
<mat-form-field appearance="outline" ngClass="mr4">
<mat-label>Ranking Code</mat-label>
<mat-select [(value)]="selectedRankingCode" (selectionChange)="applyFilter()">
<mat-option>None</mat-option>
<mat-option *ngFor="let rankingCode of validFilters" [value]="rankingCode">
<span [appAddEmacRankingCodeClass]="rankingCode">
{{ rankingCode | uppercase }}
</span>
</mat-option>
</mat-select>
</mat-form-field>
<!-- FIELD -->
<mat-form-field class="filter-field" appearance="outline">
<mat-label>Amount Symbols</mat-label>
<input matInput type="number" [(ngModel)]="symbolsSliceEnd" (keydown.enter)="onEnterKey()"
placeholder="PRESS ENTER" />
<mat-icon matSuffix>input</mat-icon>
</mat-form-field>
</mat-card-content>
</mat-card>
</div>
<!-- DATA TABLE -->
<div class="table-responsive mat-elevation-z8">
<table mat-table [dataSource]="dataSource" matSort>
<!-- Number Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription="Sort by position in the list" class="custom-header"></th>
<td mat-cell *matCellDef="let element" class="custom-cell">
{{element.rowPosition}}
</td>
</ng-container>
<!-- Reviewed Row with Checkbox -->
<ng-container matColumnDef="reviewedCheck">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"> Reviewed </th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<mat-checkbox [(ngModel)]="element.reviewedCheck"></mat-checkbox>
</td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"> Symbol </th>
<td mat-cell *matCellDef="let element" class="custom-cell">
{{element.symbol}}
</td>
</ng-container>
<!-- EMAc Column 15m -->
<ng-container matColumnDef="strategyData15m">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header">15m</th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<span class="border element-block">
{{ element.strategyData15m.emacHighLowDistanceIncremental | percent: '1.2-4' }}
</span>
<ng-container *ngFor="let prop of ['emasTrend', 'emacPosition']">
<span [appAddEmacPositionClass]="element.strategyData15m[prop]" class="border element-inline-block">
{{ element.strategyData15m[prop] }}
</span>
</ng-container>
</td>
</ng-container>
<!-- EMAc Column 30m -->
<ng-container matColumnDef="strategyData30m">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header">30m</th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<span class="border element-block">
{{ element.strategyData30m.emacHighLowDistanceIncremental | percent: '1.2-4' }}
</span>
<ng-container *ngFor="let prop of ['emasTrend', 'emacPosition']">
<span [appAddEmacPositionClass]="element.strategyData30m[prop]" class="border element-inline-block">
{{ element.strategyData30m[prop] }}
</span>
</ng-container>
</td>
</ng-container>
<!-- EMAc Column 1h -->
<ng-container matColumnDef="strategyData1h">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"> 1h </th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<span class="border element-block">
{{ element.strategyData1h.emacHighLowDistanceIncremental | percent: '1.2-4' }}
</span>
<ng-container *ngFor="let prop of ['emasTrend', 'emacPosition']">
<span [appAddEmacPositionClass]="element.strategyData1h[prop]" class="border element-inline-block">
{{ element.strategyData1h[prop] }}
</span>
</ng-container>
</td>
</ng-container>
<!-- EMAc Column 4h -->
<ng-container matColumnDef="strategyData4h">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"> 4h </th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<span class="border element-block">
{{ element.strategyData4h.emacHighLowDistanceIncremental | percent: '1.2-4' }}
</span>
<ng-container *ngFor="let prop of ['emasTrend', 'emacPosition']">
<span [appAddEmacPositionClass]="element.strategyData4h[prop]" class="border element-inline-block">
{{ element.strategyData4h[prop] }}
</span>
</ng-container>
</td>
</ng-container>
<!-- EMAc Column 1D -->
<ng-container matColumnDef="strategyData1D">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"> 1D </th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<span class="border element-block">
{{ element.strategyData1D.emacHighLowDistanceIncremental | percent: '1.2-4' }}
</span>
<ng-container *ngFor="let prop of ['emasTrend', 'emacPosition']">
<span [appAddEmacPositionClass]="element.strategyData1D[prop]" class="border element-inline-block">
{{ element.strategyData1D[prop] }}
</span>
</ng-container>
</td>
</ng-container>
<!-- EMAc Column 1W -->
<ng-container matColumnDef="strategyData1W">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"> 1W </th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<span class="border element-block">
{{ element.strategyData1W.emacHighLowDistanceIncremental | percent: '1.2-4' }}
</span>
<ng-container *ngFor="let prop of ['emasTrend', 'emacPosition']">
<span [appAddEmacPositionClass]="element.strategyData1W[prop]" class="border element-inline-block">
{{ element.strategyData1W[prop] }}
</span>
</ng-container>
</td>
</ng-container>
<!-- EMAc Column 1M -->
<ng-container matColumnDef="strategyData1M">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"> 1M </th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<span class="border element-block">
{{ element.strategyData1M.emacHighLowDistanceIncremental | percent: '1.2-4' }}
</span>
<ng-container *ngFor="let prop of ['emasTrend', 'emacPosition']">
<span [appAddEmacPositionClass]="element.strategyData1M[prop]" class="border element-inline-block">
{{ element.strategyData1M[prop] }}
</span>
</ng-container>
</td>
</ng-container>
<!-- Price Column -->
<ng-container matColumnDef="price">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"
matTooltip="Last price in Tether Stable Coin, or USD" [matTooltipPosition]="tooltipPosition.value!">
USDT<mat-icon class="mat-icon-small">help</mat-icon></th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<i> $ {{ element.price | currency:'':'':'1.2-4' }} </i>
</td>
</ng-container>
<!-- EMAc Ranking Points Column -->
<ng-container matColumnDef="emacRankingPoints">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"
matTooltip="EMAc Position Ranking Points" [matTooltipPosition]="tooltipPosition.value!">EPRP<mat-icon
class="mat-icon-small">help</mat-icon></th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<span [appAddEmacRankingClass]="element.emacRankingPoints">
{{element.emacRankingPoints}}
</span>
</td>
</ng-container>
<!-- EMAc Ranking Code Column -->
<ng-container matColumnDef="emacRankingCode">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="custom-header"
matTooltip="EMAc Position Ranking Code" [matTooltipPosition]="tooltipPosition.value!">EPRC
<mat-icon class="mat-icon-small">help</mat-icon>
</th>
<td mat-cell *matCellDef="let element" [ngClass]="element.emacRankingCode" class="custom-cell">
<span [appAddEmacRankingClass]="element.emacRankingCode">
{{element.emacRankingCode}}
</span>
</td>
</ng-container>
<!-- Links Column -->
<ng-container matColumnDef="urls">
<th mat-header-cell *matHeaderCellDef class="custom-header"> Links </th>
<td mat-cell *matCellDef="let element" class="custom-cell">
<ng-container *ngFor="let link of element.urls">
<!-- Render additional content if the link contains 'tradingview' -->
<a *ngIf="link && link.includes('tradingview')" [href]="link" target="_blank" class="link-clean">
<img src="assets/icons/tradingview-dark.svg" alt="TradingView Icon" class="link-icon" />
</a>
<!-- Render content for links that do not contain 'tradingview' -->
<a [href]="link" target="_blank" class="link-clean" *ngIf="link && !link.includes('tradingview')">
<img src="assets/icons/binance.svg" alt="Link Icon" class="link-icon" />
</a>
</ng-container>
<a [href]="element.symbol" target="_blank" class="link-clean">
<img src="assets/icons/open_in_new.svg" alt="Link Icon" class="link-icon" />
</a>
</td>
</ng-container>
<!-- ? -->
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<!-- Table Row -->
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [class.highlighted-row]="row.reviewedCheck">
</tr>
<!-- Row shown when there is no matching data. -->
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4">No data matching the filter "{{input.value}}"</td>
</tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]" aria-label="Select page of users"></mat-paginator>
</div>
</ng-container>
<mat-card class="mb4 mt4">
<mat-card-header>
<mat-card-title>Trading Strategy Instructions</mat-card-title>
<mat-card-subtitle>EMAc Strategy</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<mat-list>
<mat-list-item>Amount Symbols = 0, return all available symbols.</mat-list-item>
</mat-list>
</mat-card-content>
<!-- <mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions> -->
</mat-card>
import { Component, ViewChild, AfterViewInit, ElementRef } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort, MatSortModule } from '@angular/material/sort';
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import { BinanceRestService } from '../../../core/services/binance-rest.service';
import {
BinanceDescription,
BinanceEmacDatatable,
BinanceEmacDatatableMode,
} from '../../../core/interfaces/binance.interface';
import { AddEmacPositionClassDirective } from '../../../shared/directives/add-emac-position-class/add-emac-position-class.directive';
import { AddEmacRankingClassDirective } from '../../../shared/directives/add-emac-ranking-class/add-emac-ranking-class.directive';
import { ProgressBarComponent } from '../../../shared/components/progress-bar/progress-bar.component';
import { MaterialModule } from '../../../core/material/material.module';
import { FormControl, FormsModule } from '@angular/forms';
import { AddEmacRankingCodeClassDirective } from '../../../shared/directives/add-emac-ranking-code-class/add-emac-ranking-code-class.directive';
import { TooltipPosition } from '@angular/material/tooltip';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-binance-emac-datatable',
standalone: true,
imports: [
MatSortModule,
MatTableModule,
CommonModule,
AddEmacPositionClassDirective,
AddEmacRankingClassDirective,
AddEmacRankingCodeClassDirective,
ProgressBarComponent,
MaterialModule,
FormsModule,
],
templateUrl: './binance-emac-datatable.component.html',
styleUrl: './binance-emac-datatable.component.css',
})
export class BinanceEmacDatatableComponent implements AfterViewInit {
displayedColumns: string[] = [
'position',
'reviewedCheck',
'symbol',
'strategyData15m',
'strategyData30m',
'strategyData1h',
'strategyData4h',
'strategyData1D',
'strategyData1W',
'strategyData1M',
'price',
'emacRankingPoints',
'emacRankingCode',
'urls',
];
emacDatatableData: BinanceEmacDatatableMode | null = null;
dataSource = new MatTableDataSource<BinanceEmacDatatable>([]); // Updated to MatTableDataSource
isLoading = true;
symbolsSliceEnd = 9;
emacDescription: BinanceDescription | undefined;
// Define the valid ranking codes for quick lookup
validFilters = [
'lr-1',
'lr-2',
'mlr-1',
'mlr-2',
'mhr-1',
'mhr-2',
'hr-1',
'hr-2',
];
selectedRankingCode: string | null = null;
positionOptions: TooltipPosition[] = ['below', 'above', 'left', 'right'];
tooltipPosition = new FormControl(this.positionOptions[1]); // 'above' is selected
@ViewChild(MatPaginator) paginator!: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
@ViewChild('input', { static: true }) inputFilter!: ElementRef;
constructor(private binanceRestService: BinanceRestService) {
this.fetchEmacData(this.symbolsSliceEnd);
this.sort = new MatSort();
// Customize filter logic
this.dataSource.filterPredicate = (
data: BinanceEmacDatatable,
filter: string
) => {
const lowerCaseFilter = filter.trim().toLowerCase();
// Check if the filter matches one of the valid ranking codes
if (this.validFilters.includes(lowerCaseFilter)) {
return data.emacRankingCode.toLowerCase() === lowerCaseFilter;
}
// Default filter logic for other cases
return (
data.symbol.toLowerCase().includes(lowerCaseFilter) ||
data.emacRankingPoints.toString().includes(lowerCaseFilter)
);
};
}
ngAfterViewInit(): void {
// Set paginator and sort after view initialization
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
private fetchEmacData(symbolsSliceEnd: number): void {
this.binanceRestService.getEmacDataTable(symbolsSliceEnd).subscribe({
next: (data) => {
this.processEmacData(data);
},
error: (err) => {
console.error('Error fetching EMAc data:', err);
this.isLoading = false;
},
});
}
private processEmacData(data: BinanceEmacDatatableMode): void {
this.emacDatatableData = data;
this.emacDescription = data.description;
console.log(data.description.serverTime);
const sortedData = this.emacDatatableData.data
.sort((a, b) => a.emacRankingPoints - b.emacRankingPoints)
.map((item) => ({
...item,
reviewedCheck: false,
}));
this.dataSource.data = sortedData;
this.isLoading = false;
}
applyFilter(event?: Event): void {
// Get the text input value if the event is triggered from the input field
const filterInputValue = event
? (event.target as HTMLInputElement).value.trim().toLowerCase()
: '';
// Get the dropdown filter value
const rankingCodeFilter = this.selectedRankingCode
? this.selectedRankingCode.toLowerCase()
: '';
console.log(filterInputValue);
console.log(rankingCodeFilter);
// Combine both filters
const combinedFilter = `${filterInputValue} ${rankingCodeFilter}`;
this.dataSource.filter = combinedFilter;
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
onEnterKey(): void {
this.isLoading = true;
console.log('Enter pressed with value:', this.symbolsSliceEnd);
// Trigger the data fetch and redraw table with the specified number of symbols
this.fetchEmacData(this.symbolsSliceEnd);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment