Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
147f0162b7 | |||
f6acf5207b | |||
80782f1098 | |||
bc58ee86ca | |||
0cb632b165 |
16
CHANGELOG.md
16
CHANGELOG.md
@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## 1.79.0 - 21.11.2021
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added the value column to the positions table
|
||||||
|
- Added support for cryptocurrency _Algorand_
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Locked the symbol input in the edit transaction dialog
|
||||||
|
- Filtered the account selector by account type (`SECURITIES`) in the create or edit transaction dialog
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed the search functionality for cryptocurrency symbols (do not show unsupported symbols)
|
||||||
|
|
||||||
## 1.78.0 - 20.11.2021
|
## 1.78.0 - 20.11.2021
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"1INCH": "1inch",
|
"1INCH": "1inch",
|
||||||
|
"ALGO": "Algorand",
|
||||||
"AVAX": "Avalanche",
|
"AVAX": "Avalanche",
|
||||||
"MATIC": "Polygon",
|
"MATIC": "Polygon",
|
||||||
"SHIB": "Shiba Inu"
|
"SHIB": "Shiba Inu"
|
||||||
|
@ -197,16 +197,20 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
// filter out undefined symbols
|
// filter out undefined symbols
|
||||||
return quote.symbol;
|
return quote.symbol;
|
||||||
})
|
})
|
||||||
.filter(({ quoteType }) => {
|
.filter(({ quoteType, symbol }) => {
|
||||||
return (
|
return (
|
||||||
quoteType === 'CRYPTOCURRENCY' ||
|
(quoteType === 'CRYPTOCURRENCY' &&
|
||||||
|
this.cryptocurrencyService.isCrypto(
|
||||||
|
symbol.replace(new RegExp('-USD$'), 'USD').replace('1', '')
|
||||||
|
)) ||
|
||||||
quoteType === 'EQUITY' ||
|
quoteType === 'EQUITY' ||
|
||||||
quoteType === 'ETF'
|
quoteType === 'ETF'
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.filter(({ quoteType, symbol }) => {
|
.filter(({ quoteType, symbol }) => {
|
||||||
if (quoteType === 'CRYPTOCURRENCY') {
|
if (quoteType === 'CRYPTOCURRENCY') {
|
||||||
// Only allow cryptocurrencies in USD
|
// Only allow cryptocurrencies in USD to avoid having redundancy in the database.
|
||||||
|
// Trades need to be converted manually before to USD (or a UI converter needs to be developed)
|
||||||
return symbol.includes('USD');
|
return symbol.includes('USD');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,14 +258,15 @@ export class YahooFinanceService implements DataProviderInterface {
|
|||||||
if (isCurrency(aSymbol.substring(0, aSymbol.length - 3))) {
|
if (isCurrency(aSymbol.substring(0, aSymbol.length - 3))) {
|
||||||
return `${aSymbol}=X`;
|
return `${aSymbol}=X`;
|
||||||
} else if (
|
} else if (
|
||||||
this.cryptocurrencyService.isCrypto(aSymbol) ||
|
this.cryptocurrencyService.isCrypto(
|
||||||
this.cryptocurrencyService.isCrypto(aSymbol.replace('1', ''))
|
aSymbol.replace(new RegExp('-USD$'), 'USD').replace('1', '')
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
// Add a dash before the last three characters
|
// Add a dash before the last three characters
|
||||||
// BTCUSD -> BTC-USD
|
// BTCUSD -> BTC-USD
|
||||||
// DOGEUSD -> DOGE-USD
|
// DOGEUSD -> DOGE-USD
|
||||||
// SOL1USD -> SOL1-USD
|
// SOL1USD -> SOL1-USD
|
||||||
return aSymbol.replace('USD', '-USD');
|
return aSymbol.replace(new RegExp('-?USD$'), '-USD');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,27 @@
|
|||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="value">
|
||||||
|
<th
|
||||||
|
*matHeaderCellDef
|
||||||
|
class="d-none d-lg-table-cell justify-content-end px-1"
|
||||||
|
i18n
|
||||||
|
mat-header-cell
|
||||||
|
mat-sort-header
|
||||||
|
>
|
||||||
|
Value
|
||||||
|
</th>
|
||||||
|
<td class="d-none d-lg-table-cell px-1" mat-cell *matCellDef="let element">
|
||||||
|
<div class="d-flex justify-content-end">
|
||||||
|
<gf-value
|
||||||
|
[isCurrency]="true"
|
||||||
|
[locale]="locale"
|
||||||
|
[value]="isLoading ? undefined : element.value"
|
||||||
|
></gf-value>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="performance">
|
<ng-container matColumnDef="performance">
|
||||||
<th
|
<th
|
||||||
*matHeaderCellDef
|
*matHeaderCellDef
|
||||||
|
@ -70,6 +70,7 @@ export class PositionsTableComponent implements OnChanges, OnDestroy, OnInit {
|
|||||||
public ngOnChanges() {
|
public ngOnChanges() {
|
||||||
this.displayedColumns = [
|
this.displayedColumns = [
|
||||||
'symbol',
|
'symbol',
|
||||||
|
'value',
|
||||||
'performance',
|
'performance',
|
||||||
'allocationInvestment',
|
'allocationInvestment',
|
||||||
'allocationCurrent'
|
'allocationCurrent'
|
||||||
|
@ -23,7 +23,7 @@ export class LandingPageComponent implements OnDestroy, OnInit {
|
|||||||
{
|
{
|
||||||
author: 'Onur',
|
author: 'Onur',
|
||||||
country: 'Switzerland 🇨🇭',
|
country: 'Switzerland 🇨🇭',
|
||||||
quote: `Ghostfolio looks like the perfect portfolio tracker that I've been searching for all these years.`
|
quote: `Ghostfolio looks like the perfect portfolio tracker I've been searching for all these years.`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
author: 'Ivo',
|
author: 'Ivo',
|
||||||
|
@ -84,6 +84,10 @@ export class CreateOrUpdateTransactionDialog implements OnDestroy {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (this.data.transaction.id) {
|
||||||
|
this.searchSymbolCtrl.disable();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.data.transaction.symbol) {
|
if (this.data.transaction.symbol) {
|
||||||
this.dataService
|
this.dataService
|
||||||
.fetchSymbolItem({
|
.fetchSymbolItem({
|
||||||
|
@ -10,9 +10,7 @@
|
|||||||
required
|
required
|
||||||
[(value)]="data.transaction.accountId"
|
[(value)]="data.transaction.accountId"
|
||||||
>
|
>
|
||||||
<mat-option
|
<mat-option *ngFor="let account of data.accounts" [value]="account.id"
|
||||||
*ngFor="let account of data.user?.accounts"
|
|
||||||
[value]="account.id"
|
|
||||||
>{{ account.name }}</mat-option
|
>{{ account.name }}</mat-option
|
||||||
>
|
>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { User } from '@ghostfolio/common/interfaces';
|
import { User } from '@ghostfolio/common/interfaces';
|
||||||
import { Order } from '@prisma/client';
|
import { Account, Order } from '@prisma/client';
|
||||||
|
|
||||||
export interface CreateOrUpdateTransactionDialogParams {
|
export interface CreateOrUpdateTransactionDialogParams {
|
||||||
accountId: string;
|
accountId: string;
|
||||||
|
accounts: Account[];
|
||||||
transaction: Order;
|
transaction: Order;
|
||||||
user: User;
|
user: User;
|
||||||
}
|
}
|
||||||
|
@ -261,6 +261,9 @@ export class TransactionsPageComponent implements OnDestroy, OnInit {
|
|||||||
}: OrderModel): void {
|
}: OrderModel): void {
|
||||||
const dialogRef = this.dialog.open(CreateOrUpdateTransactionDialog, {
|
const dialogRef = this.dialog.open(CreateOrUpdateTransactionDialog, {
|
||||||
data: {
|
data: {
|
||||||
|
accounts: this.user.accounts.filter((account) => {
|
||||||
|
return account.accountType === 'SECURITIES';
|
||||||
|
}),
|
||||||
transaction: {
|
transaction: {
|
||||||
accountId,
|
accountId,
|
||||||
currency,
|
currency,
|
||||||
@ -343,6 +346,9 @@ export class TransactionsPageComponent implements OnDestroy, OnInit {
|
|||||||
private openCreateTransactionDialog(aTransaction?: OrderModel): void {
|
private openCreateTransactionDialog(aTransaction?: OrderModel): void {
|
||||||
const dialogRef = this.dialog.open(CreateOrUpdateTransactionDialog, {
|
const dialogRef = this.dialog.open(CreateOrUpdateTransactionDialog, {
|
||||||
data: {
|
data: {
|
||||||
|
accounts: this.user.accounts.filter((account) => {
|
||||||
|
return account.accountType === 'SECURITIES';
|
||||||
|
}),
|
||||||
transaction: {
|
transaction: {
|
||||||
accountId: aTransaction?.accountId ?? this.defaultAccountId,
|
accountId: aTransaction?.accountId ?? this.defaultAccountId,
|
||||||
currency: aTransaction?.currency ?? null,
|
currency: aTransaction?.currency ?? null,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ghostfolio",
|
"name": "ghostfolio",
|
||||||
"version": "1.78.0",
|
"version": "1.79.0",
|
||||||
"homepage": "https://ghostfol.io",
|
"homepage": "https://ghostfol.io",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
Reference in New Issue
Block a user