├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── app │ └── src │ │ └── main │ │ └── java │ │ └── io │ │ └── flutter │ │ └── plugins │ │ └── GeneratedPluginRegistrant.java └── local.properties ├── example └── lib │ └── main.dart ├── ios ├── Flutter │ ├── Generated.xcconfig │ └── flutter_export_environment.sh └── Runner │ ├── GeneratedPluginRegistrant.h │ └── GeneratedPluginRegistrant.m ├── lib ├── bavest.dart ├── client │ ├── abstract │ │ └── bavest_rest_abstract_client.dart │ ├── bavest_rest_client.dart │ ├── cache │ │ └── bavest_cache_manager.dart │ └── event │ │ └── bavest_websocket_event.dart ├── extensions │ └── bavest_function_extension.dart └── model │ ├── .gitkeep │ └── v0 │ ├── etf │ ├── country │ │ └── etf_country.dart │ ├── holdings │ │ └── etf_holdings.dart │ ├── profile │ │ └── etf_profile.dart │ └── sector │ │ └── etf_sector.dart │ ├── forex │ └── forex.dart │ ├── portfolio │ ├── allocation │ │ └── portfolio_allocation.dart │ ├── metric │ │ └── portfolio_metric.dart │ ├── portfolio.dart │ ├── region │ │ └── portfolio_region.dart │ ├── sector │ │ └── portfolio_sector.dart │ ├── stats │ │ ├── portfolio_stats.dart │ │ └── risk_model.dart │ └── trade_direction.dart │ ├── search │ └── search.dart │ ├── security │ ├── security_identifier.dart │ └── security_type.dart │ ├── sentiment │ └── sentiment.dart │ ├── stock │ ├── .gitkeep │ ├── candle │ │ ├── candle.dart │ │ └── candle_type.dart │ ├── dividend │ │ └── dividend.dart │ ├── esg │ │ └── esg.dart │ ├── financials │ │ ├── balance.dart │ │ ├── cashflow.dart │ │ ├── financials.dart │ │ ├── financials_mode.dart │ │ └── income.dart │ ├── fundamentals │ │ └── fundamentals.dart │ ├── ipo │ │ └── ipo.dart │ ├── metric │ │ └── metric.dart │ ├── news │ │ └── news.dart │ ├── profile │ │ └── profile.dart │ ├── quote │ │ └── quote.dart │ └── split │ │ └── split.dart │ └── widget │ └── peers │ └── peers.dart ├── linux └── flutter │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.cmake ├── macos └── Flutter │ ├── GeneratedPluginRegistrant.swift │ └── ephemeral │ ├── Flutter-Generated.xcconfig │ └── flutter_export_environment.sh ├── pubspec.yaml ├── test └── unit_test │ └── api_test.dart └── windows └── flutter ├── generated_plugin_registrant.cc ├── generated_plugin_registrant.h └── generated_plugins.cmake /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | .packages 30 | build/ 31 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.7 2 | * Updated dependencies 3 | 4 | ## 0.0.6 5 | * Updated the dashboard link in the README.md 6 | 7 | ## 0.0.5 8 | * Change Dividends and Search signature and encapsulate the response in a class 9 | * Add Dividends and Search tests 10 | * Implement ETF profile, ETF holdings, ETF dividends and ETF search tests 11 | 12 | ## 0.0.4 13 | * Upgrade description in pubspec.yaml 14 | 15 | ## 0.0.3 16 | 17 | * Update client examples 18 | 19 | ## 0.0.2 20 | 21 | * Add BavestRestClient example 22 | * Add BavestRestClient tests 23 | 24 | ## 0.0.1 25 | 26 | * Initial Bavest SDK release 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Bavest Technologies GmbH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | # Bavest Dart SDK 6 | 7 | 8 | 9 | **The Bavest Finance SDK is an open-source library to create finance products in weeks. Bavest offers:** 10 | 11 | * Financial api with 99.95% uptime 12 | * Easy to integrate and use 13 | * Free for open-source projects 14 | 15 | 16 | ## Get API key 17 | 18 | First, you need to create a [Bavest](https://dashboard.bavest.co) account. 19 | After registration, you will find your api key in the dashboard. 20 | 21 | ### Free API key for Open-Source projects 22 | 23 | First, use the [TypeForm](https://e0nemwrtihz.typeform.com/to/xT8KfS0I) to provide all required information. 24 | After, you will receive an API key via E-Mail. 25 | 26 | 27 | ### Install the package 28 | 29 | First install the flutter package, it is available at [pub.dev](https://pub.dev/packages/bavest): 30 | 31 | ```dart 32 | flutter pub add bavest 33 | ``` 34 | 35 | ### Usage 36 | 37 | 1. Now, use the package in your project: 38 | ```dart 39 | import 'package:bavest/bavest.dart'; 40 | ``` 41 | 42 | 2. Create a finance `client`: 43 | ```dart 44 | var client = BavestRestClient(apiKey); 45 | ``` 46 | 47 | 3. Now you can use it to get data from the api: 48 | 49 | ```dart 50 | var client = BavestRestClient(apiKey); 51 | final id = SecurityIdentifier(symbol: "AAPL"); 52 | var quote = await client.quote(id); 53 | ``` 54 | 55 | 56 | ### Examples 57 | 58 | ```dart 59 | var profile = await client.profile(id); 60 | var metric = await client.metric(id); 61 | var dividend = await client.dividends(id); 62 | var companyNews = await client.companyNews(id); 63 | var fundamentals = await client.fundamentals(id); 64 | var peersWidget = await client.peersWidget(id); 65 | var forex = await client.forex("EUR", "USD"); 66 | var sentiment = await client.sentiment(id); 67 | var splits = await client.splits(id, years: 5); 68 | 69 | // ETF 70 | final id = SecurityIdentifier(symbol: "ARKK"); 71 | var etfSector = await client.etfSector(id); 72 | var etfCountry = await client.etfCountry(id); 73 | var etfHoldings = await client.etfHoldings(id); 74 | var etfProfile = await client.etfProfile(id); 75 | 76 | // Portfolio methods 77 | var portfolio = Portfolio.fromJson({ 78 | "portfolio_items": [ 79 | {"symbol": "ABEA.DE", "amount": 5, "buy_date": 1649887200000}, 80 | {"symbol": "DEQ.DE", "amount": 41, "buy_date": 1619647200000}, 81 | {"symbol": "AAPL", "amount": 100, "buy_date": 1556661600000}, 82 | {"symbol": "ADS.DE", "amount": 10, "buy_date": 1491343200000} 83 | ] 84 | }); 85 | 86 | var from = 1630352898; 87 | var to = 1655848800; 88 | var resolution = CandleType.day; 89 | 90 | await client.portfolioStats(portfolio, 91 | from: from, to: to, resolution: resolution); 92 | 93 | var allocation = Portfolio.fromJson({ 94 | "portfolio_items": [ 95 | { 96 | "symbol": "BNTX", 97 | "amount": 10 98 | }, 99 | { 100 | "symbol": "AAPL", 101 | "amount": 4 102 | }, 103 | { 104 | "symbol": "SAP.DE", 105 | "amount": 4 106 | } 107 | ] 108 | }); 109 | 110 | 111 | await client.portfolioPrice(portfolio); 112 | await client.portfolioAllocation(allocation); 113 | await client.portfolioRegion(allocation); 114 | await client.portfolioSector(allocation); 115 | await client.portfolioPrice(portfolio); 116 | await client.portfolioChart(portfolio, 117 | from: from, to: to, resolution: resolution); 118 | ``` 119 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | # Additional information about this file can be found at 4 | # https://dart.dev/guides/language/analysis-options 5 | -------------------------------------------------------------------------------- /android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java: -------------------------------------------------------------------------------- 1 | package io.flutter.plugins; 2 | 3 | import io.flutter.plugin.common.PluginRegistry; 4 | 5 | /** 6 | * Generated file. Do not edit. 7 | */ 8 | public final class GeneratedPluginRegistrant { 9 | public static void registerWith(PluginRegistry registry) { 10 | if (alreadyRegisteredWith(registry)) { 11 | return; 12 | } 13 | } 14 | 15 | private static boolean alreadyRegisteredWith(PluginRegistry registry) { 16 | final String key = GeneratedPluginRegistrant.class.getCanonicalName(); 17 | if (registry.hasPlugin(key)) { 18 | return true; 19 | } 20 | registry.registrarFor(key); 21 | return false; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /android/local.properties: -------------------------------------------------------------------------------- 1 | sdk.dir=/Users/monolidth/Library/Android/Sdk 2 | flutter.sdk=/opt/homebrew/Caskroom/flutter/3.3.4/flutter -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:bavest/bavest.dart'; 2 | import 'package:bavest/model/v0/security/security_identifier.dart'; 3 | import 'package:bavest/model/v0/stock/candle/candle_type.dart'; 4 | import 'package:flutter_test/flutter_test.dart'; 5 | 6 | Future main() async { 7 | var apiKey = const String.fromEnvironment('API_KEY'); 8 | var client = BavestRestClient(apiKey); 9 | var id = SecurityIdentifier(symbol: "AAPL"); 10 | 11 | /// Search for a symbol 12 | await client.search("App"); 13 | 14 | /// Get stock data 15 | await client.quote(id); 16 | await client.profile(id); 17 | await client.metric(id); 18 | await client.dividends(id); 19 | await client.companyNews(id); 20 | await client.fundamentals(id); 21 | await client.peersWidget(id); 22 | await client.forex("EUR", "USD"); 23 | await client.sentiment(id); 24 | await client.splits(id, years: 5); 25 | 26 | id = SecurityIdentifier(symbol: "ARKK"); 27 | await client.etfSector(id); 28 | await client.etfCountry(id); 29 | await client.etfHoldings(id); 30 | await client.etfProfile(id); 31 | 32 | var portfolio = Portfolio.fromJson({ 33 | "portfolio_items": [ 34 | {"symbol": "ABEA.DE", "amount": 5, "buy_date": 1649887200000}, 35 | {"symbol": "DEQ.DE", "amount": 41, "buy_date": 1619647200000}, 36 | {"symbol": "AAPL", "amount": 100, "buy_date": 1556661600000}, 37 | {"symbol": "ADS.DE", "amount": 10, "buy_date": 1491343200000} 38 | ] 39 | }); 40 | 41 | var from = 1630352898; 42 | var to = 1655848800; 43 | var resolution = CandleResolution.day; 44 | 45 | await client.portfolioStats(portfolio, 46 | from: from, to: to, resolution: resolution); 47 | 48 | var allocation = Portfolio.fromJson({ 49 | "portfolio_items": [ 50 | {"symbol": "BNTX", "amount": 10}, 51 | {"symbol": "AAPL", "amount": 4}, 52 | {"symbol": "SAP.DE", "amount": 4} 53 | ] 54 | }); 55 | 56 | await client.portfolioPrice(portfolio); 57 | await client.portfolioAllocation(allocation); 58 | await client.portfolioRegion(allocation); 59 | await client.portfolioSector(allocation); 60 | await client.portfolioPrice(portfolio); 61 | await client.portfolioChart(portfolio, 62 | from: from, to: to, resolution: resolution); 63 | } 64 | -------------------------------------------------------------------------------- /ios/Flutter/Generated.xcconfig: -------------------------------------------------------------------------------- 1 | // This is a generated file; do not edit or check into version control. 2 | FLUTTER_ROOT=/opt/homebrew/Caskroom/flutter/3.3.4/flutter 3 | FLUTTER_APPLICATION_PATH=/Users/monolidth/StudioProjects/dart-sdk 4 | COCOAPODS_PARALLEL_CODE_SIGN=true 5 | FLUTTER_TARGET=lib/main.dart 6 | FLUTTER_BUILD_DIR=build 7 | FLUTTER_BUILD_NAME=0.0.6 8 | FLUTTER_BUILD_NUMBER=0.0.6 9 | EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386 10 | EXCLUDED_ARCHS[sdk=iphoneos*]=armv7 11 | DART_OBFUSCATION=false 12 | TRACK_WIDGET_CREATION=true 13 | TREE_SHAKE_ICONS=false 14 | PACKAGE_CONFIG=.dart_tool/package_config.json 15 | -------------------------------------------------------------------------------- /ios/Flutter/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=/opt/homebrew/Caskroom/flutter/3.3.4/flutter" 4 | export "FLUTTER_APPLICATION_PATH=/Users/monolidth/StudioProjects/dart-sdk" 5 | export "COCOAPODS_PARALLEL_CODE_SIGN=true" 6 | export "FLUTTER_TARGET=lib/main.dart" 7 | export "FLUTTER_BUILD_DIR=build" 8 | export "FLUTTER_BUILD_NAME=0.0.6" 9 | export "FLUTTER_BUILD_NUMBER=0.0.6" 10 | export "DART_OBFUSCATION=false" 11 | export "TRACK_WIDGET_CREATION=true" 12 | export "TREE_SHAKE_ICONS=false" 13 | export "PACKAGE_CONFIG=.dart_tool/package_config.json" 14 | -------------------------------------------------------------------------------- /ios/Runner/GeneratedPluginRegistrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GeneratedPluginRegistrant_h 8 | #define GeneratedPluginRegistrant_h 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface GeneratedPluginRegistrant : NSObject 15 | + (void)registerWithRegistry:(NSObject*)registry; 16 | @end 17 | 18 | NS_ASSUME_NONNULL_END 19 | #endif /* GeneratedPluginRegistrant_h */ 20 | -------------------------------------------------------------------------------- /ios/Runner/GeneratedPluginRegistrant.m: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #import "GeneratedPluginRegistrant.h" 8 | 9 | @implementation GeneratedPluginRegistrant 10 | 11 | + (void)registerWithRegistry:(NSObject*)registry { 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /lib/bavest.dart: -------------------------------------------------------------------------------- 1 | /// The Bavest Finance SDK 2 | /// The SDK is a wrapper around the [Bavest Finance API](https://bavest.finance/api/v0/docs). 3 | library bavest; 4 | 5 | /// Client 6 | export 'client/bavest_rest_client.dart'; 7 | 8 | /// model 9 | export 'model/v0/stock/candle/candle.dart'; 10 | export 'model/v0/stock/quote/quote.dart'; 11 | export 'model/v0/stock/profile/profile.dart'; 12 | export 'model/v0/stock/metric/metric.dart'; 13 | export 'model/v0/stock/dividend/dividend.dart'; 14 | export 'model/v0/stock/ipo/ipo.dart'; 15 | export 'model/v0/stock/news/news.dart'; 16 | export 'model/v0/stock/financials/income.dart'; 17 | export 'model/v0/stock/financials/cashflow.dart'; 18 | export 'model/v0/stock/financials/financials_mode.dart'; 19 | export 'model/v0/stock/financials/balance.dart'; 20 | export 'model/v0/stock/fundamentals/fundamentals.dart'; 21 | export 'model/v0/sentiment/sentiment.dart'; 22 | export 'model/v0/stock/split/split.dart'; 23 | export 'model/v0/forex/forex.dart'; 24 | export 'model/v0/security/security_type.dart'; 25 | export 'model/v0/etf/profile/etf_profile.dart'; 26 | export 'model/v0/etf/sector/etf_sector.dart'; 27 | export 'model/v0/etf/country/etf_country.dart'; 28 | export 'model/v0/etf/holdings/etf_holdings.dart'; 29 | 30 | /// Portfolio 31 | export 'model/v0/portfolio/portfolio.dart'; 32 | export 'model/v0/portfolio/allocation/portfolio_allocation.dart'; 33 | export 'model/v0/portfolio/region/portfolio_region.dart'; 34 | export 'model/v0/portfolio/stats/portfolio_stats.dart'; 35 | export 'model/v0/portfolio/stats/risk_model.dart'; 36 | export 'model/v0/portfolio/trade_direction.dart'; 37 | 38 | /// Widgets 39 | export 'model/v0/widget/peers/peers.dart'; 40 | -------------------------------------------------------------------------------- /lib/client/abstract/bavest_rest_abstract_client.dart: -------------------------------------------------------------------------------- 1 | import 'package:bavest/bavest.dart'; 2 | import 'package:bavest/model/v0/portfolio/metric/portfolio_metric.dart'; 3 | import 'package:bavest/model/v0/portfolio/sector/portfolio_sector.dart'; 4 | import 'package:bavest/model/v0/search/search.dart'; 5 | import 'package:bavest/model/v0/security/security_identifier.dart'; 6 | import 'package:bavest/model/v0/stock/candle/candle_type.dart'; 7 | import 'package:bavest/model/v0/stock/esg/esg.dart'; 8 | 9 | abstract class BavestAbstractRestClient { 10 | /// The [quote] method is used to get the quote for a given stock symbol. 11 | /// By default, the quote is returned in EUR. You can specify a different currency 12 | /// by passing the [currency] argument. 13 | /// 14 | /// It returns a [Quote] object. 15 | /// 16 | /// ```dart 17 | /// // Get quote for Apple in EUR 18 | /// final client = BavestRestClient(api_key); 19 | /// client.quote(SecurityIdentifier(symbol: "AAPL")); 20 | /// ``` 21 | Future quote(SecurityIdentifier id, {String? currency}); 22 | 23 | /// The [candle] method is used to get the candle data for a given stock symbol. 24 | /// By default, the candle data is returned in EUR. You can specify a different currency 25 | /// by passing the [currency] argument. 26 | /// 27 | /// The [from] and [to] arguments are used to specify the time range for the candle data in unix timestamp. 28 | /// The [resolution] argument is used to specify the resolution of the candle data. 29 | /// 30 | /// Valid resolutions are 1, 5, 60, D, W, M. 31 | /// 32 | /// ```dart 33 | /// // Get candle data for Apple in EUR 34 | /// final client = BavestRestClient(api_key); 35 | /// final candle = client.candle(SecurityIdentifier(symbol: "AAPL"), '1630352898', '1655848800', CandleType.day, currency: 'EUR); 36 | /// ``` 37 | Future candle(SecurityIdentifier id, String from, String to, 38 | CandleResolution resolution, 39 | {String? currency}); 40 | 41 | /// The [metric] method is used to get the metric for a given stock symbol. 42 | /// 43 | /// The [id] argument is used to specify the stock id. 44 | /// ```dart 45 | /// // Get metric for Apple 46 | /// final client = BavestRestClient(api_key); 47 | /// final metric = client.metric(SecurityIdentifier(symbol: "AAPL")); 48 | /// ``` 49 | Future metric(SecurityIdentifier id); 50 | 51 | /// The [profile] method is used to get the profile for a given stock symbol. 52 | /// Market capitalisation is adjusted by the specified currency and is NOT in million. 53 | /// The zip code, isin and city can be empty. 54 | /// 55 | /// The [id] argument is used to specify the stock id. 56 | /// ```dart 57 | /// // Get profile for Apple 58 | /// final client = BavestRestClient(api_key); 59 | /// final profile = client.profile(SecurityIdentifier(symbol: "AAPL")); 60 | /// ``` 61 | Future profile(SecurityIdentifier id); 62 | 63 | /// The [dividends] method is used to get the dividends for a given stock symbol. 64 | /// By default, the dividends are returned in EUR. You can specify a different currency 65 | /// by passing the [currency] argument. 66 | /// 67 | /// The [id] argument is used to specify the stock id. 68 | /// The [currency] argument is used to specify the currency. 69 | /// ```dart 70 | /// // Get dividends for Apple in EUR 71 | /// final client = BavestRestClient(api_key); 72 | /// final dividends = client.dividends(SecurityIdentifier(symbol: "AAPL")); 73 | /// ``` 74 | Future dividends(SecurityIdentifier id, {String? currency}); 75 | 76 | /// The [news] method is used to get the news for a given stock symbol. 77 | /// 78 | /// The [id] argument is used to specify the stock id. 79 | /// ```dart 80 | /// // Get news for Apple 81 | /// final client = BavestRestClient(api_key); 82 | /// final news = client.news(SecurityIdentifier(symbol: "AAPL")); 83 | /// ``` 84 | Future> companyNews(SecurityIdentifier id); 85 | 86 | /// The [ipos] endpoint returns upcoming initial public offerings (IPOs) and 87 | /// their expected release dates. 88 | /// 89 | /// ```dart 90 | /// // Get ipos 91 | /// final client = BavestRestClient(api_key); 92 | /// final ipos = client.ipos(); 93 | /// ``` 94 | Future ipos(); 95 | 96 | /// The [peersWidget] endpoint returns a list of peers for a given stock symbol. 97 | /// The list contains the symbol, name and logo of the peers. 98 | /// 99 | /// The [id] argument is used to specify the stock id. 100 | /// 101 | /// ```dart 102 | /// // Get peers for Apple 103 | /// final client = BavestRestClient(api_key); 104 | /// final peers = client.peersWidget(SecurityIdentifier(symbol: "AAPL")); 105 | /// ``` 106 | Future> peersWidget(SecurityIdentifier id); 107 | 108 | /// The [income] method is used to get the income statement for a given stock symbol. 109 | /// By default, the income statement is returned in EUR. You can specify a different currency 110 | /// by passing the [currency] argument. 111 | /// 112 | /// The [mode] argument is used to specify the mode of the income statement. 113 | /// The [id] argument is used to specify the stock id. 114 | /// The [currency] argument is used to specify the currency. 115 | /// 116 | /// ```dart 117 | /// // Get income statement for Apple in EUR 118 | /// final client = BavestRestClient(api_key); 119 | /// final income = client.income(SecurityIdentifier(symbol: "AAPL"), currency: 'EUR', mode: FinancialsMode.annual); 120 | /// ``` 121 | Future income(SecurityIdentifier id, 122 | {String? currency, Freq mode = Freq.annual}); 123 | 124 | /// The [cashflow] method is used to get the cashflow statement for a given stock symbol. 125 | /// By default, the cashflow statement is returned in EUR. You can specify a different currency 126 | /// by passing the [currency] argument. 127 | /// 128 | /// The [mode] argument is used to specify the mode of the cashflow statement. 129 | /// The [id] argument is used to specify the stock id. 130 | /// The [currency] argument is used to specify the currency. 131 | /// 132 | /// ```dart 133 | /// // Get cashflow statement for Apple in EUR 134 | /// final client = BavestRestClient(api_key); 135 | /// final cashflow = client.cashflow(SecurityIdentifier(symbol: "AAPL"), currency: 'EUR', mode: FinancialsMode.annual); 136 | /// ``` 137 | Future cashflow(SecurityIdentifier id, 138 | {String? currency, Freq mode = Freq.annual}); 139 | 140 | /// The [balance] method is used to get the balance sheet for a given stock symbol. 141 | /// By default, the balance sheet is returned in EUR. You can specify a different currency 142 | /// by passing the [currency] argument. 143 | /// 144 | /// The [mode] argument is used to specify the mode of the balance sheet. 145 | /// The [id] argument is used to specify the stock id. 146 | /// The [currency] argument is used to specify the currency. 147 | /// 148 | /// ```dart 149 | /// // Get balance sheet for Apple in EUR 150 | /// final client = BavestRestClient(api_key); 151 | /// final balance = client.balance(SecurityIdentifier(symbol: "AAPL"), currency: 'EUR', mode: FinancialsMode.annual); 152 | /// ``` 153 | Future balance(SecurityIdentifier id, 154 | {String? currency, Freq mode = Freq.annual}); 155 | 156 | /// The [fundamentals] method is used to get the fundamentals for a given stock symbol. 157 | /// 158 | /// The [id] argument is used to specify the stock id. 159 | /// 160 | /// ```dart 161 | /// // Get fundamentals for Apple 162 | /// final client = BavestRestClient(api_key); 163 | /// final fundamentals = client.fundamentals(SecurityIdentifier(symbol: "AAPL")); 164 | /// ``` 165 | Future fundamentals(SecurityIdentifier id); 166 | 167 | /// The [esg] method is used to get the ESG scores for a given stock symbol. 168 | /// 169 | /// The [id] argument is used to specify the stock id. 170 | /// 171 | /// ```dart 172 | /// // Get ESG scores for Apple 173 | /// final client = BavestRestClient(api_key); 174 | /// final esg = client.esg(SecurityIdentifier(symbol: "AAPL")); 175 | /// ``` 176 | Future esg(SecurityIdentifier id); 177 | 178 | /// The [splits] method is used to get the splits for a given stock symbol. 179 | /// The [id] argument is used to specify the stock id. 180 | /// The [years] argument is used to specify the number of years to get the splits for. 181 | /// 182 | /// ```dart 183 | /// // Get splits for Apple in the last 5 years 184 | /// final client = BavestRestClient(api_key); 185 | /// final splits = client.splits(SecurityIdentifier(symbol: "AAPL"), years: 5); 186 | /// ``` 187 | Future splits(SecurityIdentifier id, {final int years = 1}); 188 | 189 | /// The [sentiment] method is used to get the sentiment for a given stock symbol. 190 | /// 191 | /// The [id] argument is used to specify the stock id. 192 | /// 193 | /// ```dart 194 | /// // Get sentiment for Apple 195 | /// final client = BavestRestClient(api_key); 196 | /// final sentiment = client.sentiment(SecurityIdentifier(symbol: "AAPL")); 197 | /// ``` 198 | Future sentiment(SecurityIdentifier id); 199 | 200 | /// The [forex] method is used to get the forex rates for a given stock symbol. 201 | /// 202 | /// The [fromCurrency] argument is used to specify the from currency to convert. 203 | /// The [toCurrency] argument is used to specify the to currency to convert. 204 | /// 205 | /// ```dart 206 | /// // Get forex rates for EUR to USD 207 | /// final client = BavestRestClient(api_key); 208 | /// final forex = client.forex('EUR', 'USD'); 209 | /// ``` 210 | Future forex(String fromCurrency, String toCurrency); 211 | 212 | /// The [search] method is used to get the search for given symbols. 213 | /// The [query] argument is used to specify the query to search for. 214 | /// 215 | /// ```dart 216 | /// // Search for Apple 217 | /// final client = BavestRestClient(api_key); 218 | /// final search = client.search(SecurityIdentifier(symbol: "AAPL")); 219 | /// ``` 220 | Future search(String query); 221 | 222 | /// The [etfProfile] method is used to get the ETF profile for a given ETF symbol. 223 | /// 224 | /// The [id] argument is used to specify the ETF id e.g. symbol. 225 | /// 226 | /// ```dart 227 | /// // Get ETF profile for SPY 228 | /// final client = BavestRestClient(api_key); 229 | /// final etfProfile = client.etfProfile('SPY'); 230 | /// ``` 231 | Future etfProfile(SecurityIdentifier id); 232 | 233 | /// The [etfHoldings] method is used to get the ETF holdings for a given ETF symbol. 234 | /// 235 | /// The [id] argument is used to specify the ETF id e.g. symbol 236 | /// 237 | /// ```dart 238 | /// // Get ETF holdings for SPY 239 | /// final client = BavestRestClient(api_key); 240 | /// final etfHoldings = client.etfHoldings('SPY'); 241 | /// ``` 242 | Future etfHoldings(SecurityIdentifier id); 243 | 244 | /// The [etfSector] method is used to get the ETF sectors for a given ETF symbol. 245 | /// 246 | /// The [id] argument is used to specify the ETF id e.g. symbol 247 | /// 248 | /// ```dart 249 | /// // Get ETF sectors for SPY 250 | /// final client = BavestRestClient(api_key); 251 | /// final etfSector = client.etfSector('SPY'); 252 | /// ``` 253 | Future etfSector(SecurityIdentifier id); 254 | 255 | /// The [etfCountry] method is used to get the ETF country for a given ETF symbol. 256 | /// 257 | /// The [id] argument is used to specify the ETF id e.g. symbol 258 | /// 259 | /// ```dart 260 | /// // Get ETF country for SPY 261 | /// final client = BavestRestClient(api_key); 262 | /// final etfCountry = client.etfCountry('SPY'); 263 | /// ``` 264 | Future etfCountry(SecurityIdentifier id); 265 | 266 | /// The [portfolioRegion] method is used to get the portfolio regions for a given portfolio. 267 | /// 268 | /// The [portfolio] argument is used to specify the portfolio. 269 | /// 270 | /// ```dart 271 | /// // Get portfolio regions for portfolio 272 | /// final client = BavestRestClient(api_key); 273 | /// 274 | /// // Create a portfolio 275 | /// final portfolioRegion = client.portfolioRegion(portfolio); 276 | /// ``` 277 | Future> portfolioRegion(Portfolio portfolio); 278 | 279 | /// The [portfolioAllocation] method is used to get the portfolio allocation for a given portfolio. 280 | /// 281 | /// The [portfolio] argument is used to specify the portfolio. 282 | /// 283 | /// ```dart 284 | /// // Get portfolio allocation for portfolio 285 | /// final client = BavestRestClient(api_key); 286 | /// final portfolioAllocation = client.portfolioAllocation(portfolio); 287 | /// ``` 288 | Future> portfolioAllocation(Portfolio portfolio); 289 | 290 | /// The [portfolioMetrics] method is used to get the portfolio metrics for a given portfolio. 291 | /// 292 | /// The [portfolio] argument is used to specify the portfolio. 293 | /// ```dart 294 | /// // Get portfolio metrics for portfolio 295 | /// final client = BavestRestClient(api_key); 296 | /// final portfolioMetrics = client.portfolioMetrics(portfolio); 297 | /// ``` 298 | Future portfolioMetrics(Portfolio portfolio, 299 | {String currency = 'EUR'}); 300 | 301 | /// The [portfolioSector] method is used to get the portfolio sectors for a given portfolio. 302 | /// 303 | /// The [portfolio] argument is used to specify the portfolio. 304 | /// 305 | /// ```dart 306 | /// // Get portfolio sectors for portfolio 307 | /// final client = BavestRestClient(api_key); 308 | /// final portfolioSector = client.portfolioSector(portfolio); 309 | /// ``` 310 | Future> portfolioSector(Portfolio portfolio, 311 | {String currency = "EUR"}); 312 | 313 | /// The [portfolioBenchmark] method is used to get the portfolio benchmark for a given portfolio. 314 | /// 315 | /// The [portfolio] argument is used to specify the portfolio. 316 | /// 317 | /// ```dart 318 | /// // Get portfolio benchmark for portfolio 319 | /// final client = BavestRestClient(api_key); 320 | /// final portfolioBenchmark = client.portfolioBenchmark(portfolio); 321 | /// ``` 322 | Future portfolioBenchmark(Portfolio portfolio); 323 | 324 | /// The [portfolioPrice] method is used to get the portfolio price for a given portfolio. 325 | /// 326 | /// The [portfolio] argument is used to specify the portfolio. 327 | /// 328 | /// ```dart 329 | /// // Get portfolio price for portfolio 330 | /// final client = BavestRestClient(api_key); 331 | /// final portfolioPrice = client.portfolioPrice(portfolio); 332 | /// ``` 333 | Future portfolioPrice(Portfolio portfolio, {String currency = "EUR"}); 334 | 335 | /// The [portfolioChart] method is used to get the portfolio chart for a given portfolio. 336 | /// 337 | /// The [portfolio] argument is used to specify the portfolio. 338 | /// 339 | /// ```dart 340 | /// // Get portfolio chart for portfolio 341 | /// final client = BavestRestClient(api_key); 342 | /// final portfolioChart = client.portfolioChart(portfolio, from: 1630352898, to: 1655848800, resolution: CandleType.day); 343 | /// ``` 344 | Future portfolioChart(Portfolio portfolio, 345 | {String currency = "EUR", 346 | required int from, 347 | required int to, 348 | required CandleResolution resolution}); 349 | 350 | /// The [portfolioStats] method is used to get the portfolio stats for a given portfolio. 351 | /// 352 | /// The [portfolio] argument is used to specify the portfolio. 353 | /// 354 | /// ```dart 355 | /// // Get portfolio stats for portfolio 356 | /// final client = BavestRestClient(api_key); 357 | /// final portfolioStats = client.portfolioStats(portfolio, from: 1630352898, to: 1655848800, resolution: CandleType.day); 358 | /// ``` 359 | Future portfolioStats(Portfolio portfolio, 360 | {String currency = "EUR", 361 | required int from, 362 | required int to, 363 | required CandleResolution resolution}); 364 | } 365 | -------------------------------------------------------------------------------- /lib/client/bavest_rest_client.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | 4 | import 'package:bavest/client/abstract/bavest_rest_abstract_client.dart'; 5 | import 'package:bavest/model/v0/etf/country/etf_country.dart'; 6 | import 'package:bavest/model/v0/etf/holdings/etf_holdings.dart'; 7 | import 'package:bavest/model/v0/etf/profile/etf_profile.dart'; 8 | import 'package:bavest/model/v0/etf/sector/etf_sector.dart'; 9 | import 'package:bavest/model/v0/forex/forex.dart'; 10 | import 'package:bavest/model/v0/portfolio/allocation/portfolio_allocation.dart'; 11 | import 'package:bavest/model/v0/portfolio/metric/portfolio_metric.dart'; 12 | import 'package:bavest/model/v0/portfolio/portfolio.dart'; 13 | import 'package:bavest/model/v0/portfolio/region/portfolio_region.dart'; 14 | import 'package:bavest/model/v0/portfolio/sector/portfolio_sector.dart'; 15 | import 'package:bavest/model/v0/portfolio/stats/portfolio_stats.dart'; 16 | import 'package:bavest/model/v0/portfolio/stats/risk_model.dart'; 17 | import 'package:bavest/model/v0/search/search.dart'; 18 | import 'package:bavest/model/v0/security/security_identifier.dart'; 19 | import 'package:bavest/model/v0/sentiment/sentiment.dart'; 20 | import 'package:bavest/model/v0/stock/candle/candle.dart'; 21 | import 'package:bavest/model/v0/stock/candle/candle_type.dart'; 22 | import 'package:bavest/model/v0/stock/dividend/dividend.dart'; 23 | import 'package:bavest/model/v0/stock/esg/esg.dart'; 24 | import 'package:bavest/model/v0/stock/financials/balance.dart'; 25 | import 'package:bavest/model/v0/stock/financials/cashflow.dart'; 26 | import 'package:bavest/model/v0/stock/financials/financials_mode.dart'; 27 | import 'package:bavest/model/v0/stock/financials/income.dart'; 28 | import 'package:bavest/model/v0/stock/fundamentals/fundamentals.dart'; 29 | import 'package:bavest/model/v0/stock/ipo/ipo.dart'; 30 | import 'package:bavest/model/v0/stock/metric/metric.dart'; 31 | import 'package:bavest/model/v0/stock/news/news.dart'; 32 | import 'package:bavest/model/v0/stock/profile/profile.dart'; 33 | import 'package:bavest/model/v0/stock/quote/quote.dart'; 34 | import 'package:bavest/model/v0/stock/split/split.dart'; 35 | import 'package:bavest/model/v0/widget/peers/peers.dart'; 36 | import 'package:dio/dio.dart'; 37 | 38 | /// The [BavestRestClient] class is the http rest client for the bavest finance api. 39 | /// To use it, you will need to provide an api key. To get an api key, please visit 40 | /// https://dashboard.bavest.co and create an account. 41 | /// 42 | /// Bavest provide a free tier for developers and open-source projects. 43 | /// Please contact us at sales@bavest.co if you are interested. 44 | /// 45 | /// ```dart 46 | /// import 'package:bavest/bavest.dart'; 47 | /// 48 | /// // Usage: 49 | /// final client = BavestRestClient(api_key); 50 | /// 51 | /// // Get quote for Apple 52 | /// client.quote(SecurityIdentifier(symbol: "AAPL")); 53 | /// ``` 54 | /// 55 | /// Please checkout https://docs.bavest.co/ for more information. 56 | class BavestRestClient extends BavestAbstractRestClient { 57 | /// The [apiKey] is the api key you get from https://dashboard.bavest.co 58 | /// It is required to make requests to the bavest finance api. 59 | final String apiKey; 60 | 61 | /// The Bavest API [_stage]. 62 | static const String _stage = 'v0'; 63 | 64 | /// The [baseUrl] is the base url of the bavest finance api. 65 | static const String _baseUrl = 'https://api.bavest.co/$_stage'; 66 | 67 | /// create singleton constructor 68 | BavestRestClient._internal(this.apiKey); 69 | 70 | static BavestRestClient? _instance; 71 | 72 | /// The [BavestRestClient] factory constructor is used to create a singleton instance 73 | /// of the [BavestRestClient] class. 74 | factory BavestRestClient(String apiKey) { 75 | _instance ??= BavestRestClient._internal(apiKey); 76 | return _instance!; 77 | } 78 | 79 | /// The [response] method is used to make a post request to the bavest finance api. 80 | /// It takes a [url] and a [params] map as arguments. 81 | /// 82 | /// The [url] is the endpoint of the api you want to call. 83 | /// The [params] is a map of the parameters you want to pass to the api. 84 | /// 85 | /// It returns a [Response] object. 86 | Future _post( 87 | final String url, final Map params) async { 88 | final dio = Dio(BaseOptions(contentType: Headers.jsonContentType, headers: { 89 | "x-api-key": apiKey, 90 | })); 91 | 92 | return await dio 93 | .post(url, data: jsonEncode(params)) 94 | .timeout(const Duration(seconds: 30)); 95 | } 96 | 97 | /// The [_isSuccess] method is used to check if the response from the bavest finance api 98 | /// is successful. 99 | /// 100 | /// It takes a [response] object as argument. 101 | /// 102 | /// It returns a [bool] value indicating if the response is successful. 103 | bool _isSuccess(Response? response) { 104 | return response != null && 105 | response.statusCode == 200 && 106 | response.data != null; 107 | } 108 | 109 | @override 110 | Future quote(SecurityIdentifier id, {String? currency}) async { 111 | const url = '$_baseUrl/quote'; 112 | final params = id.toJson(); 113 | 114 | final response = await _post(url, params); 115 | if (_isSuccess(response)) { 116 | return Quote.fromJson(jsonDecode(response!.data)); 117 | } 118 | 119 | throw Exception('Failed to get quote for $id'); 120 | } 121 | 122 | @override 123 | Future candle(SecurityIdentifier id, String from, String to, 124 | CandleResolution resolution, 125 | {String? currency}) async { 126 | const url = '$_baseUrl/candle'; 127 | final params = { 128 | "from": from, 129 | "to": to, 130 | "resolution": resolution.str, 131 | "currency": currency ?? "EUR", 132 | }..addAll(id.toJson()); 133 | 134 | final response = await _post(url, params); 135 | if (_isSuccess(response)) { 136 | return Candles.fromJson(jsonDecode(response!.data)); 137 | } 138 | 139 | throw Exception('Failed to get candle for $id'); 140 | } 141 | 142 | @override 143 | Future metric(SecurityIdentifier id) async { 144 | const url = '$_baseUrl/stock/metric'; 145 | final params = id.toJson(); 146 | 147 | var response = await _post(url, params); 148 | if (response != null && response.statusCode == 200) { 149 | return Metric.fromJson(jsonDecode(response.data)); 150 | } 151 | 152 | throw Exception("could not fetch API"); 153 | } 154 | 155 | @override 156 | Future profile(SecurityIdentifier id) async { 157 | const url = '$_baseUrl/stock/profile'; 158 | final params = id.toJson(); 159 | final response = await _post(url, params); 160 | if (_isSuccess(response)) { 161 | return CompanyProfile.fromJson(jsonDecode(response!.data)); 162 | } 163 | 164 | throw Exception('Failed to get profile for $id'); 165 | } 166 | 167 | @override 168 | Future dividends(SecurityIdentifier id, {String? currency}) async { 169 | const url = '$_baseUrl/stock/dividend'; 170 | final params = { 171 | 'currency': currency ?? 'EUR', 172 | }..addAll(id.toJson()); 173 | 174 | var response = await _post(url, params); 175 | if (_isSuccess(response)) { 176 | return Dividends.fromJson({"data": jsonDecode(response!.data)}); 177 | } 178 | 179 | throw Exception("Failed to get dividends for $id"); 180 | } 181 | 182 | @override 183 | Future> companyNews(SecurityIdentifier id) async { 184 | const url = '$_baseUrl/stock/news'; 185 | final params = id.toJson(); 186 | 187 | var response = await _post(url, params); 188 | if (_isSuccess(response)) { 189 | dynamic data = jsonDecode(response!.data); 190 | return data.map((e) => News.fromJson(e)).toList(); 191 | } 192 | 193 | throw Exception("Failed to get news for $id"); 194 | } 195 | 196 | @override 197 | Future ipos() async { 198 | final DateTime c = DateTime.now(); 199 | 200 | var from = c.subtract(const Duration(days: 30)).millisecondsSinceEpoch; 201 | var to = c.millisecondsSinceEpoch; 202 | 203 | from = from ~/ 1000; 204 | to = to ~/ 1000; 205 | 206 | const url = '$_baseUrl/calender/ipo'; 207 | var params = {"from": from, "to": to}; 208 | 209 | var response = await _post(url, params); 210 | 211 | if (_isSuccess(response)) { 212 | return Ipo.fromJson(jsonDecode(response!.data)); 213 | } 214 | 215 | throw Exception("could not fetch API"); 216 | } 217 | 218 | @override 219 | Future> peersWidget(SecurityIdentifier id) async { 220 | const url = '$_baseUrl/widgets/stock/peers'; 221 | final params = id.toJson(); 222 | 223 | var response = await _post(url, params); 224 | if (_isSuccess(response)) { 225 | dynamic peers = jsonDecode(response!.data); 226 | if (peers is List) { 227 | return peers.map((e) => PeersWidget.fromJson(e)).toList(); 228 | } else { 229 | return [PeersWidget.fromJson(peers)]; 230 | } 231 | } 232 | throw Exception("could not get data for $id"); 233 | } 234 | 235 | @override 236 | Future income(SecurityIdentifier id, 237 | {String? currency, Freq mode = Freq.annual}) async { 238 | const url = '$_baseUrl/stock/financials'; 239 | final freq = mode == Freq.annual ? "annual" : "quarterly"; 240 | final params = { 241 | "statement": "ic", 242 | "currency": currency ?? "EUR", 243 | "freq": freq 244 | }..addAll(id.toJson()); 245 | 246 | var response = await _post(url, params); 247 | if (_isSuccess(response)) { 248 | return Income.fromJson(jsonDecode(response!.data)); 249 | } 250 | 251 | throw Exception("could not retrieve data for $id"); 252 | } 253 | 254 | @override 255 | Future cashflow(SecurityIdentifier id, 256 | {String? currency, Freq mode = Freq.annual}) async { 257 | const url = '$_baseUrl/stock/financials'; 258 | final freq = mode == Freq.annual ? "annual" : "quarterly"; 259 | final params = { 260 | "statement": "cf", 261 | "currency": currency ?? "EUR", 262 | "freq": freq 263 | }..addAll(id.toJson()); 264 | 265 | var response = await _post(url, params); 266 | if (_isSuccess(response)) { 267 | return Cashflow.fromJson(jsonDecode(response!.data)); 268 | } 269 | 270 | throw Exception("could not retrieve cashflow"); 271 | } 272 | 273 | @override 274 | Future balance(SecurityIdentifier id, 275 | {String? currency, Freq mode = Freq.annual}) async { 276 | const url = '$_baseUrl/stock/financials'; 277 | final freq = mode == Freq.annual ? "annual" : "quarterly"; 278 | final params = { 279 | "statement": "bs", 280 | "currency": currency ?? "EUR", 281 | "freq": freq 282 | }..addAll(id.toJson()); 283 | 284 | var response = await _post(url, params); 285 | if (_isSuccess(response)) { 286 | return Balance.fromJson(jsonDecode(response!.data)); 287 | } 288 | 289 | throw Exception("could not receive data for $id"); 290 | } 291 | 292 | @override 293 | Future fundamentals(SecurityIdentifier id) async { 294 | const url = '$_baseUrl/stock/fundamentals'; 295 | final params = id.toJson(); 296 | 297 | var response = await _post(url, params); 298 | if (response != null && response.statusCode == 200) { 299 | var fundamentals = Fundamentals.fromJson(jsonDecode(response.data)); 300 | final seen = {}; 301 | if (fundamentals.metrics == null) return fundamentals; 302 | 303 | fundamentals.metrics!.removeWhere((e) { 304 | var isDuplicate = seen.contains(e.period.toString()); 305 | seen.add(e.period.toString()); 306 | 307 | return isDuplicate; 308 | }); 309 | 310 | if (fundamentals.metrics == null) return fundamentals; 311 | 312 | fundamentals.metrics! 313 | .sort((a, b) => b.period!.year.compareTo(a.period!.year)); 314 | 315 | return fundamentals; 316 | } 317 | 318 | throw Exception("could not fetch fundamentals for $id"); 319 | } 320 | 321 | @override 322 | Future esg(SecurityIdentifier id) async { 323 | const url = '$_baseUrl/stock/esg'; 324 | final params = id.toJson(); 325 | 326 | var response = await _post(url, params); 327 | if (_isSuccess(response)) { 328 | return Esg.fromJson(jsonDecode(response!.data)); 329 | } 330 | 331 | throw Exception("could not receive esg data for $id"); 332 | } 333 | 334 | @override 335 | Future splits(SecurityIdentifier id, {final int years = 1}) async { 336 | const url = '$_baseUrl/stock/split'; 337 | var from = DateTime.now() 338 | .subtract(Duration(days: 365 * years)) 339 | .millisecondsSinceEpoch; 340 | var to = DateTime.now().millisecondsSinceEpoch; 341 | final params = { 342 | 'from': from.toString(), 343 | 'to': to.toString(), 344 | }..addAll(id.toJson()); 345 | 346 | var response = await _post(url, params); 347 | if (_isSuccess(response)) { 348 | return Splits.fromJson(jsonDecode(response!.data)); 349 | } 350 | 351 | throw Exception("could not receive esg data for $id"); 352 | } 353 | 354 | @override 355 | Future sentiment(SecurityIdentifier id) async { 356 | const url = '$_baseUrl/sentiment'; 357 | final params = id.toJson(); 358 | 359 | var response = await _post(url, params); 360 | if (_isSuccess(response)) { 361 | return Sentiment.fromJson(jsonDecode(response!.data)); 362 | } 363 | 364 | throw Exception("could not receive esg data for $id"); 365 | } 366 | 367 | @override 368 | Future forex(String fromCurrency, String toCurrency) async { 369 | const url = '$_baseUrl/fx/quote'; 370 | final params = { 371 | 'from': fromCurrency, 372 | 'to': toCurrency, 373 | }; 374 | 375 | var response = await _post(url, params); 376 | if (_isSuccess(response)) { 377 | return Forex.fromJson(jsonDecode(response!.data)); 378 | } 379 | throw Exception( 380 | "could not receive forex data for $fromCurrency to $toCurrency"); 381 | } 382 | 383 | @override 384 | Future search(String query) async { 385 | const url = '$_baseUrl/search'; 386 | final params = { 387 | 'query': query, 388 | }; 389 | 390 | var response = await _post(url, params); 391 | if (_isSuccess(response)) { 392 | return SearchResult.fromJson(jsonDecode(response!.data)); 393 | } 394 | 395 | throw Exception("could not receive search result for $query"); 396 | } 397 | 398 | @override 399 | Future etfProfile(SecurityIdentifier id) async { 400 | const url = '$_baseUrl/etf/profile'; 401 | final params = id.toJson(); 402 | 403 | var response = await _post(url, params); 404 | if (_isSuccess(response)) { 405 | return EtfProfile.fromJson(jsonDecode(response!.data)); 406 | } 407 | 408 | throw Exception("could not receive etf profile for $id"); 409 | } 410 | 411 | @override 412 | Future etfHoldings(SecurityIdentifier id) async { 413 | const url = '$_baseUrl/etf/holdings'; 414 | final params = id.toJson(); 415 | 416 | var response = await _post(url, params); 417 | if (_isSuccess(response)) { 418 | return EtfHoldings.fromJson(jsonDecode(response!.data)); 419 | } 420 | 421 | throw Exception("could not receive etf profile for $id"); 422 | } 423 | 424 | @override 425 | Future etfSector(SecurityIdentifier id) async { 426 | const url = '$_baseUrl/etf/sector'; 427 | final params = id.toJson(); 428 | 429 | var response = await _post(url, params); 430 | if (_isSuccess(response)) { 431 | return EtfSector.fromJson(jsonDecode(response!.data)); 432 | } 433 | 434 | throw Exception("could not receive etf profile for $id"); 435 | } 436 | 437 | @override 438 | Future etfCountry(SecurityIdentifier id) async { 439 | const url = '$_baseUrl/etf/country'; 440 | final params = id.toJson(); 441 | 442 | var response = await _post(url, params); 443 | if (_isSuccess(response)) { 444 | return EtfCountry.fromJson(jsonDecode(response!.data)); 445 | } 446 | 447 | throw Exception("could not receive etf profile for $id"); 448 | } 449 | 450 | @override 451 | Future> portfolioRegion(Portfolio portfolio) async { 452 | const url = '$_baseUrl/portfolio/region'; 453 | final params = portfolio.toJson(); 454 | 455 | var response = await _post(url, params); 456 | if (_isSuccess(response)) { 457 | List filteredResults = jsonDecode(response!.data); 458 | return filteredResults.map((e) => PortfolioRegion.fromJson(e)).toList(); 459 | } 460 | 461 | throw Exception("could not receive portfolio region for $portfolio"); 462 | } 463 | 464 | @override 465 | Future> portfolioAllocation( 466 | Portfolio portfolio) async { 467 | const url = '$_baseUrl/portfolio/allocation'; 468 | final params = portfolio.toJson(); 469 | 470 | var response = await _post(url, params); 471 | if (_isSuccess(response)) { 472 | List filteredResults = jsonDecode(response!.data); 473 | return filteredResults 474 | .map((e) => PortfolioAllocation.fromJson(e)) 475 | .toList(); 476 | } 477 | 478 | throw Exception("could not receive portfolio allocation for $portfolio"); 479 | } 480 | 481 | @override 482 | Future portfolioMetrics(Portfolio portfolio, 483 | {String currency = 'EUR'}) async { 484 | const url = '$_baseUrl/portfolio/metrics'; 485 | final params = portfolio.toJson()..addAll({'currency': currency}); 486 | 487 | final response = await _post(url, params); 488 | if (_isSuccess(response)) { 489 | return PortfolioMetric.fromJson(jsonDecode(response!.data)); 490 | } 491 | 492 | throw Exception("could not receive portfolio metrics for $portfolio"); 493 | } 494 | 495 | @override 496 | Future> portfolioSector(Portfolio portfolio, 497 | {String currency = "EUR"}) async { 498 | const url = '$_baseUrl/portfolio/sector'; 499 | final params = portfolio.toJson()..addAll({'currency': currency}); 500 | 501 | final response = await _post(url, params); 502 | if (_isSuccess(response)) { 503 | List sectors = jsonDecode(response!.data); 504 | return sectors.map((e) => PortfolioSector.fromJson(e)).toList(); 505 | } 506 | 507 | throw Exception("could not receive portfolio metrics for $portfolio"); 508 | } 509 | 510 | @override 511 | Future portfolioBenchmark(Portfolio portfolio) { 512 | throw UnimplementedError(); 513 | } 514 | 515 | @override 516 | Future portfolioPrice(Portfolio portfolio, 517 | {String currency = "EUR"}) async { 518 | const url = '$_baseUrl/portfolio/price'; 519 | final params = portfolio.toJson()..addAll({"currency": currency}); 520 | 521 | var response = await _post(url, params); 522 | if (_isSuccess(response)) { 523 | var parsedJson = json.decode(response!.data); 524 | return Quote.fromJson(parsedJson); 525 | } 526 | 527 | throw Exception("could not receive portfolio price for $portfolio"); 528 | } 529 | 530 | @override 531 | Future portfolioChart(Portfolio portfolio, 532 | {String currency = "EUR", 533 | required int from, 534 | required int to, 535 | required CandleResolution resolution}) async { 536 | const url = '$_baseUrl/portfolio/chart'; 537 | var params = portfolio.toJson() 538 | ..addAll({ 539 | "currency": currency, 540 | "from": from, 541 | "to": to, 542 | "resolution": resolution.str, 543 | }); 544 | 545 | var response = await _post(url, params); 546 | if (_isSuccess(response)) { 547 | var parsedJson = json.decode(response!.data); 548 | return Candles.fromJson(parsedJson); 549 | } 550 | 551 | throw Exception("could not receive portfolio chart for $portfolio"); 552 | } 553 | 554 | @override 555 | Future portfolioStats(Portfolio portfolio, 556 | {String currency = "EUR", 557 | required int from, 558 | required int to, 559 | required CandleResolution resolution}) async { 560 | const url = '$_baseUrl/portfolio/stats'; 561 | var params = portfolio.toJson() 562 | ..addAll({ 563 | "currency": currency, 564 | "from": from, 565 | "to": to, 566 | "resolution": resolution.str, 567 | }); 568 | 569 | final response = await _post(url, params); 570 | if (_isSuccess(response)) { 571 | var parsedJson = json.decode(response!.data); 572 | Candles candles = Candles.fromJson(parsedJson["series"]); 573 | List riskModels = []; 574 | for (var key in parsedJson["riskReturnRatio"].keys) { 575 | riskModels.add(PortfolioRiskModel.fromValue( 576 | key, parsedJson["riskReturnRatio"][key])); 577 | } 578 | 579 | List> correlation = []; 580 | for (var key in parsedJson["correlation"].keys) { 581 | List correlationModels = []; 582 | for (var key2 in parsedJson["correlation"][key].keys) { 583 | correlationModels.add(PortfolioRiskModel.fromValue( 584 | key2, parsedJson["correlation"][key][key2])); 585 | } 586 | correlation.add(correlationModels); 587 | } 588 | return PortfolioStats.fromJson( 589 | parsedJson, candles, riskModels, correlation); 590 | } 591 | 592 | throw Exception("could not receive portfolio stats for $portfolio"); 593 | } 594 | } 595 | -------------------------------------------------------------------------------- /lib/client/cache/bavest_cache_manager.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | class CacheManager { 4 | /// The [failedKeys] is a list of failed keys. 5 | List failedKeys = []; 6 | 7 | /// The [requestedKeys] is a list of requested keys. 8 | List requestedKeys = []; 9 | 10 | /// The [init] method is called to initialize the cache manager. 11 | /// It will reset the failed keys and requested keys. 12 | void init() { 13 | failedKeys = []; 14 | requestedKeys = []; 15 | } 16 | 17 | /// The [listen] method is called to listen to the websocket channel. 18 | /// It will send a request to the websocket channel every 30 seconds for the failed keys. 19 | /// 20 | /// The [channel] is the websocket channel. 21 | /// The [cache] is the memory cache. 22 | /// The [disconnected] is a boolean to check if the websocket is disconnected. 23 | void listen(var channel, var cache, bool disconnected) { 24 | if (disconnected) return; 25 | if (channel == null) return; 26 | 27 | Timer.periodic(const Duration(seconds: 30), (timer) { 28 | if (failedKeys.isEmpty) return; 29 | for (var entry in failedKeys) { 30 | channel!.sink._addToSink(entry.websocketData); 31 | } 32 | failedKeys = []; 33 | }); 34 | } 35 | 36 | /// The [addFailed] method is called to add a failed key to the requested keys list. 37 | /// 38 | /// The [cacheEntry] is the cache entry. 39 | void addFailed(CacheEntry cacheEntry) { 40 | if (failedKeys.indexWhere((e) => e.cacheKey == cacheEntry.cacheKey) == -1) { 41 | failedKeys.add(cacheEntry); 42 | } 43 | } 44 | } 45 | 46 | //// The [CacheEntry] class is used to store the cache key and websocket data. 47 | class CacheEntry { 48 | /// The [cacheKey] is the cache key. 49 | String cacheKey; 50 | 51 | /// The [websocketData] is the websocket data. 52 | String websocketData; 53 | 54 | /// The [CacheEntry] constructor is used to initialize the cache entry. 55 | /// 56 | /// The [cacheKey] is the cache key. 57 | /// The [websocketData] is the websocket data. 58 | CacheEntry(this.cacheKey, this.websocketData); 59 | } 60 | -------------------------------------------------------------------------------- /lib/client/event/bavest_websocket_event.dart: -------------------------------------------------------------------------------- 1 | enum WebsocketEvent { 2 | /// The websocket is connected. 3 | connected, 4 | 5 | /// The websocket is disconnected. 6 | disconnected, 7 | 8 | /// The websocket is reconnecting. 9 | reconnecting, 10 | 11 | /// The websocket is reconnecting. 12 | reconnected, 13 | 14 | /// The websocket indicate 15 | error, 16 | 17 | // The websocket is connecting 18 | connecting, 19 | } 20 | 21 | enum WebsocketEventAction { 22 | quote("quote"), 23 | candle("realtime/candle"), 24 | profile("stock/profile"), 25 | metric("stock/metric"), 26 | dividend("stock/dividend"), 27 | ipo("calender/ipo"), 28 | esg("stock/esg"), 29 | news("stock/news"), 30 | finance("stock/financials"), 31 | fundamentals("stock/fundamentals"), 32 | sentiment("sentiment"), 33 | split("split"), 34 | search("search"), 35 | forex("forex"), 36 | etfProfile("etf/profile"), 37 | etfSector("etf/sector"), 38 | etfCountry("etf/country"), 39 | etfHoldings("etf/holdings"), 40 | peers("stock/peers"), 41 | peersWidget("stock/peers/widget"), 42 | portfolioAllocation("portfolio/allocation"), 43 | portfolioRegion("portfolio/region"), 44 | portfolioStats("portfolio/stats"), 45 | portfolioPrice("portfolio/price"), 46 | portfolioBenchmark("portfolio/benchmark"), 47 | portfolioChart("portfolio/chart"), 48 | keepAlive("ping"); 49 | 50 | const WebsocketEventAction(this.action); 51 | 52 | final String action; 53 | } 54 | -------------------------------------------------------------------------------- /lib/extensions/bavest_function_extension.dart: -------------------------------------------------------------------------------- 1 | extension BavestFunctionExtension on Function { 2 | /// Execute the function if the debug condition is true 3 | /// 4 | void onDebug(bool debug, {required String args}) { 5 | if (debug) { 6 | this(args); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /lib/model/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bavest/dart-sdk/36fa79027308e6636ea5e9a4e72302d81edc86d9/lib/model/.gitkeep -------------------------------------------------------------------------------- /lib/model/v0/etf/country/etf_country.dart: -------------------------------------------------------------------------------- 1 | /// Get [EtfCountry] data for a given [SecurityIdentifier] e.g. 2 | /// [SecurityIdentifier(symbol: 'SPY)]. 3 | class EtfCountry { 4 | List? countryExposure; 5 | String? symbol; 6 | 7 | EtfCountry({countryExposure, symbol}); 8 | 9 | EtfCountry.fromJson(Map json) { 10 | if (json['countryExposure'] != null) { 11 | countryExposure = []; 12 | json['countryExposure'].forEach((v) { 13 | countryExposure!.add(CountryExposure.fromJson(v)); 14 | }); 15 | } 16 | symbol = json['symbol']; 17 | } 18 | 19 | Map toJson() { 20 | final Map data = {}; 21 | if (countryExposure != null) { 22 | data['countryExposure'] = 23 | countryExposure!.map((v) => v.toJson()).toList(); 24 | } 25 | data['symbol'] = symbol; 26 | return data; 27 | } 28 | } 29 | 30 | class CountryExposure { 31 | double? exposure; 32 | String? country; 33 | 34 | CountryExposure({exposure, country}); 35 | 36 | CountryExposure.fromJson(Map json) { 37 | exposure = json['exposure']; 38 | country = json['country']; 39 | } 40 | 41 | Map toJson() { 42 | final Map data = {}; 43 | data['exposure'] = exposure; 44 | data['country'] = country; 45 | return data; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lib/model/v0/etf/holdings/etf_holdings.dart: -------------------------------------------------------------------------------- 1 | /// The [EtfHoldings] data represent the holdings of an ETF e.g. for the ETF 2 | /// SPY [SecurityIdentifier(symbol: 'SPY)]. 3 | class EtfHoldings { 4 | List? holdings; 5 | String? atDate; 6 | String? symbol; 7 | 8 | EtfHoldings({holdings, atDate, symbol}); 9 | 10 | EtfHoldings.fromJson(Map json) { 11 | if (json['holdings'] != null) { 12 | holdings = []; 13 | json['holdings'].forEach((v) { 14 | holdings!.add(Holdings.fromJson(v)); 15 | }); 16 | } 17 | atDate = json['atDate']; 18 | symbol = json['symbol']; 19 | } 20 | 21 | Map toJson() { 22 | final Map data = {}; 23 | if (holdings != null) { 24 | data['holdings'] = holdings!.map((v) => v.toJson()).toList(); 25 | } 26 | data['atDate'] = atDate; 27 | data['symbol'] = symbol; 28 | return data; 29 | } 30 | } 31 | 32 | class Holdings { 33 | String? symbol; 34 | String? cusip; 35 | String? name; 36 | int? share; 37 | double? percent; 38 | double? value; 39 | String? isin; 40 | 41 | Holdings({symbol, cusip, name, share, percent, value, isin}); 42 | 43 | Holdings.fromJson(Map json) { 44 | symbol = json['symbol']; 45 | cusip = json['cusip']; 46 | name = json['name']; 47 | share = json['share']; 48 | percent = json['percent']?.toDouble(); 49 | value = json['value']?.toDouble(); 50 | isin = json['isin']; 51 | } 52 | 53 | Map toJson() { 54 | final Map data = {}; 55 | data['symbol'] = symbol; 56 | data['cusip'] = cusip; 57 | data['name'] = name; 58 | data['share'] = share; 59 | data['percent'] = percent; 60 | data['value'] = value; 61 | data['isin'] = isin; 62 | return data; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/model/v0/etf/profile/etf_profile.dart: -------------------------------------------------------------------------------- 1 | /// The [EtfProfile] data represent the profile of an ETF e.g. for the ETF 2 | /// SPY [SecurityIdentifier(symbol: 'SPY)]. 3 | class EtfProfile { 4 | Profile? profile; 5 | String? symbol; 6 | 7 | EtfProfile({profile, symbol}); 8 | 9 | EtfProfile.fromJson(Map json) { 10 | profile = 11 | json['profile'] != null ? Profile.fromJson(json['profile']) : null; 12 | symbol = json['symbol']; 13 | } 14 | 15 | Map toJson() { 16 | final Map data = {}; 17 | if (profile != null) { 18 | data['profile'] = profile!.toJson(); 19 | } 20 | data['symbol'] = symbol; 21 | return data; 22 | } 23 | } 24 | 25 | class Profile { 26 | String? assetClass; 27 | int? aum; 28 | int? avgVolume; 29 | String? cusip; 30 | String? description; 31 | String? domicile; 32 | String? etfCompany; 33 | double? expenseRatio; 34 | String? inceptionDate; 35 | String? isin; 36 | String? name; 37 | double? nav; 38 | String? navCurrency; 39 | String? website; 40 | int? holdingsCount; 41 | 42 | Profile( 43 | {assetClass, 44 | aum, 45 | avgVolume, 46 | cusip, 47 | description, 48 | domicile, 49 | etfCompany, 50 | expenseRatio, 51 | inceptionDate, 52 | isin, 53 | name, 54 | nav, 55 | navCurrency, 56 | website, 57 | holdingsCount}); 58 | 59 | Profile.fromJson(Map json) { 60 | assetClass = json['assetClass']; 61 | aum = json['aum']; 62 | avgVolume = json['avgVolume']; 63 | cusip = json['cusip']; 64 | description = json['description']; 65 | domicile = json['domicile']; 66 | etfCompany = json['etfCompany']; 67 | expenseRatio = json['expenseRatio']; 68 | inceptionDate = json['inceptionDate']; 69 | isin = json['isin']; 70 | name = json['name']; 71 | nav = json['nav']; 72 | navCurrency = json['navCurrency']; 73 | website = json['website']; 74 | holdingsCount = json['holdingsCount']; 75 | } 76 | 77 | Map toJson() { 78 | final Map data = {}; 79 | data['assetClass'] = assetClass; 80 | data['aum'] = aum; 81 | data['avgVolume'] = avgVolume; 82 | data['cusip'] = cusip; 83 | data['description'] = description; 84 | data['domicile'] = domicile; 85 | data['etfCompany'] = etfCompany; 86 | data['expenseRatio'] = expenseRatio; 87 | data['inceptionDate'] = inceptionDate; 88 | data['isin'] = isin; 89 | data['name'] = name; 90 | data['nav'] = nav; 91 | data['navCurrency'] = navCurrency; 92 | data['website'] = website; 93 | data['holdingsCount'] = holdingsCount; 94 | return data; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /lib/model/v0/etf/sector/etf_sector.dart: -------------------------------------------------------------------------------- 1 | /// The [EtfSector] data represent the sector of an ETF e.g. for the ETF 2 | /// SPY [SecurityIdentifier(symbol: 'SPY)]. 3 | class EtfSector { 4 | String? symbol; 5 | List? sectorExposure; 6 | 7 | EtfSector({symbol, sectorExposure}); 8 | 9 | EtfSector.fromJson(Map json) { 10 | symbol = json['symbol']; 11 | if (json['sectorExposure'] != null) { 12 | sectorExposure = []; 13 | json['sectorExposure'].forEach((v) { 14 | sectorExposure!.add(SectorExposure.fromJson(v)); 15 | }); 16 | } 17 | } 18 | 19 | Map toJson() { 20 | final Map data = {}; 21 | data['symbol'] = symbol; 22 | if (sectorExposure != null) { 23 | data['sectorExposure'] = sectorExposure!.map((v) => v.toJson()).toList(); 24 | } 25 | return data; 26 | } 27 | } 28 | 29 | class SectorExposure { 30 | double? weightPercentage; 31 | String? sector; 32 | 33 | SectorExposure({weightPercentage, sector}); 34 | 35 | SectorExposure.fromJson(Map json) { 36 | weightPercentage = json['weightPercentage']?.toDouble(); 37 | sector = json['sector']; 38 | } 39 | 40 | Map toJson() { 41 | final Map data = {}; 42 | data['weightPercentage'] = weightPercentage?.toDouble(); 43 | data['sector'] = sector; 44 | return data; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/model/v0/forex/forex.dart: -------------------------------------------------------------------------------- 1 | /// The [Forex] data represent the exchange rate of two currencies 2 | /// e.g. for the exchange rate of EUR to USD. 3 | class Forex { 4 | /// The success of the request. 5 | bool? success; 6 | 7 | /// The query of the request. 8 | Query? query; 9 | 10 | /// Additional information about the request. 11 | Info? info; 12 | 13 | /// The date of the request. 14 | String? date; 15 | 16 | /// The result of the request e.g. the exchange rate. 17 | double? result; 18 | 19 | Forex({this.success, this.query, this.info, this.date, this.result}); 20 | 21 | Forex.fromJson(Map json) { 22 | success = json['success']; 23 | query = json['query'] != null ? Query.fromJson(json['query']) : null; 24 | info = json['info'] != null ? Info.fromJson(json['info']) : null; 25 | date = json['date']; 26 | result = json['result']; 27 | } 28 | 29 | Map toJson() { 30 | final Map data = {}; 31 | data['success'] = success; 32 | if (query != null) { 33 | data['query'] = query!.toJson(); 34 | } 35 | if (info != null) { 36 | data['info'] = info!.toJson(); 37 | } 38 | data['date'] = date; 39 | data['result'] = result; 40 | return data; 41 | } 42 | } 43 | 44 | class Query { 45 | String? from; 46 | String? to; 47 | 48 | Query({this.from, this.to}); 49 | 50 | Query.fromJson(Map json) { 51 | from = json['from']; 52 | to = json['to']; 53 | } 54 | 55 | Map toJson() { 56 | final Map data = {}; 57 | data['from'] = from; 58 | data['to'] = to; 59 | return data; 60 | } 61 | } 62 | 63 | class Info { 64 | String? timestamp; 65 | double? rate; 66 | 67 | Info({this.timestamp, this.rate}); 68 | 69 | Info.fromJson(Map json) { 70 | timestamp = json['timestamp']; 71 | rate = json['rate']; 72 | } 73 | 74 | Map toJson() { 75 | final Map data = {}; 76 | data['timestamp'] = timestamp; 77 | data['rate'] = rate; 78 | return data; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lib/model/v0/portfolio/allocation/portfolio_allocation.dart: -------------------------------------------------------------------------------- 1 | /// The [PortfolioAllocation] data represent the allocation of a portfolio. 2 | class PortfolioAllocation { 3 | PortfolioAllocation({ 4 | required this.symbol, 5 | required this.percentage, 6 | }); 7 | 8 | /// The symbol of the security. 9 | String symbol; 10 | 11 | /// The percentage of the security in the portfolio. 12 | double percentage; 13 | 14 | factory PortfolioAllocation.fromJson(Map json) => 15 | PortfolioAllocation( 16 | symbol: json["symbol"], 17 | percentage: json["percentage"].toDouble(), 18 | ); 19 | 20 | Map toJson() => { 21 | "symbol": symbol, 22 | "percentage": percentage, 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /lib/model/v0/portfolio/metric/portfolio_metric.dart: -------------------------------------------------------------------------------- 1 | /// The [PortfolioMetric] data represent the metrics of a portfolio. 2 | class PortfolioMetric { 3 | PortfolioMetric({ 4 | required this.beta, 5 | required this.the26WeekPriceReturnDaily, 6 | required this.the5DayPriceReturnDaily, 7 | required this.the52WeekPriceReturnDaily, 8 | required this.dividendPerShareAnnual, 9 | required this.treynorQuotient, 10 | required this.sharpeRatio, 11 | required this.alpha, 12 | }); 13 | 14 | double beta; 15 | double the26WeekPriceReturnDaily; 16 | double the5DayPriceReturnDaily; 17 | double? the52WeekPriceReturnDaily; 18 | double? dividendPerShareAnnual; 19 | double? treynorQuotient; 20 | double? sharpeRatio; 21 | double? alpha; 22 | 23 | factory PortfolioMetric.fromJson(Map json) => 24 | PortfolioMetric( 25 | beta: json["beta"].toDouble(), 26 | the26WeekPriceReturnDaily: json["26WeekPriceReturnDaily"]?.toDouble(), 27 | the5DayPriceReturnDaily: json["5DayPriceReturnDaily"]?.toDouble(), 28 | the52WeekPriceReturnDaily: json["52WeekPriceReturnDaily"]?.toDouble(), 29 | dividendPerShareAnnual: json["dividendPerShareAnnual"]?.toDouble(), 30 | treynorQuotient: json["treynorQuotient"]?.toDouble(), 31 | sharpeRatio: json["sharpeRatio"]?.toDouble(), 32 | alpha: json["alpha"]?.toDouble(), 33 | ); 34 | 35 | Map toJson() => { 36 | "beta": beta, 37 | "26WeekPriceReturnDaily": the26WeekPriceReturnDaily, 38 | "5DayPriceReturnDaily": the5DayPriceReturnDaily, 39 | "52WeekPriceReturnDaily": the52WeekPriceReturnDaily, 40 | "dividendPerShareAnnual": dividendPerShareAnnual, 41 | "treynorQuotient": treynorQuotient, 42 | "sharpeRatio": sharpeRatio, 43 | "alpha": alpha, 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /lib/model/v0/portfolio/portfolio.dart: -------------------------------------------------------------------------------- 1 | import 'package:bavest/model/v0/portfolio/trade_direction.dart'; 2 | 3 | /// Portfolio tracks all transactions of a user. 4 | class Portfolio { 5 | /// List of transactions 6 | final List transactions; 7 | 8 | Portfolio({required this.transactions}); 9 | 10 | factory Portfolio.fromJson(Map json) => Portfolio( 11 | transactions: List.from( 12 | json["portfolio_items"].map((x) => Transactions.fromJson(x))), 13 | ); 14 | 15 | Map toJson() => { 16 | "portfolio_items": 17 | List.from(transactions.map((x) => x.toJson())), 18 | }; 19 | } 20 | 21 | /// Transactions represent a single transaction of a user e.g. buy or sell. 22 | /// 23 | /// The [symbol] parameter is the security symbol. 24 | /// The [amount] parameter is used to determine the trade direction. 25 | /// The [buyDate] parameter is the buy date Unix timestamp. 26 | /// The [tradeDirection] parameter is the trade direction e.g. buy or sell. 27 | class Transactions { 28 | /// Security symbol 29 | final String symbol; 30 | 31 | /// Amount of shares 32 | final double amount; 33 | 34 | /// Buy date Unix timestamp 35 | final int? buyDate; 36 | 37 | /// Trade direction 38 | final TradeDirection tradeDirection; 39 | 40 | /// Constructor to create a new Transactions object. 41 | Transactions( 42 | {required this.symbol, 43 | required this.amount, 44 | required this.buyDate, 45 | required this.tradeDirection}); 46 | 47 | /// Factory method to create a new Transactions object without 48 | /// specifying the trade direction. 49 | /// 50 | /// The [symbol] parameter is the security symbol. 51 | /// The [amount] parameter is used to determine the trade direction. 52 | /// The [buyDate] parameter is the buy date Unix timestamp. 53 | factory Transactions.create( 54 | {required String symbol, 55 | required double amount, 56 | required int buyDate}) => 57 | Transactions( 58 | symbol: symbol, 59 | amount: amount, 60 | buyDate: buyDate, 61 | tradeDirection: 62 | amount > 0 ? TradeDirection.buy : TradeDirection.sell); 63 | 64 | factory Transactions.fromJson(Map json) => Transactions( 65 | symbol: json["symbol"], 66 | amount: json["amount"].toDouble(), 67 | buyDate: json["buy_date"]?.toInt(), 68 | tradeDirection: json["amount"].toInt() > 0 69 | ? TradeDirection.buy 70 | : TradeDirection.sell, 71 | ); 72 | 73 | Map toJson() => { 74 | "symbol": symbol, 75 | "amount": amount, 76 | "buy_date": buyDate, 77 | }; 78 | } 79 | -------------------------------------------------------------------------------- /lib/model/v0/portfolio/region/portfolio_region.dart: -------------------------------------------------------------------------------- 1 | /// The [PortfolioRegion] data represent the region of a portfolio. 2 | class PortfolioRegion { 3 | String? region; 4 | double? percentage; 5 | 6 | PortfolioRegion({region, percentage}); 7 | 8 | PortfolioRegion.fromJson(Map json) { 9 | region = json['region']; 10 | percentage = json['percentage']?.toDouble(); 11 | } 12 | 13 | Map toJson() { 14 | final Map data = {}; 15 | data['region'] = region; 16 | data['percentage'] = percentage; 17 | return data; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/model/v0/portfolio/sector/portfolio_sector.dart: -------------------------------------------------------------------------------- 1 | /// The [PortfolioSector] data represent the sector of a portfolio. 2 | class PortfolioSector { 3 | PortfolioSector({ 4 | required this.sector, 5 | required this.percentage, 6 | }); 7 | 8 | String sector; 9 | double percentage; 10 | 11 | factory PortfolioSector.fromJson(Map json) => 12 | PortfolioSector( 13 | sector: json["sector"], 14 | percentage: json["percentage"].toDouble(), 15 | ); 16 | 17 | Map toJson() => { 18 | "sector": sector, 19 | "percentage": percentage, 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /lib/model/v0/portfolio/stats/portfolio_stats.dart: -------------------------------------------------------------------------------- 1 | import 'package:bavest/model/v0/portfolio/stats/risk_model.dart'; 2 | import 'package:bavest/model/v0/stock/candle/candle.dart'; 3 | 4 | /// The PortfolioStats class is a model that contains all the statistics of a portfolio. 5 | class PortfolioStats { 6 | PortfolioStats( 7 | {required this.candles, 8 | required this.riskFree, 9 | required this.totalReturn, 10 | required this.cagr, 11 | required this.correlation, 12 | required this.riskModels, 13 | required this.maxDrawdown, 14 | required this.calmar, 15 | required this.mtd, 16 | required this.threeMonth, 17 | required this.sixMonth, 18 | required this.ytd, 19 | required this.oneYear, 20 | required this.threeYear, 21 | required this.fiveYear, 22 | required this.tenYear, 23 | required this.inception, 24 | required this.dailySharpe, 25 | required this.dailySortino, 26 | required this.dailyMean, 27 | required this.dailyVolume, 28 | required this.dailySkew, 29 | required this.dailyKurt, 30 | required this.bestDay, 31 | required this.worstDay, 32 | required this.monthlySharpe, 33 | required this.monthlySortino, 34 | required this.monthlyMean, 35 | required this.monthlyVol, 36 | required this.monthlySkew, 37 | required this.monthlyKurt, 38 | required this.bestMonth, 39 | required this.worstMonth, 40 | required this.yearlySharpe, 41 | required this.yearlySortino, 42 | required this.yearlyMean, 43 | required this.yearlyVol, 44 | required this.yearlySkew, 45 | required this.yearlyKurt, 46 | required this.bestYear, 47 | required this.worstYear, 48 | required this.avgDrawdown, 49 | required this.avgDrawdownDays, 50 | required this.avgUpMonth, 51 | required this.avgDownMonth, 52 | required this.winYearPerc, 53 | required this.twelveMonthWinPerc}); 54 | 55 | double? riskFree; 56 | double? totalReturn; 57 | double? cagr; 58 | double? maxDrawdown; 59 | 60 | double? calmar; 61 | double? mtd; 62 | double? threeMonth; 63 | double? sixMonth; 64 | 65 | double? ytd; 66 | double? oneYear; 67 | double? threeYear; 68 | double? fiveYear; 69 | 70 | double? tenYear; 71 | double? inception; 72 | double? dailySharpe; 73 | double? dailySortino; 74 | 75 | double? dailyMean; 76 | double? dailyVolume; 77 | double? dailySkew; 78 | double? dailyKurt; 79 | 80 | double? bestDay; 81 | double? worstDay; 82 | double? monthlySharpe; 83 | double? monthlySortino; 84 | 85 | double? monthlyMean; 86 | double? monthlyVol; 87 | double? monthlySkew; 88 | double? monthlyKurt; 89 | 90 | double? bestMonth; 91 | double? worstMonth; 92 | double? yearlySharpe; 93 | double? yearlySortino; 94 | 95 | double? yearlyMean; 96 | double? yearlyVol; 97 | double? yearlySkew; 98 | double? yearlyKurt; 99 | 100 | double? bestYear; 101 | double? worstYear; 102 | double? avgDrawdown; 103 | double? avgDrawdownDays; 104 | 105 | double? avgUpMonth; 106 | double? avgDownMonth; 107 | double? winYearPerc; 108 | double? twelveMonthWinPerc; 109 | 110 | Candles? candles; 111 | List riskModels = []; 112 | List> correlation = []; 113 | 114 | factory PortfolioStats.fromJson( 115 | Map json, 116 | Candles candles, 117 | List riskModels, 118 | List> correlation) { 119 | final response = json["stats"]; 120 | return PortfolioStats( 121 | candles: candles, 122 | riskModels: riskModels, 123 | correlation: correlation, 124 | riskFree: response["riskFree"], 125 | totalReturn: response["totalReturn"], 126 | cagr: response["cagr"], 127 | maxDrawdown: response["maxDrawdown"], 128 | calmar: response["calmar"], 129 | mtd: response["mtd"], 130 | threeMonth: response["threeMonth"], 131 | sixMonth: response["sixMonth"], 132 | ytd: response["ytd"], 133 | oneYear: response["oneYear"], 134 | threeYear: response["threeYear"], 135 | fiveYear: response["fiveYear"], 136 | tenYear: response["tenYear"], 137 | inception: response["inception"], 138 | dailySharpe: response["dailySharpe"], 139 | dailySortino: response["dailySortino"], 140 | dailyMean: response["dailyMean"], 141 | dailyVolume: response["dailyVolume"], 142 | dailySkew: response["dailySkew"], 143 | dailyKurt: response["dailyKurt"], 144 | bestDay: response["bestDay"], 145 | worstDay: response["worstDay"], 146 | monthlySharpe: response["monthlySharpe"], 147 | monthlySortino: response["monthlySortino"], 148 | monthlyMean: response["monthlyMean"], 149 | monthlyVol: response["monthlyVol"], 150 | monthlySkew: response["monthlySkew"], 151 | monthlyKurt: response["monthlyKurt"], 152 | bestMonth: response["bestMonth"], 153 | worstMonth: response["worstMonth"], 154 | yearlySharpe: response["yearlySharpe"], 155 | yearlySortino: response["yearlySortino"], 156 | yearlyMean: response["yearlyMean"], 157 | yearlyVol: response["yearlyVol"], 158 | yearlySkew: response["yearlySkew"], 159 | yearlyKurt: response["yearlyKurt"], 160 | bestYear: response["bestYear"], 161 | worstYear: response["worstYear"], 162 | avgDrawdown: response["avgDrawdown"], 163 | avgDrawdownDays: response["avgDrawdownDays"], 164 | avgUpMonth: response["avgUpMonth"], 165 | avgDownMonth: response["avgDownMonth"], 166 | winYearPerc: response["winYearPerc"], 167 | twelveMonthWinPerc: response["twelveMonthWinPerc"], 168 | ); 169 | } 170 | 171 | Map toJson() => { 172 | "riskFree": riskFree, 173 | "totalReturn": totalReturn, 174 | "cagr": cagr, 175 | "maxDrawdown": maxDrawdown, 176 | "calmar": calmar, 177 | "mtd": mtd, 178 | "threeMonth": threeMonth, 179 | "sixMonth": sixMonth, 180 | "ytd": ytd, 181 | "oneYear": oneYear, 182 | "threeYear": threeYear, 183 | "fiveYear": fiveYear, 184 | "tenYear": tenYear, 185 | "inception": inception, 186 | "dailySharpe": dailySharpe, 187 | "dailySortino": dailySortino, 188 | "dailyMean": dailyMean, 189 | "dailyVolume": dailyVolume, 190 | "dailySkew": dailySkew, 191 | "dailyKurt": dailyKurt, 192 | "bestDay": bestDay, 193 | "worstDay": worstDay, 194 | "monthlySharpe": monthlySharpe, 195 | "monthlySortino": monthlySortino, 196 | "monthlyMean": monthlyMean, 197 | "monthlyVol": monthlyVol, 198 | "monthlySkew": monthlySkew, 199 | "monthlyKurt": monthlyKurt, 200 | "bestMonth": bestMonth, 201 | "worstMonth": worstMonth, 202 | "yearlySharpe": yearlySharpe, 203 | "yearlySortino": yearlySortino, 204 | "yearlyMean": yearlyMean, 205 | "yearlyVol": yearlyVol, 206 | "yearlySkew": yearlySkew, 207 | "yearlyKurt": yearlyKurt, 208 | "bestYear": bestYear, 209 | "worstYear": worstYear, 210 | "avgDrawdown": avgDrawdown, 211 | "avgDrawdownDays": avgDrawdownDays, 212 | "avgUpMonth": avgUpMonth, 213 | "avgDownMonth": avgDownMonth, 214 | "winYearPerc": winYearPerc, 215 | "twelveMonthWinPerc": twelveMonthWinPerc, 216 | }; 217 | } 218 | -------------------------------------------------------------------------------- /lib/model/v0/portfolio/stats/risk_model.dart: -------------------------------------------------------------------------------- 1 | /// The [PortfolioRiskModel] data represent the risk metrics of a portfolio. 2 | class PortfolioRiskModel { 3 | String symbol; 4 | double value; 5 | 6 | PortfolioRiskModel( 7 | this.symbol, 8 | this.value, 9 | ); 10 | 11 | factory PortfolioRiskModel.fromValue(String symbol, double value) { 12 | return PortfolioRiskModel( 13 | symbol, 14 | value, 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/model/v0/portfolio/trade_direction.dart: -------------------------------------------------------------------------------- 1 | /// TradeDirection enum represents the trade direction e.g. buy or sell. 2 | /// For more information see [Transactions]. 3 | enum TradeDirection { 4 | buy, 5 | sell, 6 | } 7 | -------------------------------------------------------------------------------- /lib/model/v0/search/search.dart: -------------------------------------------------------------------------------- 1 | /// The [SearchResult] data represent the search results. The [SearchResult] contain 2 | /// a list of [Results]. The [Results] contain the symbol, company name, 3 | /// isin, is etf, is actively trading, is adr, is fund, currency and market 4 | /// capitalization. 5 | class SearchResult { 6 | /// Search request status code. 7 | int? statusCode; 8 | 9 | /// Search request results. 10 | List? results; 11 | 12 | SearchResult({statusCode, results}); 13 | 14 | SearchResult.fromJson(Map json) { 15 | statusCode = json['statusCode']; 16 | if (json['results'] != null) { 17 | results = []; 18 | json['results'].forEach((v) { 19 | results!.add(Results.fromJson(v)); 20 | }); 21 | } 22 | } 23 | 24 | Map toJson() { 25 | final Map data = {}; 26 | data['statusCode'] = statusCode; 27 | if (results != null) { 28 | data['results'] = results!.map((v) => v.toJson()).toList(); 29 | } 30 | return data; 31 | } 32 | } 33 | 34 | /// The [Results] data represent the search results. 35 | /// The [Results] contain the symbol, company name, 36 | /// isin, is etf, is actively trading, is adr, is fund, currency and market 37 | /// capitalization. By default the results are sorted by market capitalization 38 | /// and country codes. 39 | class Results { 40 | /// The symbol of the company. 41 | String? symbol; 42 | 43 | /// The company name. 44 | String? companyName; 45 | 46 | /// The isin of the company. 47 | String? isin; 48 | 49 | /// The etf of the company. 50 | bool? isEtf; 51 | 52 | /// The actively trading of the company. 53 | bool? isActivelyTrading; 54 | 55 | /// The adr of the company. 56 | bool? isAdr; 57 | 58 | /// The fund of the company. 59 | bool? isFund; 60 | 61 | /// The currency of the company. 62 | String? currency; 63 | 64 | /// The market capitalization of the company. 65 | double? marketCapitalization; 66 | 67 | Results( 68 | {symbol, 69 | companyName, 70 | isin, 71 | isEtf, 72 | isActivelyTrading, 73 | isAdr, 74 | isFund, 75 | currency, 76 | marketCapitalization}); 77 | 78 | Results.fromJson(Map json) { 79 | symbol = json['symbol']; 80 | companyName = json['companyName']; 81 | isin = json['isin']; 82 | isEtf = json['isEtf']; 83 | isActivelyTrading = json['isActivelyTrading']; 84 | isAdr = json['isAdr']; 85 | isFund = json['isFund']; 86 | currency = json['currency']; 87 | marketCapitalization = json['marketCapitalization']?.toDouble(); 88 | } 89 | 90 | Map toJson() { 91 | final Map data = {}; 92 | data['symbol'] = symbol; 93 | data['companyName'] = companyName; 94 | data['isin'] = isin; 95 | data['isEtf'] = isEtf; 96 | data['isActivelyTrading'] = isActivelyTrading; 97 | data['isAdr'] = isAdr; 98 | data['isFund'] = isFund; 99 | data['currency'] = currency; 100 | data['marketCapitalization'] = marketCapitalization; 101 | return data; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /lib/model/v0/security/security_identifier.dart: -------------------------------------------------------------------------------- 1 | /// The [SecurityIdentifier] data represent the identifier of a security. 2 | /// The identifier can be a symbol, ISIN, CUSIP or WKN. At the moment Bavest 3 | /// only supports the symbol. 4 | class SecurityIdentifier { 5 | /// Identifier by symbol 6 | final String? symbol; 7 | 8 | /// Identifier by ISIN currently not supported 9 | final String? isin; 10 | 11 | /// Identifier by CUSIP currently not supported 12 | final String? cusip; 13 | 14 | /// Identifier by WKN currently not supported 15 | final String? wkn; 16 | 17 | SecurityIdentifier({this.symbol, this.isin, this.cusip, this.wkn}) 18 | : assert( 19 | !(symbol == null && isin == null && cusip == null && wkn == null)); 20 | 21 | factory SecurityIdentifier.fromJson(Map json) => 22 | SecurityIdentifier( 23 | symbol: json['symbol'], 24 | isin: json['isin'], 25 | cusip: json['cusip'], 26 | wkn: json['wkn'], 27 | ); 28 | 29 | @override 30 | String toString() { 31 | if (symbol != null) { 32 | return 'SecurityIdentifier(symbol: $symbol)'; 33 | } else if (isin != null) { 34 | return 'SecurityIdentifier(isin: $isin)'; 35 | } else if (cusip != null) { 36 | return 'SecurityIdentifier(cusip: $cusip)'; 37 | } else if (wkn != null) { 38 | return 'SecurityIdentifier(wkn: $wkn)'; 39 | } else { 40 | // Never reached because of assert in constructor 41 | throw Exception('No identifier found'); 42 | } 43 | } 44 | 45 | /// Returns a map with the identifier as key and the value as value. 46 | /// This is used to provide extensions in future versions. 47 | /// 48 | /// The security identifier can easily by extended by adding a new field 49 | /// and therefore we don't have to change any method signature. 50 | Map toJson() { 51 | if (symbol != null) { 52 | return {'symbol': symbol.toString()}; 53 | } else if (isin != null) { 54 | return {'isin': isin.toString()}; 55 | } else if (cusip != null) { 56 | return {'cusip': cusip.toString()}; 57 | } else if (wkn != null) { 58 | return {'wkn': wkn.toString()}; 59 | } else { 60 | // Never reached because of assert in constructor 61 | throw Exception('No identifier found'); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/model/v0/security/security_type.dart: -------------------------------------------------------------------------------- 1 | /// The type of a security e.g. stock, etf, adr, fund. 2 | enum SecurityType { stock, etf, adr, fund } 3 | -------------------------------------------------------------------------------- /lib/model/v0/sentiment/sentiment.dart: -------------------------------------------------------------------------------- 1 | /// The Bavest Finance SDK [Sentiment] data represent the sentiment of the 2 | /// company news. 3 | class Sentiment { 4 | Sentiment({ 5 | this.score, 6 | this.len, 7 | this.negative, 8 | this.positive, 9 | this.neutral, 10 | }); 11 | 12 | double? score; 13 | double? negative; 14 | double? neutral; 15 | double? positive; 16 | int? len; 17 | 18 | factory Sentiment.fromJson(Map json) => Sentiment( 19 | score: json["score"].toDouble(), 20 | len: json["len"], 21 | positive: (json["positive"]).toDouble(), 22 | neutral: (json["neutral"]).toDouble(), 23 | negative: (json["negative"]).toDouble()); 24 | 25 | Map toJson() => { 26 | "score": score, 27 | "len": len, 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /lib/model/v0/stock/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Bavest/dart-sdk/36fa79027308e6636ea5e9a4e72302d81edc86d9/lib/model/v0/stock/.gitkeep -------------------------------------------------------------------------------- /lib/model/v0/stock/candle/candle.dart: -------------------------------------------------------------------------------- 1 | /// The candle data returns a list of candles. Close price, high price, low price, open price, status, timestamps, from, to and resolution are required. The from, to and resolution are optional. 2 | class Candles { 3 | List close; 4 | 5 | List high; 6 | 7 | List low; 8 | 9 | List open; 10 | 11 | String status; 12 | 13 | List timestamps; 14 | 15 | int? from; 16 | 17 | int? to; 18 | 19 | String? resolution; 20 | 21 | Candles( 22 | this.close, this.high, this.low, this.open, this.status, this.timestamps, 23 | {this.from, this.to, this.resolution}); 24 | 25 | static Candles fromJson(Map json) => Candles( 26 | (json['c'] as List) 27 | .map( 28 | (e) => (e as num).toDouble(), 29 | ) 30 | .toList(), 31 | (json['h'] as List) 32 | .map( 33 | (e) => (e as num).toDouble(), 34 | ) 35 | .toList(), 36 | (json['l'] as List) 37 | .map( 38 | (e) => (e as num).toDouble(), 39 | ) 40 | .toList(), 41 | (json['o'] as List) 42 | .map( 43 | (e) => (e as num).toDouble(), 44 | ) 45 | .toList(), 46 | json['s'] as String, 47 | (json['t'] as List).map((e) => e.toInt() as int).toList(), 48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /lib/model/v0/stock/candle/candle_type.dart: -------------------------------------------------------------------------------- 1 | /// The [CandleResolution] data represent the candle resolution e.g. 2 | /// 1 second, 5 seconds, 60 seconds, 1 minute, 1 day, 1 week, 1 month. 3 | /// 4 | /// Adjust the candle resolution according to the date range. 5 | enum CandleResolution { 6 | oneSecond, 7 | fiveSeconds, 8 | sixtySeconds, 9 | minute, 10 | day, 11 | week, 12 | month, 13 | } 14 | 15 | /// The [CandleTypeExtension] extend the [CandleResolution] to get the string value and use it for 16 | /// the JSON conversion. 17 | extension CandleTypeExtension on CandleResolution { 18 | String get str { 19 | switch (this) { 20 | case CandleResolution.oneSecond: 21 | return '1'; 22 | case CandleResolution.fiveSeconds: 23 | return '5'; 24 | case CandleResolution.sixtySeconds: 25 | return '60'; 26 | case CandleResolution.minute: 27 | return 'M'; 28 | case CandleResolution.day: 29 | return 'D'; 30 | case CandleResolution.week: 31 | return 'W'; 32 | case CandleResolution.month: 33 | return 'M'; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/model/v0/stock/dividend/dividend.dart: -------------------------------------------------------------------------------- 1 | /// The [DividendData] data represent the dividend data of a company e.g. 2 | /// date, recordDate, amount, declarationDate, adjustedAmount, payDate. 3 | class DividendData { 4 | /// The date of the dividend. 5 | DateTime? date; 6 | 7 | /// The record date of the dividend. 8 | String? recordDate; 9 | 10 | /// The amount of the dividend. 11 | double? amount; 12 | 13 | /// The declaration date of the dividend. 14 | String? declarationDate; 15 | 16 | /// The adjusted amount of the dividend. 17 | double? adjustedAmount; 18 | 19 | /// The pay date of the dividend. 20 | String? payDate; 21 | 22 | DividendData( 23 | {required date, 24 | recordDate, 25 | amount, 26 | declarationDate, 27 | adjustedAmount, 28 | payDate}); 29 | 30 | DividendData.fromJson(Map json) { 31 | date = DateTime.parse(json["date"]); 32 | recordDate = json['recordDate']; 33 | amount = json['amount']?.toDouble(); 34 | declarationDate = json['declarationDate']; 35 | adjustedAmount = json['adjustedAmount']?.toDouble(); 36 | payDate = json['payDate']; 37 | } 38 | 39 | Map toJson() { 40 | final Map data = {}; 41 | data['date'] = date; 42 | data['recordDate'] = recordDate; 43 | data['amount'] = amount; 44 | data['declarationDate'] = declarationDate; 45 | data['adjustedAmount'] = adjustedAmount; 46 | data['payDate'] = payDate; 47 | return data; 48 | } 49 | } 50 | 51 | /// The [Dividends] data represent the dividends of a company. 52 | class Dividends { 53 | Dividends({ 54 | required data, 55 | required symbol, 56 | }); 57 | 58 | List? data; 59 | String? symbol; 60 | 61 | Dividends.fromJson(Map json) { 62 | if (json['data'] != null) { 63 | data = []; 64 | json['data'].forEach((v) { 65 | data!.add(DividendData.fromJson(v)); 66 | }); 67 | } 68 | symbol = json['symbol']; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/model/v0/stock/esg/esg.dart: -------------------------------------------------------------------------------- 1 | /// The [Esg] data represent the ESG data of the company e.g. 2 | /// the environment score, the governance score, the social score, the total ESG score. 3 | class Esg { 4 | /// The [EsgData] data represent the ESG data of the company. 5 | List? data; 6 | 7 | /// The [Series] data represent the series of the ESG data. 8 | Series? series; 9 | 10 | /// The [Sector] data represent the sector of the ESG data. 11 | Sector? sector; 12 | 13 | /// The [IndustrieRating] data represent the industry rating of the ESG data. 14 | IndustrieRating? industryRating; 15 | 16 | /// The environment score of the ESG data. 17 | double? environmentScore; 18 | 19 | /// The governance score of the ESG data. 20 | double? governanceScore; 21 | 22 | /// The social score of the ESG data. 23 | double? socialScore; 24 | 25 | /// The symbol of the ESG data. 26 | String? symbol; 27 | 28 | /// The total ESG score of the ESG data. 29 | double? totalEsg; 30 | 31 | Esg( 32 | {this.data, 33 | this.series, 34 | this.sector, 35 | this.industryRating, 36 | this.environmentScore, 37 | this.governanceScore, 38 | this.socialScore, 39 | this.symbol, 40 | this.totalEsg}); 41 | 42 | Esg.fromJson(Map json) { 43 | if (json['data'] != null) { 44 | data = []; 45 | json['data'].forEach((v) { 46 | data!.add(EsgData.fromJson(v)); 47 | }); 48 | } 49 | series = json['series'] != null ? Series.fromJson(json['series']) : null; 50 | sector = json['sector'] != null ? Sector.fromJson(json['sector']) : null; 51 | industryRating = json['industrie-rating'] != null 52 | ? IndustrieRating.fromJson(json['industrie-rating']) 53 | : null; 54 | 55 | environmentScore = json['environmentScore']?.toDouble(); 56 | governanceScore = json['governanceScore']?.toDouble(); 57 | socialScore = json['socialScore']?.toDouble(); 58 | symbol = json['symbol']; 59 | totalEsg = json['totalEsg']?.toDouble(); 60 | } 61 | } 62 | 63 | /// The [EsgData] data represent the ESG data of the company. 64 | class EsgData { 65 | String? formType; 66 | String? acceptedDate; 67 | String? date; 68 | 69 | EsgData({this.formType, this.acceptedDate, this.date}); 70 | 71 | EsgData.fromJson(Map json) { 72 | formType = json['formType']; 73 | acceptedDate = json['acceptedDate']; 74 | date = json['date']; 75 | } 76 | } 77 | 78 | class Series { 79 | List? totalEsg; 80 | List? socialScore; 81 | List? governanceScore; 82 | List? environmentScore; 83 | 84 | Series( 85 | {this.totalEsg, 86 | this.socialScore, 87 | this.governanceScore, 88 | this.environmentScore}); 89 | 90 | Series.fromJson(Map json) { 91 | if (json['totalEsg'] != null) { 92 | totalEsg = []; 93 | json['totalEsg'].forEach((v) { 94 | totalEsg!.add(EsgSeries.fromJson(v)); 95 | }); 96 | } 97 | if (json['socialScore'] != null) { 98 | socialScore = []; 99 | json['socialScore'].forEach((v) { 100 | socialScore!.add(EsgSeries.fromJson(v)); 101 | }); 102 | } 103 | if (json['governanceScore'] != null) { 104 | governanceScore = []; 105 | json['governanceScore'].forEach((v) { 106 | governanceScore!.add(EsgSeries.fromJson(v)); 107 | }); 108 | } 109 | if (json['environmentScore'] != null) { 110 | environmentScore = []; 111 | json['environmentScore'].forEach((v) { 112 | environmentScore!.add(EsgSeries.fromJson(v)); 113 | }); 114 | } 115 | } 116 | } 117 | 118 | class EsgSeries { 119 | double? score; 120 | String? date; 121 | 122 | EsgSeries({this.score, this.date}); 123 | 124 | EsgSeries.fromJson(Map json) { 125 | score = json['score']?.toDouble(); 126 | date = json['date']; 127 | } 128 | } 129 | 130 | class Sector { 131 | int? year; 132 | String? sector; 133 | EnvironmentalScore? environmentalScore; 134 | EnvironmentalScore? socialScore; 135 | EnvironmentalScore? governanceScore; 136 | EnvironmentalScore? totalEsg; 137 | 138 | Sector( 139 | {this.year, 140 | this.sector, 141 | this.environmentalScore, 142 | this.socialScore, 143 | this.governanceScore, 144 | this.totalEsg}); 145 | 146 | Sector.fromJson(Map json) { 147 | year = json['year']; 148 | sector = json['sector']; 149 | environmentalScore = json['environmentalScore'] != null 150 | ? EnvironmentalScore.fromJson(json['environmentalScore']) 151 | : null; 152 | socialScore = json['socialScore'] != null 153 | ? EnvironmentalScore.fromJson(json['socialScore']) 154 | : null; 155 | governanceScore = json['governanceScore'] != null 156 | ? EnvironmentalScore.fromJson(json['governanceScore']) 157 | : null; 158 | totalEsg = json['totalEsg'] != null 159 | ? EnvironmentalScore.fromJson(json['totalEsg']) 160 | : null; 161 | } 162 | } 163 | 164 | class EnvironmentalScore { 165 | double? score; 166 | double? d; 167 | 168 | EnvironmentalScore({this.score, this.d}); 169 | 170 | EnvironmentalScore.fromJson(Map json) { 171 | score = json['score']; 172 | d = json['d']; 173 | } 174 | } 175 | 176 | class IndustrieRating { 177 | String? symbol; 178 | String? cik; 179 | String? companyName; 180 | String? industry; 181 | int? year; 182 | String? eSGRiskRating; 183 | IndustryRank? industryRank; 184 | 185 | IndustrieRating( 186 | {this.symbol, 187 | this.cik, 188 | this.companyName, 189 | this.industry, 190 | this.year, 191 | this.eSGRiskRating, 192 | this.industryRank}); 193 | 194 | IndustrieRating.fromJson(Map json) { 195 | symbol = json['symbol']; 196 | cik = json['cik']; 197 | companyName = json['companyName']; 198 | industry = json['industry']; 199 | year = json['year']; 200 | eSGRiskRating = json['ESGRiskRating']; 201 | industryRank = json['industryRank'] != null 202 | ? IndustryRank.fromJson(json['industryRank']) 203 | : null; 204 | } 205 | } 206 | 207 | class IndustryRank { 208 | int? pos; 209 | int? total; 210 | 211 | IndustryRank({this.pos, this.total}); 212 | 213 | IndustryRank.fromJson(Map json) { 214 | pos = json['pos']?.toInt(); 215 | total = json['total']?.toInt(); 216 | } 217 | 218 | @override 219 | String toString() { 220 | return '$pos / $total'; 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /lib/model/v0/stock/financials/balance.dart: -------------------------------------------------------------------------------- 1 | /// The [BalanceData] data represent the balance sheet of the company. 2 | /// The balance sheet is a financial statement that reports a company's assets, 3 | /// liabilities, and shareholders' equity at a specific point in time. 4 | class BalanceData { 5 | String? date; 6 | String? symbol; 7 | String? reportedCurrency; 8 | String? cik; 9 | String? fillingDate; 10 | String? acceptedDate; 11 | int? year; 12 | String? period; 13 | double? cashAndCashEquivalents; 14 | double? shortTermInvestments; 15 | double? inventory; 16 | double? otherCurrentAssets; 17 | double? goodwill; 18 | double? intangibleAssets; 19 | double? goodwillAndIntangibleAssets; 20 | double? longTermInvestments; 21 | double? taxAssets; 22 | double? otherNonCurrentAssets; 23 | double? totalNonCurrentAssets; 24 | double? otherAssets; 25 | double? totalAssets; 26 | double? shortTermDebt; 27 | double? taxPayables; 28 | double? deferredRevenue; 29 | double? otherCurrentLiabilities; 30 | double? longTermDebt; 31 | double? deferredRevenueNonCurrent; 32 | double? deferredTaxLiabilitiesNonCurrent; 33 | double? otherNonCurrentLiabilities; 34 | double? totalNonCurrentLiabilities; 35 | double? otherLiabilities; 36 | double? capitalLeaseObligations; 37 | double? totalLiabilities; 38 | double? preferredStock; 39 | double? commonStock; 40 | double? retainedEarnings; 41 | double? othertotalStockholdersEquity; 42 | double? totalStockholdersEquity; 43 | double? minorityInterest; 44 | double? totalEquity; 45 | double? totalLiabilitiesAndTotalEquity; 46 | double? totalInvestments; 47 | double? totalDebt; 48 | double? netDebt; 49 | String? link; 50 | String? finalLink; 51 | double? accountsPayable; 52 | double? cashShortTermInvestments; 53 | double? currentAssets; 54 | double? currentLiabilities; 55 | double? liabilitiesShareholdersEquity; 56 | double? otherEquity; 57 | double? propertyPlantEquipment; 58 | double? totalReceivables; 59 | 60 | bool isQuarterly() { 61 | return period!.contains('Q'); 62 | } 63 | 64 | BalanceData( 65 | {this.date, 66 | this.symbol, 67 | this.reportedCurrency, 68 | this.cik, 69 | this.fillingDate, 70 | this.acceptedDate, 71 | this.year, 72 | this.period, 73 | this.cashAndCashEquivalents, 74 | this.shortTermInvestments, 75 | this.inventory, 76 | this.otherCurrentAssets, 77 | this.goodwill, 78 | this.intangibleAssets, 79 | this.goodwillAndIntangibleAssets, 80 | this.longTermInvestments, 81 | this.taxAssets, 82 | this.otherNonCurrentAssets, 83 | this.totalNonCurrentAssets, 84 | this.otherAssets, 85 | this.totalAssets, 86 | this.shortTermDebt, 87 | this.taxPayables, 88 | this.deferredRevenue, 89 | this.otherCurrentLiabilities, 90 | this.longTermDebt, 91 | this.deferredRevenueNonCurrent, 92 | this.deferredTaxLiabilitiesNonCurrent, 93 | this.otherNonCurrentLiabilities, 94 | this.totalNonCurrentLiabilities, 95 | this.otherLiabilities, 96 | this.capitalLeaseObligations, 97 | this.totalLiabilities, 98 | this.preferredStock, 99 | this.commonStock, 100 | this.retainedEarnings, 101 | this.othertotalStockholdersEquity, 102 | this.totalStockholdersEquity, 103 | this.minorityInterest, 104 | this.totalEquity, 105 | this.totalLiabilitiesAndTotalEquity, 106 | this.totalInvestments, 107 | this.totalDebt, 108 | this.netDebt, 109 | this.link, 110 | this.finalLink, 111 | this.accountsPayable, 112 | this.cashShortTermInvestments, 113 | this.currentAssets, 114 | this.currentLiabilities, 115 | this.liabilitiesShareholdersEquity, 116 | this.otherEquity, 117 | this.propertyPlantEquipment, 118 | this.totalReceivables}); 119 | 120 | BalanceData.fromJson(Map json) { 121 | date = json['date']; 122 | symbol = json['symbol']; 123 | reportedCurrency = json['reportedCurrency']; 124 | cik = json['cik']; 125 | fillingDate = json['fillingDate']; 126 | acceptedDate = json['acceptedDate']; 127 | year = DateTime.parse(json['date']!).year; 128 | period = json['period']; 129 | cashAndCashEquivalents = json['cashAndCashEquivalents']?.toDouble(); 130 | shortTermInvestments = json['shortTermInvestments']?.toDouble(); 131 | inventory = json['inventory']?.toDouble(); 132 | otherCurrentAssets = json['otherCurrentAssets']?.toDouble(); 133 | goodwill = json['goodwill']?.toDouble(); 134 | intangibleAssets = json['intangibleAssets']?.toDouble(); 135 | goodwillAndIntangibleAssets = 136 | json['goodwillAndIntangibleAssets']?.toDouble(); 137 | longTermInvestments = json['longTermInvestments']?.toDouble(); 138 | taxAssets = json['taxAssets']?.toDouble(); 139 | otherNonCurrentAssets = json['otherNonCurrentAssets']?.toDouble(); 140 | totalNonCurrentAssets = json['totalNonCurrentAssets']?.toDouble(); 141 | otherAssets = json['otherAssets']?.toDouble(); 142 | totalAssets = json['totalAssets']?.toDouble(); 143 | shortTermDebt = json['shortTermDebt']?.toDouble(); 144 | taxPayables = json['taxPayables']?.toDouble(); 145 | deferredRevenue = json['deferredRevenue']?.toDouble(); 146 | otherCurrentLiabilities = json['otherCurrentLiabilities']?.toDouble(); 147 | longTermDebt = json['longTermDebt']?.toDouble(); 148 | deferredRevenueNonCurrent = json['deferredRevenueNonCurrent']?.toDouble(); 149 | deferredTaxLiabilitiesNonCurrent = 150 | json['deferredTaxLiabilitiesNonCurrent']?.toDouble(); 151 | otherNonCurrentLiabilities = json['otherNonCurrentLiabilities']?.toDouble(); 152 | totalNonCurrentLiabilities = json['totalNonCurrentLiabilities']?.toDouble(); 153 | otherLiabilities = json['otherLiabilities']?.toDouble(); 154 | capitalLeaseObligations = json['capitalLeaseObligations']?.toDouble(); 155 | totalLiabilities = json['totalLiabilities']?.toDouble(); 156 | preferredStock = json['preferredStock']?.toDouble(); 157 | commonStock = json['commonStock']?.toDouble(); 158 | retainedEarnings = json['retainedEarnings']?.toDouble(); 159 | othertotalStockholdersEquity = 160 | json['othertotalStockholdersEquity']?.toDouble(); 161 | totalStockholdersEquity = json['totalStockholdersEquity']?.toDouble(); 162 | minorityInterest = json['minorityInterest']?.toDouble(); 163 | totalEquity = json['totalEquity']?.toDouble(); 164 | totalLiabilitiesAndTotalEquity = 165 | json['totalLiabilitiesAndTotalEquity']?.toDouble(); 166 | totalInvestments = json['totalInvestments']?.toDouble(); 167 | totalDebt = json['totalDebt']?.toDouble(); 168 | netDebt = json['netDebt']?.toDouble(); 169 | link = json['link']; 170 | finalLink = json['finalLink']; 171 | accountsPayable = json['accountsPayable']?.toDouble(); 172 | cashShortTermInvestments = json['cashShortTermInvestments']?.toDouble(); 173 | currentAssets = json['currentAssets']?.toDouble(); 174 | currentLiabilities = json['currentLiabilities']?.toDouble(); 175 | liabilitiesShareholdersEquity = 176 | json['liabilitiesShareholdersEquity']?.toDouble(); 177 | otherEquity = json['otherEquity']?.toDouble(); 178 | propertyPlantEquipment = json['propertyPlantEquipment']?.toDouble(); 179 | totalReceivables = json['totalReceivables']?.toDouble(); 180 | } 181 | } 182 | 183 | class Balance { 184 | List? balanceData; 185 | String? symbol; 186 | 187 | Balance({this.balanceData, this.symbol}); 188 | 189 | Balance.fromJson(Map json) { 190 | if (json['financials'] != null) { 191 | balanceData = []; 192 | json['financials'].forEach((v) { 193 | balanceData!.add(BalanceData.fromJson(v)); 194 | }); 195 | } 196 | symbol = json['symbol']; 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /lib/model/v0/stock/financials/cashflow.dart: -------------------------------------------------------------------------------- 1 | /// The [CashFlowData] data represent the cash flow data of the company. 2 | class CashFlowData { 3 | String? date; 4 | String? symbol; 5 | String? reportedCurrency; 6 | String? cik; 7 | String? fillingDate; 8 | String? acceptedDate; 9 | int? year; 10 | String? period; 11 | double? stockBasedCompensation; 12 | double? accountsReceivables; 13 | double? inventory; 14 | double? accountsPayables; 15 | double? otherWorkingCapital; 16 | double? otherNonCashItems; 17 | double? netCashProvidedByOperatingActivities; 18 | double? investmentsInPropertyPlantAndEquipment; 19 | double? acquisitionsNet; 20 | double? purchasesOfInvestments; 21 | double? salesMaturitiesOfInvestments; 22 | double? otherInvestingActivites; 23 | double? debtRepayment; 24 | double? commonStockIssued; 25 | double? otherFinancingActivites; 26 | double? effectOfForexChangesOnCash; 27 | double? cashAtEndOfPeriod; 28 | double? cashAtBeginningOfPeriod; 29 | String? link; 30 | String? finalLink; 31 | double? capex; 32 | double? cashDividendsPaid; 33 | double? changeinCash; 34 | double? changesinWorkingCapital; 35 | double? deferredTaxesInvestmentTaxCredit; 36 | double? depreciationAmortization; 37 | double? fcf; 38 | double? issuanceReductionCapitalStock; 39 | double? netCashFinancingActivities; 40 | double? netIncomeStartingLine; 41 | double? netInvestingCashFlow; 42 | double? netOperatingCashFlow; 43 | 44 | CashFlowData( 45 | {this.date, 46 | this.symbol, 47 | this.reportedCurrency, 48 | this.cik, 49 | this.fillingDate, 50 | this.acceptedDate, 51 | this.year, 52 | this.period, 53 | this.stockBasedCompensation, 54 | this.accountsReceivables, 55 | this.inventory, 56 | this.accountsPayables, 57 | this.otherWorkingCapital, 58 | this.otherNonCashItems, 59 | this.netCashProvidedByOperatingActivities, 60 | this.investmentsInPropertyPlantAndEquipment, 61 | this.acquisitionsNet, 62 | this.purchasesOfInvestments, 63 | this.salesMaturitiesOfInvestments, 64 | this.otherInvestingActivites, 65 | this.debtRepayment, 66 | this.commonStockIssued, 67 | this.otherFinancingActivites, 68 | this.effectOfForexChangesOnCash, 69 | this.cashAtEndOfPeriod, 70 | this.cashAtBeginningOfPeriod, 71 | this.link, 72 | this.finalLink, 73 | this.capex, 74 | this.cashDividendsPaid, 75 | this.changeinCash, 76 | this.changesinWorkingCapital, 77 | this.deferredTaxesInvestmentTaxCredit, 78 | this.depreciationAmortization, 79 | this.fcf, 80 | this.issuanceReductionCapitalStock, 81 | this.netCashFinancingActivities, 82 | this.netIncomeStartingLine, 83 | this.netInvestingCashFlow, 84 | this.netOperatingCashFlow}); 85 | 86 | CashFlowData.fromJson(Map json) { 87 | date = json['date']; 88 | symbol = json['symbol']; 89 | reportedCurrency = json['reportedCurrency']; 90 | cik = json['cik']; 91 | fillingDate = json['fillingDate']; 92 | acceptedDate = json['acceptedDate']; 93 | year = int.parse(json['calendarYear']); 94 | period = json['period']; 95 | stockBasedCompensation = json['stockBasedCompensation']?.toDouble(); 96 | accountsReceivables = json['accountsReceivables']?.toDouble(); 97 | inventory = json['inventory']?.toDouble(); 98 | accountsPayables = json['accountsPayables']?.toDouble(); 99 | otherWorkingCapital = json['otherWorkingCapital']?.toDouble(); 100 | otherNonCashItems = json['otherNonCashItems']?.toDouble(); 101 | netCashProvidedByOperatingActivities = 102 | json['netCashProvidedByOperatingActivities']?.toDouble(); 103 | investmentsInPropertyPlantAndEquipment = 104 | json['investmentsInPropertyPlantAndEquipment']?.toDouble(); 105 | acquisitionsNet = json['acquisitionsNet']?.toDouble(); 106 | purchasesOfInvestments = json['purchasesOfInvestments']?.toDouble(); 107 | salesMaturitiesOfInvestments = 108 | json['salesMaturitiesOfInvestments']?.toDouble(); 109 | otherInvestingActivites = json['otherInvestingActivites']?.toDouble(); 110 | debtRepayment = json['debtRepayment']?.toDouble(); 111 | commonStockIssued = json['commonStockIssued']?.toDouble(); 112 | otherFinancingActivites = json['otherFinancingActivites']?.toDouble(); 113 | effectOfForexChangesOnCash = json['effectOfForexChangesOnCash']?.toDouble(); 114 | cashAtEndOfPeriod = json['cashAtEndOfPeriod']?.toDouble(); 115 | cashAtBeginningOfPeriod = json['cashAtBeginningOfPeriod']?.toDouble(); 116 | link = json['link']; 117 | finalLink = json['finalLink']; 118 | capex = json['capex']?.toDouble(); 119 | cashDividendsPaid = json['cashDividendsPaid']?.toDouble(); 120 | changeinCash = json['changeinCash']?.toDouble(); 121 | changesinWorkingCapital = json['changesinWorkingCapital']?.toDouble(); 122 | deferredTaxesInvestmentTaxCredit = 123 | json['deferredTaxesInvestmentTaxCredit']?.toDouble(); 124 | depreciationAmortization = json['depreciationAmortization']?.toDouble(); 125 | fcf = json['freeCashFlow']?.toDouble(); 126 | issuanceReductionCapitalStock = 127 | json['issuanceReductionCapitalStock']?.toDouble(); 128 | netCashFinancingActivities = json['netCashFinancingActivities']?.toDouble(); 129 | netIncomeStartingLine = json['netIncomeStartingLine']?.toDouble(); 130 | netInvestingCashFlow = json['netInvestingCashFlow']?.toDouble(); 131 | netOperatingCashFlow = json['netOperatingCashFlow']?.toDouble(); 132 | } 133 | } 134 | 135 | class Cashflow { 136 | Cashflow({ 137 | required this.cashFlowData, 138 | required this.symbol, 139 | }); 140 | 141 | List? cashFlowData; 142 | 143 | String symbol; 144 | 145 | static Cashflow fromJson(Map json) => Cashflow( 146 | cashFlowData: (json['financials'] as List?) 147 | ?.map( 148 | (e) => CashFlowData.fromJson(e as Map), 149 | ) 150 | .toList(), 151 | symbol: (json['symbol'] ?? "") as String, 152 | ); 153 | } 154 | -------------------------------------------------------------------------------- /lib/model/v0/stock/financials/financials.dart: -------------------------------------------------------------------------------- 1 | import 'package:bavest/model/v0/stock/financials/balance.dart'; 2 | import 'package:bavest/model/v0/stock/financials/cashflow.dart'; 3 | import 'package:bavest/model/v0/stock/financials/income.dart'; 4 | 5 | /// The [Financials] class is used to store all financials of a stock 6 | /// e.g. [Balance], [Cashflow], [Income]. 7 | class Financials { 8 | /// The [Balance] class is used to store all balance data of a stock. 9 | Balance? balance; 10 | 11 | /// The [Cashflow] class is used to store all cashflow data of a stock. 12 | Cashflow? cashflow; 13 | 14 | /// The [Income] class is used to store all income data of a stock. 15 | Income? income; 16 | 17 | /// The [Financials] constructor. 18 | /// 19 | /// The parameter [balance] is the [Balance] class. 20 | /// The parameter [cashflow] is the [Cashflow] class. 21 | /// The parameter [income] is the [Income] class. 22 | Financials({this.balance, this.cashflow, this.income}); 23 | } 24 | -------------------------------------------------------------------------------- /lib/model/v0/stock/financials/financials_mode.dart: -------------------------------------------------------------------------------- 1 | /// The [Freq] data represent the frequency of the [Balance], [Cashflow], 2 | /// [Income] data e.g. annual, quarterly. 3 | enum Freq { 4 | annual, 5 | quarterly, 6 | } 7 | -------------------------------------------------------------------------------- /lib/model/v0/stock/financials/income.dart: -------------------------------------------------------------------------------- 1 | /// The [IncomeData] data represent the income data of the company. 2 | class IncomeData { 3 | String? date; 4 | String? symbol; 5 | String? reportedCurrency; 6 | String? cik; 7 | String? fillingDate; 8 | String? acceptedDate; 9 | int? year; 10 | String? period; 11 | double? revenue; 12 | double? grossProfitRatio; 13 | double? generalAndAdministrativeExpenses; 14 | double? sellingAndMarketingExpenses; 15 | double? otherExpenses; 16 | double? costAndExpenses; 17 | double? interestIncome; 18 | double? interestExpense; 19 | double? depreciationAndAmortization; 20 | double? ebitda; 21 | double? ebitdaratio; 22 | double? operatingIncomeRatio; 23 | double? totalOtherIncomeExpensesNet; 24 | double? incomeBeforeTaxRatio; 25 | double? netIncome; 26 | double? netIncomeRatio; 27 | double? eps; 28 | double? weightedAverageShsOut; 29 | String? link; 30 | String? finalLink; 31 | double? costOfGoodsSold; 32 | double? dilutedAverageSharesOutstanding; 33 | double? dilutedEPS; 34 | double? ebit; 35 | double? grossIncome; 36 | double? pretaxIncome; 37 | double? provisionforIncomeTaxes; 38 | double? researchDevelopment; 39 | double? sgaExpense; 40 | double? totalOperatingExpense; 41 | 42 | IncomeData( 43 | {this.date, 44 | this.symbol, 45 | this.reportedCurrency, 46 | this.cik, 47 | this.fillingDate, 48 | this.acceptedDate, 49 | this.year, 50 | this.period, 51 | this.revenue, 52 | this.grossProfitRatio, 53 | this.generalAndAdministrativeExpenses, 54 | this.sellingAndMarketingExpenses, 55 | this.otherExpenses, 56 | this.costAndExpenses, 57 | this.interestIncome, 58 | this.interestExpense, 59 | this.depreciationAndAmortization, 60 | this.ebitda, 61 | this.ebitdaratio, 62 | this.operatingIncomeRatio, 63 | this.totalOtherIncomeExpensesNet, 64 | this.incomeBeforeTaxRatio, 65 | this.netIncome, 66 | this.netIncomeRatio, 67 | this.eps, 68 | this.weightedAverageShsOut, 69 | this.link, 70 | this.finalLink, 71 | this.costOfGoodsSold, 72 | this.dilutedAverageSharesOutstanding, 73 | this.dilutedEPS, 74 | this.ebit, 75 | this.grossIncome, 76 | this.pretaxIncome, 77 | this.provisionforIncomeTaxes, 78 | this.researchDevelopment, 79 | this.sgaExpense, 80 | this.totalOperatingExpense}); 81 | 82 | IncomeData.fromJson(Map json) { 83 | date = json['date']; 84 | symbol = json['symbol']; 85 | reportedCurrency = json['reportedCurrency']; 86 | cik = json['cik']; 87 | fillingDate = json['fillingDate']; 88 | acceptedDate = json['acceptedDate']; 89 | year = DateTime.parse(json['date']!).year; 90 | period = json['period']; 91 | revenue = json['revenue']?.toDouble(); 92 | grossProfitRatio = json['grossProfitRatio']?.toDouble(); 93 | generalAndAdministrativeExpenses = 94 | json['generalAndAdministrativeExpenses']?.toDouble(); 95 | sellingAndMarketingExpenses = 96 | json['sellingAndMarketingExpenses']?.toDouble(); 97 | otherExpenses = json['otherExpenses']?.toDouble(); 98 | costAndExpenses = json['costAndExpenses']?.toDouble(); 99 | interestIncome = json['interestIncome']?.toDouble(); 100 | interestExpense = json['interestExpense']?.toDouble(); 101 | depreciationAndAmortization = 102 | json['depreciationAndAmortization']?.toDouble(); 103 | ebitda = json['ebitda']?.toDouble(); 104 | ebitdaratio = json['ebitdaratio']?.toDouble(); 105 | operatingIncomeRatio = json['operatingIncomeRatio']?.toDouble(); 106 | totalOtherIncomeExpensesNet = 107 | json['totalOtherIncomeExpensesNet']?.toDouble(); 108 | incomeBeforeTaxRatio = json['incomeBeforeTaxRatio']?.toDouble(); 109 | netIncome = json['netIncome']?.toDouble(); 110 | netIncomeRatio = json['netIncomeRatio']?.toDouble(); 111 | eps = json['eps']?.toDouble(); 112 | weightedAverageShsOut = json['weightedAverageShsOut']?.toDouble(); 113 | link = json['link']; 114 | finalLink = json['finalLink']; 115 | costOfGoodsSold = json['costOfGoodsSold']?.toDouble(); 116 | dilutedAverageSharesOutstanding = 117 | json['dilutedAverageSharesOutstanding']?.toDouble(); 118 | dilutedEPS = json['dilutedEPS']?.toDouble(); 119 | ebit = json['ebit']?.toDouble(); 120 | grossIncome = json['grossIncome']?.toDouble(); 121 | pretaxIncome = json['pretaxIncome']?.toDouble(); 122 | provisionforIncomeTaxes = json['provisionforIncomeTaxes']?.toDouble(); 123 | researchDevelopment = json['researchDevelopment']?.toDouble(); 124 | sgaExpense = json['sgaExpense']?.toDouble(); 125 | totalOperatingExpense = json['totalOperatingExpense']?.toDouble(); 126 | } 127 | } 128 | 129 | class Income { 130 | Income({ 131 | required this.incomeData, 132 | required this.symbol, 133 | }); 134 | 135 | List? incomeData; 136 | 137 | String? symbol; 138 | 139 | Income.fromJson(Map json) { 140 | if (json['financials'] != null) { 141 | incomeData = []; 142 | json['financials'].forEach((v) { 143 | incomeData!.add(IncomeData.fromJson(v)); 144 | }); 145 | } 146 | symbol = json['symbol']; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /lib/model/v0/stock/fundamentals/fundamentals.dart: -------------------------------------------------------------------------------- 1 | /// The [Fundamentals] data represent the fundamentals of the company. 2 | class Fundamentals { 3 | /// The [metrics] data represent the metrics of the company. 4 | List? metrics; 5 | 6 | Fundamentals({this.metrics}); 7 | 8 | Fundamentals.fromJson(Map json) { 9 | if (json['metrics'] != null) { 10 | metrics = []; 11 | json['metrics'].forEach((v) { 12 | metrics!.add(FundamentalMetrics.fromJson(v)); 13 | }); 14 | } 15 | } 16 | } 17 | 18 | class FundamentalMetrics { 19 | /// The [Multiples] data represent the multiples of the company. 20 | Multiples? multiples; 21 | 22 | /// The [Stability] data represent the stability of the company. 23 | Stability? stability; 24 | 25 | /// The [Revenue] data represent the revenue of the company. 26 | Revenue? revenue; 27 | 28 | /// The [period] data represent the period of the company. 29 | DateTime? period; 30 | 31 | FundamentalMetrics( 32 | {this.multiples, this.stability, this.revenue, this.period}); 33 | 34 | FundamentalMetrics.fromJson(Map json) { 35 | multiples = json['multiples'] != null 36 | ? Multiples.fromJson(json['multiples']) 37 | : null; 38 | stability = json['stability'] != null 39 | ? Stability.fromJson(json['stability']) 40 | : null; 41 | revenue = 42 | json['revenue'] != null ? Revenue.fromJson(json['revenue']) : null; 43 | period = json['period'] != null ? DateTime.parse(json['period']) : null; 44 | } 45 | } 46 | 47 | class Multiples { 48 | double? ev; 49 | double? evRevenue; 50 | double? evEbit; 51 | double? evFcf; 52 | double? evEbitda; 53 | double? priceEarningsRatio; 54 | double? priceBookRatio; 55 | double? priceCashflowRatio; 56 | double? priceSalesRatio; 57 | 58 | Multiples( 59 | {this.ev, 60 | this.evRevenue, 61 | this.evEbit, 62 | this.evFcf, 63 | this.evEbitda, 64 | this.priceEarningsRatio, 65 | this.priceBookRatio, 66 | this.priceCashflowRatio, 67 | this.priceSalesRatio}); 68 | 69 | Multiples.fromJson(Map json) { 70 | ev = json['ev']?.toDouble(); 71 | evRevenue = json['ev/revenue']?.toDouble(); 72 | evEbit = json['ev/ebit']?.toDouble(); 73 | evFcf = json['ev/fcf']?.toDouble(); 74 | evEbitda = json['ev/ebitda']?.toDouble(); 75 | priceEarningsRatio = json['priceEarningsRatio']?.toDouble(); 76 | priceBookRatio = json['priceBookRatio']?.toDouble(); 77 | priceCashflowRatio = json['priceCashflowRatio']?.toDouble(); 78 | priceSalesRatio = json['priceSalesRatio']?.toDouble(); 79 | } 80 | } 81 | 82 | class Stability { 83 | double? equityRatio; 84 | double? debtRatio; 85 | double? debtToEquityRatio; 86 | double? dynamicLeverage; 87 | double? cataRatio; 88 | double? currentRatio; 89 | double? fixedAssetIntensity; 90 | double? ppeRatio; 91 | double? assetCoverage1; 92 | double? assetCoverage2; 93 | double? cashRatio; 94 | double? quickRatio; 95 | 96 | Stability( 97 | {this.equityRatio, 98 | this.debtRatio, 99 | this.debtToEquityRatio, 100 | this.dynamicLeverage, 101 | this.cataRatio, 102 | this.currentRatio, 103 | this.fixedAssetIntensity, 104 | this.ppeRatio, 105 | this.assetCoverage1, 106 | this.assetCoverage2, 107 | this.cashRatio, 108 | this.quickRatio}); 109 | 110 | Stability.fromJson(Map json) { 111 | equityRatio = json['equityRatio']?.toDouble(); 112 | debtRatio = json['debtRatio']?.toDouble(); 113 | debtToEquityRatio = json['debtToEquityRatio']?.toDouble(); 114 | dynamicLeverage = json['dynamicLeverage']?.toDouble(); 115 | cataRatio = json['cataRatio']?.toDouble(); 116 | currentRatio = json['currentRatio']?.toDouble(); 117 | fixedAssetIntensity = json['fixedAssetIntensity']?.toDouble(); 118 | ppeRatio = json['ppeRatio']?.toDouble(); 119 | assetCoverage1 = json['assetCoverage1']?.toDouble(); 120 | assetCoverage2 = json['assetCoverage2']?.toDouble(); 121 | cashRatio = json['cashRatio']?.toDouble(); 122 | quickRatio = json['quickRatio']?.toDouble(); 123 | } 124 | } 125 | 126 | class Revenue { 127 | double? equityReturn; 128 | double? salesReturn; 129 | double? ebitMargin; 130 | double? ebitdaMargin; 131 | double? capitalTurnover; 132 | double? assetsReturn; 133 | 134 | Revenue( 135 | {this.equityReturn, 136 | this.salesReturn, 137 | this.ebitMargin, 138 | this.ebitdaMargin, 139 | this.capitalTurnover, 140 | this.assetsReturn}); 141 | 142 | Revenue.fromJson(Map json) { 143 | equityReturn = json['equityReturn']?.toDouble(); 144 | salesReturn = json['salesReturn']?.toDouble(); 145 | ebitMargin = json['ebitMargin']?.toDouble(); 146 | ebitdaMargin = json['ebitdaMargin']?.toDouble(); 147 | capitalTurnover = json['capitalTurnover']?.toDouble(); 148 | assetsReturn = json['assetsReturn']?.toDouble(); 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /lib/model/v0/stock/ipo/ipo.dart: -------------------------------------------------------------------------------- 1 | /// The [IpoCalendar] data represent the IPO calendar of the company. 2 | class IpoCalendar { 3 | IpoCalendar( 4 | {required this.symbol, 5 | required this.price, 6 | required this.numberOfShares, 7 | required this.totalSharesValue, 8 | required this.name, 9 | required this.exchange, 10 | required this.actions, 11 | required this.date}); 12 | 13 | /// The symbol of the company. 14 | String? symbol; 15 | 16 | /// The price of the company. 17 | String? price; 18 | 19 | /// The number of shares of the company. 20 | int? numberOfShares; 21 | 22 | /// The total shares value of the company. 23 | double? totalSharesValue; 24 | 25 | /// The name of the company. 26 | String? name; 27 | 28 | /// The exchange of the company. 29 | String? exchange; 30 | 31 | /// The actions of the company. 32 | String? actions; 33 | 34 | /// The date of the company. 35 | DateTime? date; 36 | 37 | factory IpoCalendar.fromJson(Map json) => IpoCalendar( 38 | symbol: json["symbol"], 39 | price: json["price"], 40 | numberOfShares: json["numberOfShares"], 41 | totalSharesValue: json["totalSharesValue"]?.toDouble(), 42 | name: json["name"], 43 | exchange: json["exchange"], 44 | actions: json["actions"], 45 | date: json["date"] == null ? null : DateTime.parse(json["date"]), 46 | ); 47 | } 48 | 49 | class Ipo { 50 | final List? ipoCalendar; 51 | 52 | Ipo({this.ipoCalendar}); 53 | 54 | static Ipo fromJson(Map json) => Ipo( 55 | ipoCalendar: (json['ipoCalendar'] as List?) 56 | ?.map( 57 | (e) => IpoCalendar.fromJson(e as Map), 58 | ) 59 | .toList(), 60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /lib/model/v0/stock/metric/metric.dart: -------------------------------------------------------------------------------- 1 | /// The [Metric] data represent the metrics of the company. 2 | class Metric { 3 | /// The [symbol] data represent the symbol of the company. 4 | String? symbol; 5 | 6 | /// The [date] data represent the date of the metric. 7 | String? date; 8 | 9 | String? period; 10 | double? revenueGrowth; 11 | double? grossProfitGrowth; 12 | double? ebitgrowth; 13 | double? operatingIncomeGrowth; 14 | double? netIncomeGrowth; 15 | double? epsgrowth; 16 | double? epsdilutedGrowth; 17 | double? weightedAverageSharesGrowth; 18 | double? weightedAverageSharesDilutedGrowth; 19 | double? dividendsperShareGrowth; 20 | double? operatingCashFlowGrowth; 21 | double? freeCashFlowGrowth; 22 | double? tenYRevenueGrowthPerShare; 23 | double? fiveYRevenueGrowthPerShare; 24 | double? threeYRevenueGrowthPerShare; 25 | double? tenYOperatingCFGrowthPerShare; 26 | double? fiveYOperatingCFGrowthPerShare; 27 | double? threeYOperatingCFGrowthPerShare; 28 | double? tenYNetIncomeGrowthPerShare; 29 | double? fiveYNetIncomeGrowthPerShare; 30 | double? threeYNetIncomeGrowthPerShare; 31 | double? tenYShareholdersEquityGrowthPerShare; 32 | double? fiveYShareholdersEquityGrowthPerShare; 33 | double? threeYShareholdersEquityGrowthPerShare; 34 | double? tenYDividendperShareGrowthPerShare; 35 | double? fiveYDividendperShareGrowthPerShare; 36 | double? threeYDividendperShareGrowthPerShare; 37 | double? receivablesGrowth; 38 | double? inventoryGrowth; 39 | double? assetGrowth; 40 | double? bookValueperShareGrowth; 41 | double? debtGrowth; 42 | double? rdexpenseGrowth; 43 | double? sgaexpensesGrowth; 44 | double? revenuePerShare; 45 | double? netIncomePerShare; 46 | double? operatingCashFlowPerShare; 47 | double? freeCashFlowPerShare; 48 | double? cashPerShare; 49 | double? bookValuePerShare; 50 | double? tangibleBookValuePerShare; 51 | double? shareholdersEquityPerShare; 52 | double? interestDebtPerShare; 53 | double? marketCap; 54 | double? enterpriseValue; 55 | double? peRatio; 56 | double? priceToSalesRatio; 57 | double? pocfratio; 58 | double? pfcfRatio; 59 | double? pbRatio; 60 | double? ptbRatio; 61 | double? evToSales; 62 | double? enterpriseValueOverEBITDA; 63 | double? evToOperatingCashFlow; 64 | double? evToFreeCashFlow; 65 | double? earningsYield; 66 | double? freeCashFlowYield; 67 | double? debtToEquity; 68 | double? debtToAssets; 69 | double? netDebtToEBITDA; 70 | double? currentRatio; 71 | double? interestCoverage; 72 | double? incomeQuality; 73 | double? dividendYield; 74 | double? dividendYieldPercentage; 75 | double? payoutRatio; 76 | double? salesGeneralAndAdministrativeToRevenue; 77 | double? researchAndDevelopementToRevenue; 78 | double? intangiblesToTotalAssets; 79 | double? capexToOperatingCashFlow; 80 | double? capexToRevenue; 81 | double? capexToDepreciation; 82 | double? stockBasedCompensationToRevenue; 83 | double? grahamNumber; 84 | double? roic; 85 | double? returnOnTangibleAssets; 86 | double? grahamNetNet; 87 | double? workingCapital; 88 | double? tangibleAssetValue; 89 | double? netCurrentAssetValue; 90 | double? investedCapital; 91 | double? averageReceivables; 92 | double? averagePayables; 93 | double? averageInventory; 94 | double? daysSalesOutstanding; 95 | double? daysPayablesOutstanding; 96 | double? daysOfInventoryOnHand; 97 | double? receivablesTurnover; 98 | double? payablesTurnover; 99 | double? inventoryTurnover; 100 | double? roe; 101 | double? capexPerShare; 102 | double? dividendPerShare; 103 | double? debtToMarketCap; 104 | double? d1DayPriceReturnDaily; 105 | double? d5DayPriceReturnDaily; 106 | double? d4WeekPriceReturnDaily; 107 | double? d13WeekPriceReturnDaily; 108 | double? d26WeekPriceReturnDaily; 109 | double? yearToDatePriceReturnDaily; 110 | double? d1yearPriceReturnDaily; 111 | double? d3yearPriceReturnDaily; 112 | double? d5yearPriceReturnDaily; 113 | double? d10yearPriceReturnDaily; 114 | double? maxPriceReturnDaily; 115 | 116 | Metric( 117 | {symbol, 118 | date, 119 | period, 120 | revenueGrowth, 121 | grossProfitGrowth, 122 | ebitgrowth, 123 | operatingIncomeGrowth, 124 | netIncomeGrowth, 125 | epsgrowth, 126 | epsdilutedGrowth, 127 | weightedAverageSharesGrowth, 128 | weightedAverageSharesDilutedGrowth, 129 | dividendsperShareGrowth, 130 | operatingCashFlowGrowth, 131 | freeCashFlowGrowth, 132 | tenYRevenueGrowthPerShare, 133 | fiveYRevenueGrowthPerShare, 134 | threeYRevenueGrowthPerShare, 135 | tenYOperatingCFGrowthPerShare, 136 | fiveYOperatingCFGrowthPerShare, 137 | threeYOperatingCFGrowthPerShare, 138 | tenYNetIncomeGrowthPerShare, 139 | fiveYNetIncomeGrowthPerShare, 140 | threeYNetIncomeGrowthPerShare, 141 | tenYShareholdersEquityGrowthPerShare, 142 | fiveYShareholdersEquityGrowthPerShare, 143 | threeYShareholdersEquityGrowthPerShare, 144 | tenYDividendperShareGrowthPerShare, 145 | fiveYDividendperShareGrowthPerShare, 146 | threeYDividendperShareGrowthPerShare, 147 | receivablesGrowth, 148 | inventoryGrowth, 149 | assetGrowth, 150 | bookValueperShareGrowth, 151 | debtGrowth, 152 | rdexpenseGrowth, 153 | sgaexpensesGrowth, 154 | revenuePerShare, 155 | netIncomePerShare, 156 | operatingCashFlowPerShare, 157 | freeCashFlowPerShare, 158 | cashPerShare, 159 | bookValuePerShare, 160 | tangibleBookValuePerShare, 161 | shareholdersEquityPerShare, 162 | interestDebtPerShare, 163 | marketCap, 164 | enterpriseValue, 165 | peRatio, 166 | priceToSalesRatio, 167 | pocfratio, 168 | pfcfRatio, 169 | pbRatio, 170 | ptbRatio, 171 | evToSales, 172 | enterpriseValueOverEBITDA, 173 | evToOperatingCashFlow, 174 | evToFreeCashFlow, 175 | earningsYield, 176 | freeCashFlowYield, 177 | debtToEquity, 178 | debtToAssets, 179 | netDebtToEBITDA, 180 | currentRatio, 181 | interestCoverage, 182 | incomeQuality, 183 | dividendYield, 184 | dividendYieldPercentage, 185 | payoutRatio, 186 | salesGeneralAndAdministrativeToRevenue, 187 | researchAndDevelopementToRevenue, 188 | intangiblesToTotalAssets, 189 | capexToOperatingCashFlow, 190 | capexToRevenue, 191 | capexToDepreciation, 192 | stockBasedCompensationToRevenue, 193 | grahamNumber, 194 | roic, 195 | returnOnTangibleAssets, 196 | grahamNetNet, 197 | workingCapital, 198 | tangibleAssetValue, 199 | netCurrentAssetValue, 200 | investedCapital, 201 | averageReceivables, 202 | averagePayables, 203 | averageInventory, 204 | daysSalesOutstanding, 205 | daysPayablesOutstanding, 206 | daysOfInventoryOnHand, 207 | receivablesTurnover, 208 | payablesTurnover, 209 | inventoryTurnover, 210 | roe, 211 | capexPerShare, 212 | dividendPerShare, 213 | debtToMarketCap, 214 | d1DayPriceReturnDaily, 215 | d5DayPriceReturnDaily, 216 | d4WeekPriceReturnDaily, 217 | d13WeekPriceReturnDaily, 218 | d26WeekPriceReturnDaily, 219 | yearToDatePriceReturnDaily, 220 | d1yearPriceReturnDaily, 221 | d3yearPriceReturnDaily, 222 | d5yearPriceReturnDaily, 223 | d10yearPriceReturnDaily, 224 | maxPriceReturnDaily}); 225 | 226 | Metric.fromJson(Map json) { 227 | symbol = json['symbol']; 228 | date = json['date']; 229 | period = json['period']; 230 | revenueGrowth = json['revenueGrowth']?.toDouble(); 231 | grossProfitGrowth = json['grossProfitGrowth']?.toDouble(); 232 | ebitgrowth = json['ebitgrowth']?.toDouble(); 233 | operatingIncomeGrowth = json['operatingIncomeGrowth']?.toDouble(); 234 | netIncomeGrowth = json['netIncomeGrowth']?.toDouble(); 235 | epsgrowth = json['epsgrowth']?.toDouble(); 236 | epsdilutedGrowth = json['epsdilutedGrowth']?.toDouble(); 237 | weightedAverageSharesGrowth = 238 | json['weightedAverageSharesGrowth']?.toDouble(); 239 | weightedAverageSharesDilutedGrowth = 240 | json['weightedAverageSharesDilutedGrowth']?.toDouble(); 241 | dividendsperShareGrowth = json['dividendsperShareGrowth']?.toDouble(); 242 | operatingCashFlowGrowth = json['operatingCashFlowGrowth']?.toDouble(); 243 | freeCashFlowGrowth = json['freeCashFlowGrowth']?.toDouble(); 244 | tenYRevenueGrowthPerShare = json['tenYRevenueGrowthPerShare']?.toDouble(); 245 | fiveYRevenueGrowthPerShare = json['fiveYRevenueGrowthPerShare']?.toDouble(); 246 | threeYRevenueGrowthPerShare = 247 | json['threeYRevenueGrowthPerShare']?.toDouble(); 248 | tenYOperatingCFGrowthPerShare = 249 | json['tenYOperatingCFGrowthPerShare']?.toDouble(); 250 | fiveYOperatingCFGrowthPerShare = 251 | json['fiveYOperatingCFGrowthPerShare']?.toDouble(); 252 | threeYOperatingCFGrowthPerShare = 253 | json['threeYOperatingCFGrowthPerShare']?.toDouble(); 254 | tenYNetIncomeGrowthPerShare = 255 | json['tenYNetIncomeGrowthPerShare']?.toDouble(); 256 | fiveYNetIncomeGrowthPerShare = 257 | json['fiveYNetIncomeGrowthPerShare']?.toDouble(); 258 | threeYNetIncomeGrowthPerShare = 259 | json['threeYNetIncomeGrowthPerShare']?.toDouble(); 260 | tenYShareholdersEquityGrowthPerShare = 261 | json['tenYShareholdersEquityGrowthPerShare']?.toDouble(); 262 | fiveYShareholdersEquityGrowthPerShare = 263 | json['fiveYShareholdersEquityGrowthPerShare']?.toDouble(); 264 | threeYShareholdersEquityGrowthPerShare = 265 | json['threeYShareholdersEquityGrowthPerShare']?.toDouble(); 266 | tenYDividendperShareGrowthPerShare = 267 | json['tenYDividendperShareGrowthPerShare']?.toDouble(); 268 | fiveYDividendperShareGrowthPerShare = 269 | json['fiveYDividendperShareGrowthPerShare']?.toDouble(); 270 | threeYDividendperShareGrowthPerShare = 271 | json['threeYDividendperShareGrowthPerShare']?.toDouble(); 272 | receivablesGrowth = json['receivablesGrowth']?.toDouble(); 273 | inventoryGrowth = json['inventoryGrowth']?.toDouble(); 274 | assetGrowth = json['assetGrowth']?.toDouble(); 275 | bookValueperShareGrowth = json['bookValueperShareGrowth']?.toDouble(); 276 | debtGrowth = json['debtGrowth']?.toDouble(); 277 | rdexpenseGrowth = json['rdexpenseGrowth']?.toDouble(); 278 | sgaexpensesGrowth = json['sgaexpensesGrowth']?.toDouble(); 279 | revenuePerShare = json['revenuePerShare']?.toDouble(); 280 | netIncomePerShare = json['netIncomePerShare']?.toDouble(); 281 | operatingCashFlowPerShare = json['operatingCashFlowPerShare']?.toDouble(); 282 | freeCashFlowPerShare = json['freeCashFlowPerShare']?.toDouble(); 283 | cashPerShare = json['cashPerShare']?.toDouble(); 284 | bookValuePerShare = json['bookValuePerShare']?.toDouble(); 285 | tangibleBookValuePerShare = json['tangibleBookValuePerShare']?.toDouble(); 286 | shareholdersEquityPerShare = json['shareholdersEquityPerShare']?.toDouble(); 287 | interestDebtPerShare = json['interestDebtPerShare']?.toDouble(); 288 | marketCap = json['marketCap']?.toDouble(); 289 | enterpriseValue = json['enterpriseValue']?.toDouble(); 290 | peRatio = json['peRatio']?.toDouble(); 291 | priceToSalesRatio = json['priceToSalesRatio']?.toDouble(); 292 | pocfratio = json['pocfratio']?.toDouble(); 293 | pfcfRatio = json['pfcfRatio']?.toDouble(); 294 | pbRatio = json['pbRatio']?.toDouble(); 295 | ptbRatio = json['ptbRatio']?.toDouble(); 296 | evToSales = json['evToSales']?.toDouble(); 297 | enterpriseValueOverEBITDA = json['enterpriseValueOverEBITDA']?.toDouble(); 298 | evToOperatingCashFlow = json['evToOperatingCashFlow']?.toDouble(); 299 | evToFreeCashFlow = json['evToFreeCashFlow']?.toDouble(); 300 | earningsYield = json['earningsYield']?.toDouble(); 301 | freeCashFlowYield = json['freeCashFlowYield']?.toDouble(); 302 | debtToEquity = json['debtToEquity']?.toDouble(); 303 | debtToAssets = json['debtToAssets']?.toDouble(); 304 | netDebtToEBITDA = json['netDebtToEBITDA']?.toDouble(); 305 | currentRatio = json['currentRatio']?.toDouble(); 306 | interestCoverage = json['interestCoverage']?.toDouble(); 307 | incomeQuality = json['incomeQuality']?.toDouble(); 308 | dividendYield = json['dividendYield']?.toDouble(); 309 | dividendYieldPercentage = json['dividendYieldPercentage']?.toDouble(); 310 | payoutRatio = json['payoutRatio']?.toDouble(); 311 | salesGeneralAndAdministrativeToRevenue = 312 | json['salesGeneralAndAdministrativeToRevenue']?.toDouble(); 313 | researchAndDevelopementToRevenue = 314 | json['researchAndDevelopementToRevenue']?.toDouble(); 315 | intangiblesToTotalAssets = json['intangiblesToTotalAssets']?.toDouble(); 316 | capexToOperatingCashFlow = json['capexToOperatingCashFlow']?.toDouble(); 317 | capexToRevenue = json['capexToRevenue']?.toDouble(); 318 | capexToDepreciation = json['capexToDepreciation']?.toDouble(); 319 | stockBasedCompensationToRevenue = 320 | json['stockBasedCompensationToRevenue']?.toDouble(); 321 | grahamNumber = json['grahamNumber']?.toDouble(); 322 | roic = json['roic']?.toDouble(); 323 | returnOnTangibleAssets = json['returnOnTangibleAssets']?.toDouble(); 324 | grahamNetNet = json['grahamNetNet']?.toDouble(); 325 | workingCapital = json['workingCapital']?.toDouble(); 326 | tangibleAssetValue = json['tangibleAssetValue']?.toDouble(); 327 | netCurrentAssetValue = json['netCurrentAssetValue']?.toDouble(); 328 | investedCapital = json['investedCapital']?.toDouble(); 329 | averageReceivables = json['averageReceivables']?.toDouble(); 330 | averagePayables = json['averagePayables']?.toDouble(); 331 | averageInventory = json['averageInventory']?.toDouble(); 332 | daysSalesOutstanding = json['daysSalesOutstanding']?.toDouble(); 333 | daysPayablesOutstanding = json['daysPayablesOutstanding']?.toDouble(); 334 | daysOfInventoryOnHand = json['daysOfInventoryOnHand']?.toDouble(); 335 | receivablesTurnover = json['receivablesTurnover']?.toDouble(); 336 | payablesTurnover = json['payablesTurnover']?.toDouble(); 337 | inventoryTurnover = json['inventoryTurnover']?.toDouble(); 338 | roe = json['roe']?.toDouble(); 339 | capexPerShare = json['capexPerShare']?.toDouble(); 340 | dividendPerShare = json['dividendPerShare']?.toDouble(); 341 | debtToMarketCap = json['debtToMarketCap']?.toDouble(); 342 | d1DayPriceReturnDaily = json['1DayPriceReturnDaily']?.toDouble(); 343 | d5DayPriceReturnDaily = json['5DayPriceReturnDaily']?.toDouble(); 344 | d4WeekPriceReturnDaily = json['4WeekPriceReturnDaily']?.toDouble(); 345 | d13WeekPriceReturnDaily = json['13WeekPriceReturnDaily']?.toDouble(); 346 | d26WeekPriceReturnDaily = json['26WeekPriceReturnDaily']?.toDouble(); 347 | yearToDatePriceReturnDaily = json['yearToDatePriceReturnDaily']?.toDouble(); 348 | d1yearPriceReturnDaily = json['1yearPriceReturnDaily']?.toDouble(); 349 | d3yearPriceReturnDaily = json['3yearPriceReturnDaily']?.toDouble(); 350 | d5yearPriceReturnDaily = json['5yearPriceReturnDaily']?.toDouble(); 351 | d10yearPriceReturnDaily = json['10yearPriceReturnDaily']?.toDouble(); 352 | maxPriceReturnDaily = json['maxPriceReturnDaily']?.toDouble(); 353 | } 354 | 355 | Map toJson() { 356 | final Map data = {}; 357 | data['symbol'] = symbol; 358 | data['date'] = date; 359 | data['period'] = period; 360 | data['revenueGrowth'] = revenueGrowth; 361 | data['grossProfitGrowth'] = grossProfitGrowth; 362 | data['ebitgrowth'] = ebitgrowth; 363 | data['operatingIncomeGrowth'] = operatingIncomeGrowth; 364 | data['netIncomeGrowth'] = netIncomeGrowth; 365 | data['epsgrowth'] = epsgrowth; 366 | data['epsdilutedGrowth'] = epsdilutedGrowth; 367 | data['weightedAverageSharesGrowth'] = weightedAverageSharesGrowth; 368 | data['weightedAverageSharesDilutedGrowth'] = 369 | weightedAverageSharesDilutedGrowth; 370 | data['dividendsperShareGrowth'] = dividendsperShareGrowth; 371 | data['operatingCashFlowGrowth'] = operatingCashFlowGrowth; 372 | data['freeCashFlowGrowth'] = freeCashFlowGrowth; 373 | data['tenYRevenueGrowthPerShare'] = tenYRevenueGrowthPerShare; 374 | data['fiveYRevenueGrowthPerShare'] = fiveYRevenueGrowthPerShare; 375 | data['threeYRevenueGrowthPerShare'] = threeYRevenueGrowthPerShare; 376 | data['tenYOperatingCFGrowthPerShare'] = tenYOperatingCFGrowthPerShare; 377 | data['fiveYOperatingCFGrowthPerShare'] = fiveYOperatingCFGrowthPerShare; 378 | data['threeYOperatingCFGrowthPerShare'] = threeYOperatingCFGrowthPerShare; 379 | data['tenYNetIncomeGrowthPerShare'] = tenYNetIncomeGrowthPerShare; 380 | data['fiveYNetIncomeGrowthPerShare'] = fiveYNetIncomeGrowthPerShare; 381 | data['threeYNetIncomeGrowthPerShare'] = threeYNetIncomeGrowthPerShare; 382 | data['tenYShareholdersEquityGrowthPerShare'] = 383 | tenYShareholdersEquityGrowthPerShare; 384 | data['fiveYShareholdersEquityGrowthPerShare'] = 385 | fiveYShareholdersEquityGrowthPerShare; 386 | data['threeYShareholdersEquityGrowthPerShare'] = 387 | threeYShareholdersEquityGrowthPerShare; 388 | data['tenYDividendperShareGrowthPerShare'] = 389 | tenYDividendperShareGrowthPerShare; 390 | data['fiveYDividendperShareGrowthPerShare'] = 391 | fiveYDividendperShareGrowthPerShare; 392 | data['threeYDividendperShareGrowthPerShare'] = 393 | threeYDividendperShareGrowthPerShare; 394 | data['receivablesGrowth'] = receivablesGrowth; 395 | data['inventoryGrowth'] = inventoryGrowth; 396 | data['assetGrowth'] = assetGrowth; 397 | data['bookValueperShareGrowth'] = bookValueperShareGrowth; 398 | data['debtGrowth'] = debtGrowth; 399 | data['rdexpenseGrowth'] = rdexpenseGrowth; 400 | data['sgaexpensesGrowth'] = sgaexpensesGrowth; 401 | data['revenuePerShare'] = revenuePerShare; 402 | data['netIncomePerShare'] = netIncomePerShare; 403 | data['operatingCashFlowPerShare'] = operatingCashFlowPerShare; 404 | data['freeCashFlowPerShare'] = freeCashFlowPerShare; 405 | data['cashPerShare'] = cashPerShare; 406 | data['bookValuePerShare'] = bookValuePerShare; 407 | data['tangibleBookValuePerShare'] = tangibleBookValuePerShare; 408 | data['shareholdersEquityPerShare'] = shareholdersEquityPerShare; 409 | data['interestDebtPerShare'] = interestDebtPerShare; 410 | data['marketCap'] = marketCap; 411 | data['enterpriseValue'] = enterpriseValue; 412 | data['peRatio'] = peRatio; 413 | data['priceToSalesRatio'] = priceToSalesRatio; 414 | data['pocfratio'] = pocfratio; 415 | data['pfcfRatio'] = pfcfRatio; 416 | data['pbRatio'] = pbRatio; 417 | data['ptbRatio'] = ptbRatio; 418 | data['evToSales'] = evToSales; 419 | data['enterpriseValueOverEBITDA'] = enterpriseValueOverEBITDA; 420 | data['evToOperatingCashFlow'] = evToOperatingCashFlow; 421 | data['evToFreeCashFlow'] = evToFreeCashFlow; 422 | data['earningsYield'] = earningsYield; 423 | data['freeCashFlowYield'] = freeCashFlowYield; 424 | data['debtToEquity'] = debtToEquity; 425 | data['debtToAssets'] = debtToAssets; 426 | data['netDebtToEBITDA'] = netDebtToEBITDA; 427 | data['currentRatio'] = currentRatio; 428 | data['interestCoverage'] = interestCoverage; 429 | data['incomeQuality'] = incomeQuality; 430 | data['dividendYield'] = dividendYield; 431 | data['dividendYieldPercentage'] = dividendYieldPercentage; 432 | data['payoutRatio'] = payoutRatio; 433 | data['salesGeneralAndAdministrativeToRevenue'] = 434 | salesGeneralAndAdministrativeToRevenue; 435 | data['researchAndDevelopementToRevenue'] = researchAndDevelopementToRevenue; 436 | data['intangiblesToTotalAssets'] = intangiblesToTotalAssets; 437 | data['capexToOperatingCashFlow'] = capexToOperatingCashFlow; 438 | data['capexToRevenue'] = capexToRevenue; 439 | data['capexToDepreciation'] = capexToDepreciation; 440 | data['stockBasedCompensationToRevenue'] = stockBasedCompensationToRevenue; 441 | data['grahamNumber'] = grahamNumber; 442 | data['roic'] = roic; 443 | data['returnOnTangibleAssets'] = returnOnTangibleAssets; 444 | data['grahamNetNet'] = grahamNetNet; 445 | data['workingCapital'] = workingCapital; 446 | data['tangibleAssetValue'] = tangibleAssetValue; 447 | data['netCurrentAssetValue'] = netCurrentAssetValue; 448 | data['investedCapital'] = investedCapital; 449 | data['averageReceivables'] = averageReceivables; 450 | data['averagePayables'] = averagePayables; 451 | data['averageInventory'] = averageInventory; 452 | data['daysSalesOutstanding'] = daysSalesOutstanding; 453 | data['daysPayablesOutstanding'] = daysPayablesOutstanding; 454 | data['daysOfInventoryOnHand'] = daysOfInventoryOnHand; 455 | data['receivablesTurnover'] = receivablesTurnover; 456 | data['payablesTurnover'] = payablesTurnover; 457 | data['inventoryTurnover'] = inventoryTurnover; 458 | data['roe'] = roe; 459 | data['capexPerShare'] = capexPerShare; 460 | data['dividendPerShare'] = dividendPerShare; 461 | data['debtToMarketCap'] = debtToMarketCap; 462 | data['1DayPriceReturnDaily'] = d1DayPriceReturnDaily; 463 | data['5DayPriceReturnDaily'] = d5DayPriceReturnDaily; 464 | data['4WeekPriceReturnDaily'] = d4WeekPriceReturnDaily; 465 | data['13WeekPriceReturnDaily'] = d13WeekPriceReturnDaily; 466 | data['26WeekPriceReturnDaily'] = d26WeekPriceReturnDaily; 467 | data['yearToDatePriceReturnDaily'] = yearToDatePriceReturnDaily; 468 | data['1yearPriceReturnDaily'] = d1yearPriceReturnDaily; 469 | data['3yearPriceReturnDaily'] = d3yearPriceReturnDaily; 470 | data['5yearPriceReturnDaily'] = d5yearPriceReturnDaily; 471 | data['10yearPriceReturnDaily'] = d10yearPriceReturnDaily; 472 | data['maxPriceReturnDaily'] = maxPriceReturnDaily; 473 | return data; 474 | } 475 | } 476 | -------------------------------------------------------------------------------- /lib/model/v0/stock/news/news.dart: -------------------------------------------------------------------------------- 1 | /// The [News] data represent the news of a company. 2 | class News { 3 | News( 4 | {required this.image, 5 | required this.url, 6 | required this.date, 7 | required this.headline, 8 | required this.source, 9 | required this.summary}); 10 | 11 | /// The image of the news. 12 | String image; 13 | 14 | /// The url of the news. 15 | String url; 16 | 17 | /// The date of the news. 18 | DateTime date; 19 | 20 | /// The headline of the news. 21 | String headline; 22 | 23 | /// The source of the news. 24 | String source; 25 | 26 | /// The summary of the news. 27 | String summary; 28 | 29 | factory News.fromJson(Map json) => News( 30 | image: json["image"], 31 | url: json["url"], 32 | date: DateTime.parse(json["publishedDate"]), 33 | headline: json["title"], 34 | source: json["site"], 35 | summary: json["text"], 36 | ); 37 | 38 | Map toJson() => { 39 | "image": image, 40 | "url": url, 41 | "date": date.toIso8601String(), 42 | "headline": headline, 43 | "source": source, 44 | "summary": summary, 45 | }; 46 | } 47 | -------------------------------------------------------------------------------- /lib/model/v0/stock/profile/profile.dart: -------------------------------------------------------------------------------- 1 | /// The [CompanyProfile] class is used to get the company profile. 2 | /// It contains the currency, the zip code, the IPO date, the sector, the industry, 3 | /// the total number of employees, the market capitalization, the country, the beta, 4 | /// the changes, the state, the city, the average volume, the exchange short name, 5 | /// the cusip, the is fund, the default image, the is ETF, the phone, the website, 6 | /// the is actively trading, the symbol, the company name, the dcf, the last div, 7 | /// the isin, the range, the is ADR, the dcf diff, the exchange and the description. 8 | class CompanyProfile { 9 | CompanyProfile({ 10 | required this.currency, 11 | required this.zip, 12 | required this.ipo, 13 | required this.sector, 14 | required this.industry, 15 | required this.employeeTotal, 16 | required this.marketCapitalization, 17 | required this.country, 18 | required this.beta, 19 | required this.changes, 20 | required this.state, 21 | required this.city, 22 | required this.volAvg, 23 | required this.exchangeShortName, 24 | required this.cusip, 25 | required this.isFund, 26 | required this.defaultImage, 27 | required this.isEtf, 28 | required this.phone, 29 | required this.website, 30 | required this.isActivelyTrading, 31 | required this.symbol, 32 | required this.companyName, 33 | required this.dcf, 34 | required this.lastDiv, 35 | required this.isin, 36 | required this.range, 37 | required this.isAdr, 38 | required this.dcfDiff, 39 | required this.exchange, 40 | required this.description, 41 | required this.price, 42 | }); 43 | 44 | String? currency; 45 | String? zip; 46 | DateTime ipo; 47 | String sector; 48 | String industry; 49 | int? employeeTotal; 50 | double marketCapitalization; 51 | String? country; 52 | double beta; 53 | double changes; 54 | String? state; 55 | String? city; 56 | double? volAvg; 57 | String? exchangeShortName; 58 | String? cusip; 59 | bool? isFund; 60 | bool? defaultImage; 61 | bool? isEtf; 62 | String? phone; 63 | String? website; 64 | bool? isActivelyTrading; 65 | String? symbol; 66 | String? companyName; 67 | double? dcf; 68 | double? lastDiv; 69 | String? isin; 70 | String? range; 71 | bool? isAdr; 72 | double? dcfDiff; 73 | String? exchange; 74 | String? description; 75 | double? price; 76 | 77 | factory CompanyProfile.fromJson(Map json) => CompanyProfile( 78 | currency: json["currency"], 79 | zip: json["zip"], 80 | ipo: json["ipo"] == null 81 | ? DateTime.parse("1970-01-01") 82 | : DateTime.parse(json["ipo"]), 83 | sector: json["sector"] ?? "N/A", 84 | industry: json["industry"] ?? "N/A", 85 | employeeTotal: json["employeeTotal"]?.toInt() ?? 0, 86 | marketCapitalization: 87 | (json["marketCapitalization"]?.toDouble() ?? 0) / (1000 * 1000), 88 | country: json["country"], 89 | beta: json["beta"].toDouble(), 90 | changes: json["changes"].toDouble(), 91 | state: json["state"], 92 | city: json["city"], 93 | volAvg: json["volAvg"].toDouble(), 94 | exchangeShortName: json["exchangeShortName"], 95 | cusip: json["cusip"], 96 | isFund: json["isFund"], 97 | defaultImage: json["defaultImage"], 98 | isEtf: json["isEtf"], 99 | phone: json["phone"], 100 | website: json["website"], 101 | isActivelyTrading: json["isActivelyTrading"], 102 | symbol: json["symbol"], 103 | companyName: json["companyName"], 104 | dcf: json["dcf"]?.toDouble(), 105 | lastDiv: json["lastDiv"]?.toDouble(), 106 | isin: json["isin"], 107 | range: json["range"], 108 | isAdr: json["isAdr"], 109 | dcfDiff: json["dcfDiff"]?.toDouble(), 110 | exchange: json["exchange"], 111 | description: json["description"], 112 | price: json["price"]?.toDouble(), 113 | ); 114 | } 115 | -------------------------------------------------------------------------------- /lib/model/v0/stock/quote/quote.dart: -------------------------------------------------------------------------------- 1 | /// The [Quote] class is used to represent the quote for a given stock symbol. 2 | /// It contains the current price, the daily change, the daily change percentage, 3 | /// the high price, the low price, the open price, the previous close price, 4 | /// the timestamp, the volume, the historical price, the metrics, the exchange 5 | /// and the earnings announcement. 6 | class Quote { 7 | Quote({ 8 | required this.c, 9 | required this.d, 10 | required this.dp, 11 | required this.h, 12 | required this.l, 13 | required this.o, 14 | required this.pc, 15 | required this.t, 16 | this.v, 17 | this.historicalPrice, 18 | this.metrics, 19 | this.exchange, 20 | this.earningsAnnouncement, 21 | }); 22 | 23 | /// The [c] property is used to get the current close price. 24 | double c; 25 | 26 | /// The [d] property is used to get the daily change. 27 | double d; 28 | 29 | /// The [dp] property is used to get the daily change percentage. 30 | double? dp; 31 | 32 | /// The [h] property is used to get the high price. 33 | double h; 34 | 35 | /// The [l] property is used to get the low price. 36 | double l; 37 | 38 | /// The [o] property is used to get the open price. 39 | double o; 40 | 41 | /// The [pc] property is used to get the previous close price. 42 | double pc; 43 | 44 | /// The [t] property is used to get the timestamp. 45 | int t; 46 | 47 | /// The [v] property is used to get the volume. 48 | double? v; 49 | 50 | /// The [historicalPrice] property is used to get the historical price. 51 | HistoricalPrice? historicalPrice; 52 | 53 | /// The [metrics] property is used to get the metrics. 54 | Metrics? metrics; 55 | 56 | /// The [exchange] property is used to get the exchange. 57 | String? exchange; 58 | 59 | /// The [earningsAnnouncement] property is used to get the earnings announcement. 60 | String? earningsAnnouncement; 61 | 62 | factory Quote.fromJson(Map json) => Quote( 63 | c: (json["c"] ?? 0).toDouble(), 64 | d: (json["d"] ?? 0).toDouble(), 65 | dp: (json["dp"] ?? 0).toDouble(), 66 | h: (json["h"] ?? 0).toDouble(), 67 | l: (json["l"] ?? 0).toDouble(), 68 | o: (json["o"] ?? 0).toDouble(), 69 | pc: (json["pc"] ?? 0).toDouble(), 70 | t: json["t"] ?? 0, 71 | v: (json["v"] ?? 0).toDouble(), 72 | //historicalPrice: HistoricalPrice.fromJson(json["historical_price"]), 73 | metrics: 74 | json["metrics"] == null ? null : Metrics.fromJson(json["metrics"]), 75 | // exchange: json["exchange"], 76 | // earningsAnnouncement: json["earningsAnnouncement"], 77 | ); 78 | 79 | Map toJson() => { 80 | "c": c, 81 | "d": d, 82 | "dp": dp, 83 | "h": h, 84 | "l": l, 85 | "o": o, 86 | "pc": pc, 87 | "t": t, 88 | "v": v, 89 | }; 90 | } 91 | 92 | class HistoricalPrice { 93 | HistoricalPrice({ 94 | required this.day, 95 | required this.the50Days, 96 | required this.the200Days, 97 | }); 98 | 99 | double? day; 100 | double? the50Days; 101 | double? the200Days; 102 | 103 | factory HistoricalPrice.fromJson(Map json) => 104 | HistoricalPrice( 105 | day: json["day"]?.toDouble(), 106 | the50Days: json["50days"]?.toDouble(), 107 | the200Days: json["200days"]?.toDouble(), 108 | ); 109 | 110 | Map toJson() => { 111 | "day": day, 112 | "50days": the50Days, 113 | "200days": the200Days, 114 | }; 115 | } 116 | 117 | class Metrics { 118 | Metrics({ 119 | required this.marketCapitalization, 120 | required this.avgVolume, 121 | required this.eps, 122 | required this.peRatio, 123 | required this.sharesOutstanding, 124 | }); 125 | 126 | double? marketCapitalization; 127 | double? avgVolume; 128 | double? eps; 129 | double? peRatio; 130 | double? sharesOutstanding; 131 | 132 | factory Metrics.fromJson(Map json) => Metrics( 133 | marketCapitalization: json["marketCapitalization"]?.toDouble(), 134 | avgVolume: json["avgVolume"]?.toDouble(), 135 | eps: json["eps"]?.toDouble(), 136 | peRatio: json["pe/ratio"]?.toDouble(), 137 | sharesOutstanding: json["sharesOutstanding"]?.toDouble(), 138 | ); 139 | 140 | Map toJson() => { 141 | "marketCapitalization": marketCapitalization, 142 | "avgVolume": avgVolume, 143 | "eps": eps, 144 | "pe/ratio": peRatio, 145 | }; 146 | } 147 | -------------------------------------------------------------------------------- /lib/model/v0/stock/split/split.dart: -------------------------------------------------------------------------------- 1 | /// The [Split] data represent the split of a company. 2 | class Splits { 3 | /// The [Split] data represent the split of a company. 4 | List? split; 5 | 6 | /// The [symbol] data represent the symbol of a company. 7 | String? symbol; 8 | 9 | Splits({this.split, this.symbol}); 10 | 11 | Splits.fromJson(Map json) { 12 | if (json['split'] != null) { 13 | split = []; 14 | json['split'].forEach((v) { 15 | split!.add(Split.fromJson(v)); 16 | }); 17 | } 18 | symbol = json['symbol']; 19 | } 20 | 21 | Map toJson() { 22 | final Map data = {}; 23 | if (split != null) { 24 | data['split'] = split!.map((v) => v.toJson()).toList(); 25 | } 26 | data['symbol'] = symbol; 27 | return data; 28 | } 29 | } 30 | 31 | class Split { 32 | /// The [date] data represent the date of a split. 33 | String? date; 34 | 35 | /// The [symbol] data represent the symbol of a company. 36 | String? symbol; 37 | 38 | /// The [fromFactor] data represent the from factor of a split. 39 | int? fromFactor; 40 | 41 | /// The [toFactor] data represent the to factor of a split. 42 | int? toFactor; 43 | 44 | Split({this.date, this.symbol, this.fromFactor, this.toFactor}); 45 | 46 | Split.fromJson(Map json) { 47 | date = json['date']; 48 | symbol = json['symbol']; 49 | fromFactor = json['fromFactor']; 50 | toFactor = json['toFactor']; 51 | } 52 | 53 | Map toJson() { 54 | final Map data = {}; 55 | data['date'] = date; 56 | data['symbol'] = symbol; 57 | data['fromFactor'] = fromFactor; 58 | data['toFactor'] = toFactor; 59 | return data; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /lib/model/v0/widget/peers/peers.dart: -------------------------------------------------------------------------------- 1 | /// The [PeersWidget] data represent the peers of a company. 2 | class PeersWidget { 3 | PeersWidget({ 4 | required this.symbol, 5 | required this.name, 6 | required this.category, 7 | required this.close, 8 | required this.priceChange, 9 | }); 10 | 11 | /// The symbol of the company. 12 | String symbol; 13 | 14 | /// The name of the company. 15 | String name; 16 | 17 | /// The category of the company. 18 | String category; 19 | 20 | /// The close of the company. 21 | double close; 22 | 23 | /// The price change of the company. 24 | double priceChange; 25 | 26 | factory PeersWidget.fromJson(Map json) => PeersWidget( 27 | symbol: json["symbol"], 28 | name: json["name"], 29 | category: json["category"], 30 | close: json["close"].toDouble(), 31 | priceChange: json["priceChange"].toDouble(), 32 | ); 33 | 34 | Map toJson() => { 35 | "symbol": symbol, 36 | "name": name, 37 | "category": category, 38 | "close": close, 39 | "priceChange": priceChange, 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | 10 | void fl_register_plugins(FlPluginRegistry* registry) { 11 | } 12 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 9 | ) 10 | 11 | set(PLUGIN_BUNDLED_LIBRARIES) 12 | 13 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 18 | endforeach(plugin) 19 | 20 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 23 | endforeach(ffi_plugin) 24 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | 9 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 10 | } 11 | -------------------------------------------------------------------------------- /macos/Flutter/ephemeral/Flutter-Generated.xcconfig: -------------------------------------------------------------------------------- 1 | // This is a generated file; do not edit or check into version control. 2 | FLUTTER_ROOT=/opt/homebrew/Caskroom/flutter/3.3.4/flutter 3 | FLUTTER_APPLICATION_PATH=/Users/monolidth/StudioProjects/dart-sdk 4 | COCOAPODS_PARALLEL_CODE_SIGN=true 5 | FLUTTER_BUILD_DIR=build 6 | FLUTTER_BUILD_NAME=0.0.6 7 | FLUTTER_BUILD_NUMBER=0.0.6 8 | DART_OBFUSCATION=false 9 | TRACK_WIDGET_CREATION=true 10 | TREE_SHAKE_ICONS=false 11 | PACKAGE_CONFIG=.dart_tool/package_config.json 12 | -------------------------------------------------------------------------------- /macos/Flutter/ephemeral/flutter_export_environment.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This is a generated file; do not edit or check into version control. 3 | export "FLUTTER_ROOT=/opt/homebrew/Caskroom/flutter/3.3.4/flutter" 4 | export "FLUTTER_APPLICATION_PATH=/Users/monolidth/StudioProjects/dart-sdk" 5 | export "COCOAPODS_PARALLEL_CODE_SIGN=true" 6 | export "FLUTTER_BUILD_DIR=build" 7 | export "FLUTTER_BUILD_NAME=0.0.6" 8 | export "FLUTTER_BUILD_NUMBER=0.0.6" 9 | export "DART_OBFUSCATION=false" 10 | export "TRACK_WIDGET_CREATION=true" 11 | export "TREE_SHAKE_ICONS=false" 12 | export "PACKAGE_CONFIG=.dart_tool/package_config.json" 13 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: bavest 2 | description: The Bavest SDK for Dart and Flutter provides realtime data for stocks, etfs, mutual fonds. 3 | 4 | version: 0.0.7 5 | homepage: https://www.bavest.co 6 | 7 | environment: 8 | sdk: '>=2.19.1 <4.0.0' 9 | flutter: ">=3.0.0" 10 | 11 | dependencies: 12 | dio: ^5.0.1 13 | fake_async: ^1.3.1 14 | flutter: 15 | sdk: flutter 16 | logger: ^2.0.2 17 | memory_cache: ^1.2.0 18 | rxdart: ^0.27.7 19 | web_socket_channel: ^2.3.0 20 | 21 | dev_dependencies: 22 | flutter_test: 23 | sdk: flutter 24 | flutter_lints: ^2.0.0 25 | 26 | # For information on the generic Dart part of this file, see the 27 | # following page: https://dart.dev/tools/pub/pubspec 28 | 29 | # The following section is specific to Flutter packages. 30 | flutter: 31 | 32 | # To add assets to your package, add an assets section, like this: 33 | # assets: 34 | # - images/a_dot_burr.jpeg 35 | # - images/a_dot_ham.jpeg 36 | # 37 | # For details regarding assets in packages, see 38 | # https://flutter.dev/assets-and-images/#from-packages 39 | # 40 | # An image asset can refer to one or more resolution-specific "variants", see 41 | # https://flutter.dev/assets-and-images/#resolution-aware 42 | 43 | # To add custom fonts to your package, add a fonts section here, 44 | # in this "flutter" section. Each entry in this list should have a 45 | # "family" key with the font family name, and a "fonts" key with a 46 | # list giving the asset and other descriptors for the font. For 47 | # example: 48 | # fonts: 49 | # - family: Schyler 50 | # fonts: 51 | # - asset: fonts/Schyler-Regular.ttf 52 | # - asset: fonts/Schyler-Italic.ttf 53 | # style: italic 54 | # - family: Trajan Pro 55 | # fonts: 56 | # - asset: fonts/TrajanPro.ttf 57 | # - asset: fonts/TrajanPro_Bold.ttf 58 | # weight: 700 59 | # 60 | # For details regarding fonts in packages, see 61 | # https://flutter.dev/custom-fonts/#from-packages 62 | -------------------------------------------------------------------------------- /test/unit_test/api_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:bavest/bavest.dart'; 2 | import 'package:bavest/model/v0/security/security_identifier.dart'; 3 | import 'package:bavest/model/v0/stock/candle/candle_type.dart'; 4 | import 'package:flutter_test/flutter_test.dart'; 5 | 6 | void main() { 7 | var apiKey = const String.fromEnvironment('API_KEY'); 8 | var client = BavestRestClient(apiKey); 9 | final id = SecurityIdentifier(symbol: "AAPL"); 10 | 11 | test("Search test", () async { 12 | var search = await client.search("App"); 13 | expect(search.results!.isNotEmpty, true); 14 | }); 15 | 16 | test("Stock test", () async { 17 | await client.quote(id); 18 | await client.profile(id); 19 | await client.metric(id); 20 | 21 | var dividends = await client.dividends(id); 22 | expect(dividends.data?.isNotEmpty ?? false, true); 23 | 24 | await client.companyNews(id); 25 | await client.fundamentals(id); 26 | await client.peersWidget(id); 27 | 28 | final Forex forex = await client.forex("EUR", "USD"); 29 | expect(forex.result != null && forex.result! > 0, true); 30 | 31 | final sentiment = await client.sentiment(id); 32 | expect(sentiment.score != null && sentiment.score! > 0, true); 33 | 34 | final splits = await client.splits(id, years: 5); 35 | expect(splits.split?.isNotEmpty ?? false, true); 36 | }); 37 | 38 | test("Etf test", () async { 39 | final id = SecurityIdentifier(symbol: "ARKK"); 40 | final sectors = await client.etfSector(id); 41 | expect(sectors.sectorExposure?.isNotEmpty ?? false, true); 42 | 43 | final countries = await client.etfCountry(id); 44 | expect(countries.countryExposure?.isNotEmpty ?? false, true); 45 | 46 | final holdings = await client.etfHoldings(id); 47 | expect(holdings.holdings?.isNotEmpty ?? false, true); 48 | 49 | final etfProfile = await client.etfProfile(id); 50 | expect(etfProfile.profile?.name != null, true); 51 | }); 52 | 53 | test("Portfolio test", () async { 54 | var portfolio = Portfolio.fromJson({ 55 | "portfolio_items": [ 56 | {"symbol": "ABEA.DE", "amount": 5, "buy_date": 1649887200000}, 57 | {"symbol": "DEQ.DE", "amount": 41, "buy_date": 1619647200000}, 58 | {"symbol": "AAPL", "amount": 100, "buy_date": 1556661600000}, 59 | {"symbol": "ADS.DE", "amount": 10, "buy_date": 1491343200000} 60 | ] 61 | }); 62 | 63 | var from = 1630352898; 64 | var to = 1655848800; 65 | var resolution = CandleResolution.day; 66 | 67 | await client.portfolioStats(portfolio, 68 | from: from, to: to, resolution: resolution); 69 | 70 | var allocation = Portfolio.fromJson({ 71 | "portfolio_items": [ 72 | {"symbol": "BNTX", "amount": 10}, 73 | {"symbol": "AAPL", "amount": 4}, 74 | {"symbol": "SAP.DE", "amount": 4} 75 | ] 76 | }); 77 | 78 | await client.portfolioPrice(portfolio); 79 | await client.portfolioAllocation(allocation); 80 | await client.portfolioRegion(allocation); 81 | await client.portfolioSector(allocation); 82 | await client.portfolioPrice(portfolio); 83 | await client.portfolioChart(portfolio, 84 | from: from, to: to, resolution: resolution); 85 | }); 86 | } 87 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | 10 | void RegisterPlugins(flutter::PluginRegistry* registry) { 11 | } 12 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 9 | ) 10 | 11 | set(PLUGIN_BUNDLED_LIBRARIES) 12 | 13 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 14 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 15 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 16 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 18 | endforeach(plugin) 19 | 20 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 21 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 23 | endforeach(ffi_plugin) 24 | --------------------------------------------------------------------------------