├── test ├── __init__.py ├── test_data_loaders.py ├── test_analysis.py ├── test_visualization.py ├── test_ml.py ├── test_risk.py └── test_portfolio.py ├── flowpylib ├── data │ ├── __init__.py │ ├── loaders │ │ ├── __init__.py │ │ ├── csv_loader.py │ │ ├── arctic_loader.py │ │ ├── kdb_loader.py │ │ ├── oracle_loader.py │ │ ├── pgsql_loader.py │ │ ├── mysql_loader.py │ │ └── sqlserver_loader.py │ └── api_integration.py ├── ml │ ├── __init__.py │ └── models.py ├── risk │ ├── __init__.py │ └── compliance.py ├── analysis │ ├── __init__.py │ ├── fx │ │ ├── __init__.py │ │ └── fx_metrics.py │ ├── bonds │ │ ├── __init__.py │ │ └── bond_metrics.py │ ├── crypto │ │ ├── __init__.py │ │ ├── crypto_metrics.py │ │ └── defi_tools.py │ ├── general │ │ ├── __init__.py │ │ ├── metrics.py │ │ └── impact.py │ ├── commodities │ │ ├── __init__.py │ │ └── commodity_metrics.py │ ├── equities │ │ ├── __init__.py │ │ └── equity_metrics.py │ ├── geospatial │ │ ├── __init__.py │ │ └── geospatial.py │ ├── real_estate │ │ ├── __init__.py │ │ └── real_estate_metrics.py │ └── sentiment │ │ ├── __init__.py │ │ └── sentiment_analysis.py ├── portfolio │ ├── __init__.py │ └── optimization.py ├── visualization │ ├── __init__.py │ ├── 3d_visuals.py │ ├── plotter.py │ ├── bokeh_visuals.py │ ├── plotly_visuals.py │ └── dash_app.py └── __init__.py ├── examples ├── visualization │ ├── 3d_visualization_example.py │ └── plot_data.py ├── api_request.py ├── analysis │ ├── equity_analysis_example.py │ ├── fx_analysis_example.py │ ├── analyze_impact.py │ └── analyze_metrics.py ├── ml │ └── ml_forecast_example.py ├── portfolio │ └── portfolio_optimization_example.py ├── data_loading │ ├── load_sql_data.py │ └── load_data.py ├── geospatial_analysis_example.py ├── api_server.py ├── risk_compliance │ └── risk_management_example.py ├── defi_analysis_example.py └── sentiment_analysis_example.py ├── requirements.txt ├── setup.cfg ├── setup.py ├── .readthedocs.yaml ├── .github └── workflows │ └── python-publish.yml ├── LICENSE ├── Dockerfile ├── .gitignore └── README.md /test/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/data/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/ml/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/risk/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/fx/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/portfolio/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/bonds/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/crypto/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/general/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/data/loaders/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/visualization/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/commodities/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/equities/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/geospatial/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/real_estate/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/sentiment/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/visualization/3d_visualization_example.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flowpylib/analysis/fx/fx_metrics.py: -------------------------------------------------------------------------------- 1 | def calculate_fx_spread(bid, ask): 2 | return ask - bid 3 | -------------------------------------------------------------------------------- /flowpylib/__init__.py: -------------------------------------------------------------------------------- 1 | __title__ = 'flowpylib' 2 | __author__ = 'Jialue Chen' 3 | __license__ = 'BSD 2-Clause' 4 | __version__='1.2.2' -------------------------------------------------------------------------------- /flowpylib/data/loaders/csv_loader.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | 3 | def load_csv_data(file_path): 4 | return pd.read_csv(file_path) 5 | -------------------------------------------------------------------------------- /flowpylib/analysis/commodities/commodity_metrics.py: -------------------------------------------------------------------------------- 1 | def calculate_basis(spot_price, futures_price): 2 | return futures_price - spot_price 3 | -------------------------------------------------------------------------------- /flowpylib/analysis/real_estate/real_estate_metrics.py: -------------------------------------------------------------------------------- 1 | def calculate_cap_rate(net_operating_income, property_value): 2 | return net_operating_income / property_value 3 | -------------------------------------------------------------------------------- /flowpylib/analysis/crypto/crypto_metrics.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | 3 | def calculate_volatility(prices, window): 4 | return pd.Series(prices).rolling(window=window).std() 5 | -------------------------------------------------------------------------------- /flowpylib/analysis/bonds/bond_metrics.py: -------------------------------------------------------------------------------- 1 | def calculate_duration(cash_flows, yield_to_maturity): 2 | return sum(cf / (1 + yield_to_maturity)**(t+1) for t, cf in enumerate(cash_flows)) 3 | -------------------------------------------------------------------------------- /flowpylib/analysis/general/metrics.py: -------------------------------------------------------------------------------- 1 | def calculate_vwap(prices, volumes): 2 | total_volume = sum(volumes) 3 | if total_volume == 0: 4 | return None 5 | return sum(p * v for p, v in zip(prices, volumes)) / total_volume 6 | -------------------------------------------------------------------------------- /flowpylib/analysis/geospatial/geospatial.py: -------------------------------------------------------------------------------- 1 | import geopandas as gpd 2 | import matplotlib.pyplot as plt 3 | 4 | def plot_geospatial_data(geodata, attribute): 5 | geodata.plot(column=attribute, cmap='OrRd', legend=True) 6 | plt.show() 7 | -------------------------------------------------------------------------------- /flowpylib/data/loaders/arctic_loader.py: -------------------------------------------------------------------------------- 1 | from arctic import Arctic 2 | import pandas as pd 3 | 4 | def load_arctic_data(host, library, symbol): 5 | store = Arctic(host) 6 | lib = store[library] 7 | df = lib.read(symbol).data 8 | return df 9 | -------------------------------------------------------------------------------- /test/test_data_loaders.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from flowpylib.data.loaders.csv_loader import load_csv_data 3 | 4 | def test_load_csv_data(): 5 | data = load_csv_data('tests/data/sample_data.csv') 6 | assert not data.empty, "Data should not be empty" 7 | -------------------------------------------------------------------------------- /flowpylib/analysis/general/impact.py: -------------------------------------------------------------------------------- 1 | def calculate_slippage(expected_price, actual_price): 2 | return actual_price - expected_price 3 | 4 | def calculate_market_impact(initial_price, final_price, volume): 5 | return (final_price - initial_price) * volume 6 | -------------------------------------------------------------------------------- /examples/api_request.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | url = 'http://localhost:5000/vwap' 4 | data = { 5 | 'prices': [100, 101, 102, 103, 104], 6 | 'volumes': [10, 15, 10, 5, 20] 7 | } 8 | response = requests.post(url, json=data) 9 | print(response.json()) 10 | -------------------------------------------------------------------------------- /flowpylib/data/loaders/kdb_loader.py: -------------------------------------------------------------------------------- 1 | from qpython import qconnection 2 | import pandas as pd 3 | 4 | def load_kdb_data(host, port, query): 5 | with qconnection.QConnection(host=host, port=port) as q: 6 | data = q(query) 7 | return pd.DataFrame(data) 8 | -------------------------------------------------------------------------------- /flowpylib/data/loaders/oracle_loader.py: -------------------------------------------------------------------------------- 1 | import cx_Oracle 2 | import pandas as pd 3 | 4 | def load_oracle_data(dsn, user, password, query): 5 | conn = cx_Oracle.connect(user=user, password=password, dsn=dsn) 6 | df = pd.read_sql(query, conn) 7 | conn.close() 8 | return df 9 | -------------------------------------------------------------------------------- /flowpylib/analysis/crypto/defi_tools.py: -------------------------------------------------------------------------------- 1 | from web3 import Web3 2 | 3 | def analyze_smart_contract(contract_address, abi): 4 | web3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID')) 5 | contract = web3.eth.contract(address=contract_address, abi=abi) 6 | return contract.functions 7 | -------------------------------------------------------------------------------- /flowpylib/analysis/equities/equity_metrics.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def calculate_beta(asset_returns, market_returns): 4 | covariance_matrix = np.cov(asset_returns, market_returns) 5 | covariance = covariance_matrix[0, 1] 6 | market_variance = covariance_matrix[1, 1] 7 | return covariance / market_variance 8 | -------------------------------------------------------------------------------- /examples/analysis/equity_analysis_example.py: -------------------------------------------------------------------------------- 1 | from flowpylib.analysis.equities.equity_metrics import calculate_beta 2 | 3 | # Example data 4 | asset_returns = [0.01, 0.02, -0.01, 0.03] 5 | market_returns = [0.015, 0.025, -0.005, 0.035] 6 | 7 | beta = calculate_beta(asset_returns, market_returns) 8 | print(f"Calculated Beta: {beta}") 9 | -------------------------------------------------------------------------------- /examples/visualization/plot_data.py: -------------------------------------------------------------------------------- 1 | from flowpylib.visualization.plotter import plot_candlestick 2 | import pandas as pd 3 | 4 | # Example data 5 | data = pd.DataFrame({ 6 | 'Date': pd.date_range(start='2021-01-01', periods=5, freq='D'), 7 | 'Close': [100, 102, 104, 103, 105] 8 | }) 9 | 10 | plot_candlestick(data) 11 | -------------------------------------------------------------------------------- /examples/analysis/fx_analysis_example.py: -------------------------------------------------------------------------------- 1 | from flowpylib.analysis.fx.fx_metrics import calculate_fx_spread 2 | 3 | # Example data 4 | bid_prices = [1.105, 1.106, 1.107] 5 | ask_prices = [1.110, 1.111, 1.112] 6 | 7 | spreads = [calculate_fx_spread(bid, ask) for bid, ask in zip(bid_prices, ask_prices)] 8 | print(f"Calculated FX Spreads: {spreads}") 9 | -------------------------------------------------------------------------------- /flowpylib/data/api_integration.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | def fetch_real_time_data(api_url, params): 4 | response = requests.get(api_url, params=params) 5 | return response.json() 6 | 7 | def analyze_social_media_sentiment(api_url, params): 8 | response = requests.get(api_url, params=params) 9 | return response.json() 10 | -------------------------------------------------------------------------------- /test/test_analysis.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from flowpylib.analysis.general.metrics import calculate_vwap 3 | 4 | def test_calculate_vwap(): 5 | prices = [100, 101, 102, 103, 104] 6 | volumes = [10, 15, 10, 5, 20] 7 | vwap = calculate_vwap(prices, volumes) 8 | assert vwap == pytest.approx(101.9091, 0.0001), "VWAP calculation error" 9 | -------------------------------------------------------------------------------- /flowpylib/visualization/3d_visuals.py: -------------------------------------------------------------------------------- 1 | import plotly.graph_objs as go 2 | 3 | def plot_3d_surface(data): 4 | fig = go.Figure(data=[go.Surface(z=data)]) 5 | fig.update_layout(title='3D Surface Plot', autosize=False, 6 | width=800, height=800, 7 | margin=dict(l=65, r=50, b=65, t=90)) 8 | fig.show() 9 | -------------------------------------------------------------------------------- /flowpylib/visualization/plotter.py: -------------------------------------------------------------------------------- 1 | import matplotlib.pyplot as plt 2 | 3 | def plot_candlestick(data): 4 | fig, ax = plt.subplots() 5 | ax.plot(data['Date'], data['Close'], label='Close Price') 6 | ax.set_xlabel('Date') 7 | ax.set_ylabel('Price') 8 | ax.set_title('Candlestick Chart') 9 | plt.legend() 10 | plt.show() 11 | -------------------------------------------------------------------------------- /flowpylib/portfolio/optimization.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def calculate_portfolio_variance(weights, cov_matrix): 4 | return np.dot(weights.T, np.dot(cov_matrix, weights)) 5 | 6 | def optimize_portfolio(returns, cov_matrix, risk_tolerance): 7 | num_assets = len(returns) 8 | weights = np.random.dirichlet(np.ones(num_assets), size=1) 9 | return weights 10 | -------------------------------------------------------------------------------- /flowpylib/data/loaders/pgsql_loader.py: -------------------------------------------------------------------------------- 1 | import psycopg2 2 | import pandas as pd 3 | 4 | def load_pgsql_data(host, database, user, password, query): 5 | conn = psycopg2.connect( 6 | host=host, 7 | database=database, 8 | user=user, 9 | password=password 10 | ) 11 | df = pd.read_sql(query, conn) 12 | conn.close() 13 | return df 14 | -------------------------------------------------------------------------------- /examples/ml/ml_forecast_example.py: -------------------------------------------------------------------------------- 1 | from flowpylib.ml.models import train_forecast_model 2 | import pandas as pd 3 | 4 | # Example data 5 | data = pd.DataFrame({ 6 | 'feature1': [1, 2, 3, 4, 5], 7 | 'feature2': [2, 3, 4, 5, 6], 8 | 'target': [1.1, 1.2, 1.3, 1.4, 1.5] 9 | }) 10 | 11 | model = train_forecast_model(data, 'target') 12 | print("Model trained successfully.") 13 | -------------------------------------------------------------------------------- /flowpylib/data/loaders/mysql_loader.py: -------------------------------------------------------------------------------- 1 | import mysql.connector 2 | import pandas as pd 3 | 4 | def load_mysql_data(host, user, password, database, query): 5 | conn = mysql.connector.connect( 6 | host=host, 7 | user=user, 8 | password=password, 9 | database=database 10 | ) 11 | df = pd.read_sql(query, conn) 12 | conn.close() 13 | return df 14 | -------------------------------------------------------------------------------- /test/test_visualization.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from flowpylib.visualization.plotter import plot_candlestick 3 | import pandas as pd 4 | 5 | def test_plot_candlestick(): 6 | data = pd.DataFrame({ 7 | 'Date': pd.date_range(start='2021-01-01', periods=5, freq='D'), 8 | 'Close': [100, 102, 104, 103, 105] 9 | }) 10 | fig = plot_candlestick(data) 11 | assert fig, "Plot should be generated" 12 | -------------------------------------------------------------------------------- /examples/portfolio/portfolio_optimization_example.py: -------------------------------------------------------------------------------- 1 | from flowpylib.portfolio.optimization import optimize_portfolio 2 | 3 | # Example data 4 | expected_returns = [0.1, 0.2, 0.15] 5 | cov_matrix = [[0.01, 0.0018, 0.0011], 6 | [0.0018, 0.04, 0.0023], 7 | [0.0011, 0.0023, 0.02]] 8 | 9 | weights = optimize_portfolio(expected_returns, cov_matrix, 0.1) 10 | print(f"Optimized Weights: {weights}") 11 | -------------------------------------------------------------------------------- /flowpylib/risk/compliance.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | def calculate_var(returns, confidence_level=0.95): 4 | sorted_returns = np.sort(returns) 5 | index = int((1 - confidence_level) * len(sorted_returns)) 6 | return sorted_returns[index] 7 | 8 | def compliance_check(transaction_data): 9 | suspicious_transactions = transaction_data[transaction_data['Amount'] > 10000] 10 | return suspicious_transactions 11 | -------------------------------------------------------------------------------- /test/test_ml.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | from flowpylib.ml.models import train_forecast_model 3 | import pandas as pd 4 | 5 | def test_train_forecast_model(): 6 | data = pd.DataFrame({ 7 | 'feature1': [1, 2, 3, 4, 5], 8 | 'feature2': [2, 3, 4, 5, 6], 9 | 'target': [1.1, 1.2, 1.3, 1.4, 1.5] 10 | }) 11 | model = train_forecast_model(data, 'target') 12 | assert model, "Model should be trained" 13 | -------------------------------------------------------------------------------- /flowpylib/data/loaders/sqlserver_loader.py: -------------------------------------------------------------------------------- 1 | import pyodbc 2 | import pandas as pd 3 | 4 | def load_sqlserver_data(server, database, user, password, query): 5 | conn_str = ( 6 | f"DRIVER={{SQL Server}};" 7 | f"SERVER={server};" 8 | f"DATABASE={database};" 9 | f"UID={user};" 10 | f"PWD={password};" 11 | ) 12 | conn = pyodbc.connect(conn_str) 13 | df = pd.read_sql(query, conn) 14 | conn.close() 15 | return df 16 | -------------------------------------------------------------------------------- /examples/data_loading/load_sql_data.py: -------------------------------------------------------------------------------- 1 | # examples/load_sql_data.py 2 | from flowpylib import load_data 3 | 4 | # Load data from MySQL 5 | mysql_data = load_data('mysql', host='localhost', user='username', password='password', database='dbname', query='SELECT * FROM trades') 6 | print(mysql_data.head()) 7 | 8 | # Load data from PostgreSQL 9 | pgsql_data = load_data('pgsql', host='localhost', user='username', password='password', database='dbname', query='SELECT * FROM trades') 10 | print(pgsql_data.head()) 11 | -------------------------------------------------------------------------------- /flowpylib/ml/models.py: -------------------------------------------------------------------------------- 1 | from sklearn.ensemble import RandomForestRegressor 2 | from sklearn.preprocessing import StandardScaler 3 | from sklearn.pipeline import Pipeline 4 | 5 | def train_forecast_model(data, target_column): 6 | X = data.drop(columns=[target_column]) 7 | y = data[target_column] 8 | 9 | pipeline = Pipeline([ 10 | ('scaler', StandardScaler()), 11 | ('model', RandomForestRegressor()) 12 | ]) 13 | 14 | model = pipeline.fit(X, y) 15 | return model 16 | -------------------------------------------------------------------------------- /examples/data_loading/load_data.py: -------------------------------------------------------------------------------- 1 | # examples/load_data.py 2 | from flowpylib import load_data 3 | 4 | # Load data from a CSV file 5 | csv_data = load_data('csv', file_path='path/to/data.csv') 6 | print(csv_data.head()) 7 | 8 | # Load data from an Excel file 9 | excel_data = load_data('excel', file_path='path/to/data.xlsx', sheet_name='Sheet1') 10 | print(excel_data.head()) 11 | 12 | # Load data from a KDB database 13 | kdb_data = load_data('kdb', host='localhost', port=5001, query='select from trade') 14 | print(kdb_data.head()) 15 | -------------------------------------------------------------------------------- /flowpylib/analysis/sentiment/sentiment_analysis.py: -------------------------------------------------------------------------------- 1 | from textblob import TextBlob 2 | import pandas as pd 3 | 4 | def analyze_sentiment(text): 5 | analysis = TextBlob(text) 6 | return analysis.sentiment.polarity, analysis.sentiment.subjectivity 7 | 8 | def sentiment_trend_over_time(texts): 9 | sentiment_data = [] 10 | for timestamp, text in texts: 11 | polarity, _ = analyze_sentiment(text) 12 | sentiment_data.append({'timestamp': timestamp, 'sentiment': polarity}) 13 | return pd.DataFrame(sentiment_data) 14 | -------------------------------------------------------------------------------- /flowpylib/visualization/bokeh_visuals.py: -------------------------------------------------------------------------------- 1 | from bokeh.plotting import figure, show, output_file 2 | from bokeh.layouts import gridplot 3 | 4 | def plot_bokeh_dashboard(data): 5 | p1 = figure(plot_width=400, plot_height=400, title="Closing Prices") 6 | p1.line(data['Date'], data['Close'], color='blue', legend_label='Close') 7 | 8 | p2 = figure(plot_width=400, plot_height=400, title="Volume") 9 | p2.vbar(x=data['Date'], top=data['Volume'], width=0.5, color='green', legend_label='Volume') 10 | 11 | layout = gridplot([[p1, p2]]) 12 | output_file("dashboard.html") 13 | show(layout) 14 | -------------------------------------------------------------------------------- /flowpylib/visualization/plotly_visuals.py: -------------------------------------------------------------------------------- 1 | import plotly.graph_objects as go 2 | 3 | def plot_interactive_candlestick(data): 4 | fig = go.Figure(data=[go.Candlestick(x=data['Date'], 5 | open=data['Open'], 6 | high=data['High'], 7 | low=data['Low'], 8 | close=data['Close'])]) 9 | fig.update_layout(title='Interactive Candlestick Chart', 10 | xaxis_title='Date', 11 | yaxis_title='Price') 12 | fig.show() 13 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Core libraries 2 | numpy 3 | pandas 4 | ollama 5 | 6 | # Financial data analysis 7 | pyodbc 8 | sqlalchemy 9 | cx_Oracle 10 | psycopg2-binary 11 | arctic 12 | web3 13 | 14 | # Plotting and visualization 15 | matplotlib 16 | plotly 17 | bokeh 18 | dash 19 | dash-bootstrap-components 20 | 21 | # Geospatial analysis 22 | geopandas 23 | 24 | # Machine learning 25 | scikit-learn 26 | 27 | # Sentiment analysis 28 | textblob 29 | 30 | # API and web services 31 | flask 32 | requests 33 | 34 | # C++ integration 35 | pybind11 36 | 37 | # Testing 38 | pytest 39 | pytest-cov 40 | 41 | # Additional dependencies 42 | inflect 43 | jax -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = flowpylib 3 | version = 1.2.2 4 | description = Algo Toolkit for Flow Order Flow Modeling and Transaction Cost Analysis 5 | author = Jialue Chen 6 | author_email = jialuechen@outlook.com 7 | url = https://github.com/jialuechen/flowpylib 8 | 9 | [options] 10 | packages = find: 11 | install_requires = 12 | pandas 13 | matplotlib 14 | plotly 15 | bokeh 16 | dash 17 | flask 18 | pybind11 19 | numpy 20 | geopandas 21 | sklearn 22 | textblob 23 | requests 24 | web3 25 | 26 | [options.extras_require] 27 | testing = 28 | pytest 29 | pytest-cov 30 | 31 | [build_ext] 32 | inplace = 1 33 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup,find_packages 2 | from setuptools.command.build_ext import build_ext 3 | from flowpylib import __version__ as versionInfo 4 | setup( 5 | name='flowpylib', 6 | version=versionInfo, 7 | description='Python Library for Transaction Cost Analysis and Market Simulation', 8 | author='Jialue Chen', 9 | author_email='jialuechen@outlook.com', 10 | url='https://github.com/jialuechen/flowpylib', 11 | packages=find_packages(), 12 | install_requires=[ 13 | 'ollama','pandas', 'matplotlib', 'plotly', 'bokeh', 'dash', 'flask', 'pybind11', 'numpy', 'geopandas', 'scikit-learn', 'textblob', 'requests','jax', 'web3' 14 | ], 15 | cmdclass={'build_ext': build_ext}, 16 | ) 17 | 18 | -------------------------------------------------------------------------------- /examples/geospatial_analysis_example.py: -------------------------------------------------------------------------------- 1 | import geopandas as gpd 2 | import matplotlib.pyplot as plt 3 | from flowpylib.analysis.geospatial import plot_geospatial_data 4 | 5 | # Example data: This would typically be loaded from a file or database. 6 | # Here, we create a simple GeoDataFrame for demonstration purposes. 7 | data = { 8 | 'geometry': [ 9 | 'POINT (10 50)', 10 | 'POINT (12 54)', 11 | 'POINT (14 52)', 12 | 'POINT (10 48)', 13 | 'POINT (16 49)' 14 | ], 15 | 'value': [100, 200, 150, 250, 300] 16 | } 17 | gdf = gpd.GeoDataFrame(data, geometry=gpd.points_from_xy([10, 12, 14, 10, 16], [50, 54, 52, 48, 49])) 18 | 19 | # Plot the geospatial data 20 | plot_geospatial_data(gdf, 'value') 21 | 22 | # Show plot 23 | plt.show() 24 | -------------------------------------------------------------------------------- /examples/analysis/analyze_impact.py: -------------------------------------------------------------------------------- 1 | from flowpylib.analysis.general.impact import calculate_slippage, calculate_market_impact 2 | 3 | # Example data for market impact analysis 4 | initial_price = 100.0 # Initial price of the asset 5 | final_price = 105.0 # Final price after the trade 6 | trade_volume = 1000 # Volume of the asset traded 7 | 8 | # Calculate market impact 9 | market_impact = calculate_market_impact(initial_price, final_price, trade_volume) 10 | print(f"Market Impact: {market_impact}") 11 | 12 | # Example data for slippage analysis 13 | expected_price = 100.0 # Expected price of the asset 14 | executed_price = 102.0 # Actual executed price 15 | 16 | # Calculate slippage 17 | slippage = calculate_slippage(expected_price, executed_price) 18 | print(f"Slippage: {slippage}") 19 | -------------------------------------------------------------------------------- /examples/analysis/analyze_metrics.py: -------------------------------------------------------------------------------- 1 | from flowpylib.analysis.general.metrics import calculate_vwap 2 | from flowpylib.analysis.equities.equity_metrics import calculate_beta 3 | import numpy as np 4 | 5 | # Example data for VWAP calculation 6 | prices = np.array([100.0, 101.0, 102.0, 103.0, 104.0]) 7 | volumes = np.array([10.0, 15.0, 10.0, 5.0, 20.0]) 8 | 9 | # Calculate VWAP 10 | vwap = calculate_vwap(prices, volumes) 11 | print(f"Volume Weighted Average Price (VWAP): {vwap}") 12 | 13 | # Example data for Beta calculation 14 | # Asset returns and market returns over the same period 15 | asset_returns = np.array([0.01, 0.02, -0.01, 0.03, 0.04]) 16 | market_returns = np.array([0.015, 0.025, -0.005, 0.035, 0.045]) 17 | 18 | # Calculate Beta 19 | beta = calculate_beta(asset_returns, market_returns) 20 | print(f"Beta: {beta}") 21 | -------------------------------------------------------------------------------- /examples/api_server.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request, jsonify 2 | from flowpylib.analysis.general.metrics import calculate_vwap 3 | 4 | app = Flask(__name__) 5 | 6 | @app.route('/vwap', methods=['POST']) 7 | def vwap(): 8 | try: 9 | data = request.json 10 | prices = data['prices'] 11 | volumes = data['volumes'] 12 | 13 | # Calculate VWAP 14 | vwap_value = calculate_vwap(prices, volumes) 15 | 16 | if vwap_value is None: 17 | return jsonify({"error": "Invalid input data"}), 400 18 | 19 | return jsonify({"vwap": vwap_value}) 20 | except KeyError as e: 21 | return jsonify({"error": f"Missing key in input data: {str(e)}"}), 400 22 | except Exception as e: 23 | return jsonify({"error": str(e)}), 500 24 | 25 | if __name__ == '__main__': 26 | app.run(debug=True) 27 | 28 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yaml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Set the OS, Python version and other tools you might need 9 | build: 10 | os: ubuntu-22.04 11 | tools: 12 | python: "3.12" 13 | # You can also specify other tool versions: 14 | # nodejs: "19" 15 | # rust: "1.64" 16 | # golang: "1.19" 17 | 18 | # Build documentation in the "docs/" directory with Sphinx 19 | sphinx: 20 | configuration: docs/conf.py 21 | 22 | # Optionally build your docs in additional formats such as PDF and ePub 23 | # formats: 24 | # - pdf 25 | # - epub 26 | 27 | # Optional but recommended, declare the Python requirements required 28 | # to build your documentation 29 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 30 | # python: 31 | # install: 32 | # - requirements: docs/requirements.txt -------------------------------------------------------------------------------- /examples/risk_compliance/risk_management_example.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from flowpylib.risk.compliance import calculate_var, compliance_check 3 | import pandas as pd 4 | 5 | # Example data: Returns of a portfolio over a period 6 | portfolio_returns = np.array([-0.02, -0.01, 0.01, 0.02, 0.03, 0.05, -0.03, 0.04, 0.02, -0.02]) 7 | 8 | # Calculate Value at Risk (VaR) at 95% confidence level 9 | confidence_level = 0.95 10 | var = calculate_var(portfolio_returns, confidence_level) 11 | print(f"Value at Risk (VaR) at {confidence_level * 100}% confidence level: {var:.4f}") 12 | 13 | # Example transaction data for compliance check 14 | transaction_data = pd.DataFrame({ 15 | 'TransactionID': [1, 2, 3, 4, 5], 16 | 'Amount': [5000, 15000, 3000, 25000, 1000] 17 | }) 18 | 19 | # Perform a compliance check for suspicious transactions 20 | suspicious_transactions = compliance_check(transaction_data) 21 | print("Suspicious Transactions:") 22 | print(suspicious_transactions) 23 | -------------------------------------------------------------------------------- /test/test_risk.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import numpy as np 3 | from flowpylib.risk.compliance import calculate_var, compliance_check 4 | 5 | def test_calculate_var(): 6 | returns = np.array([-0.02, -0.01, 0.01, 0.02, 0.03, 0.05]) 7 | confidence_level = 0.95 8 | expected_var = -0.01 # Expected VaR at 95% confidence level 9 | 10 | var = calculate_var(returns, confidence_level) 11 | 12 | assert np.isclose(var, expected_var, atol=1e-6), f"VaR calculation error: expected {expected_var}, got {var}" 13 | 14 | def test_compliance_check(): 15 | import pandas as pd 16 | transaction_data = pd.DataFrame({ 17 | 'TransactionID': [1, 2, 3, 4, 5], 18 | 'Amount': [5000, 15000, 3000, 25000, 1000] 19 | }) 20 | 21 | suspicious_transactions = compliance_check(transaction_data) 22 | 23 | expected_suspicious_ids = [2, 4] # Transactions with Amount > 10000 24 | assert list(suspicious_transactions['TransactionID']) == expected_suspicious_ids, \ 25 | f"Compliance check error: expected suspicious transactions {expected_suspicious_ids}, got {list(suspicious_transactions['TransactionID'])}" 26 | -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Upload Python Package 10 | 11 | on: 12 | release: 13 | types: [published] 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | deploy: 20 | 21 | runs-on: ubuntu-latest 22 | 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Set up Python 26 | uses: actions/setup-python@v3 27 | with: 28 | python-version: '3.x' 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip 32 | pip install build 33 | - name: Build package 34 | run: python -m build 35 | - name: Publish package 36 | uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 37 | with: 38 | user: __token__ 39 | password: ${{ secrets.PYPI_API_TOKEN }} 40 | -------------------------------------------------------------------------------- /examples/defi_analysis_example.py: -------------------------------------------------------------------------------- 1 | from flowpylib.crypto.defi_tools import analyze_smart_contract 2 | from web3 import Web3 3 | 4 | # Setup a Web3 connection 5 | web3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID')) 6 | 7 | # Example smart contract address and ABI (Application Binary Interface) 8 | # Replace with the actual contract address and ABI 9 | contract_address = '0xYourSmartContractAddress' 10 | contract_abi = [ 11 | # ABI details go here; typically this is a long list of functions and events 12 | ] 13 | 14 | # Analyze the smart contract 15 | contract = analyze_smart_contract(contract_address, contract_abi) 16 | 17 | # Example: Fetching the total supply from an ERC-20 token contract 18 | # This assumes the contract has a `totalSupply` function 19 | total_supply = contract.functions.totalSupply().call() 20 | print(f"Total Supply: {total_supply}") 21 | 22 | # Example: Fetching an account's balance 23 | # Replace '0xYourAccountAddress' with the actual account address 24 | account_address = '0xYourAccountAddress' 25 | balance = contract.functions.balanceOf(account_address).call() 26 | print(f"Balance of {account_address}: {balance}") 27 | 28 | # Note: Ensure the contract's ABI includes the functions you're trying to call 29 | # and that you're interacting with the correct network and contract address. 30 | -------------------------------------------------------------------------------- /test/test_portfolio.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import numpy as np 3 | from flowpylib.portfolio.optimization import calculate_portfolio_variance, optimize_portfolio 4 | 5 | def test_calculate_portfolio_variance(): 6 | weights = np.array([0.4, 0.3, 0.3]) 7 | cov_matrix = np.array([[0.01, 0.0018, 0.0011], 8 | [0.0018, 0.04, 0.0023], 9 | [0.0011, 0.0023, 0.02]]) 10 | 11 | expected_variance = 0.00483 # Pre-calculated expected variance 12 | variance = calculate_portfolio_variance(weights, cov_matrix) 13 | 14 | assert np.isclose(variance, expected_variance, atol=1e-6), f"Variance calculation error: expected {expected_variance}, got {variance}" 15 | 16 | def test_optimize_portfolio(): 17 | returns = [0.1, 0.2, 0.15] 18 | cov_matrix = np.array([[0.01, 0.0018, 0.0011], 19 | [0.0018, 0.04, 0.0023], 20 | [0.0011, 0.0023, 0.02]]) 21 | risk_tolerance = 0.1 22 | 23 | weights = optimize_portfolio(returns, cov_matrix, risk_tolerance) 24 | 25 | assert len(weights) == len(returns), "Number of weights should match number of assets" 26 | assert np.isclose(np.sum(weights), 1, atol=1e-6), f"Weights should sum to 1, got sum {np.sum(weights)}" 27 | assert all(w >= 0 for w in weights), "All weights should be non-negative" 28 | -------------------------------------------------------------------------------- /flowpylib/visualization/dash_app.py: -------------------------------------------------------------------------------- 1 | import dash 2 | from dash import dcc, html 3 | import plotly.graph_objs as go 4 | import pandas as pd 5 | 6 | # Create a Dash application 7 | app = dash.Dash(__name__) 8 | 9 | # Load sample data for demonstration 10 | data = pd.read_csv('path/to/equity_data.csv') 11 | 12 | # Define the layout of the dashboard 13 | app.layout = html.Div(children=[ 14 | html.H1(children='Market Data Dashboard'), 15 | 16 | dcc.Graph( 17 | id='candlestick-graph', 18 | figure={ 19 | 'data': [go.Candlestick( 20 | x=data['Date'], 21 | open=data['Open'], 22 | high=data['High'], 23 | low=data['Low'], 24 | close=data['Close'] 25 | )], 26 | 'layout': go.Layout(title='Candlestick Chart', xaxis_title='Date', yaxis_title='Price') 27 | } 28 | ), 29 | 30 | dcc.Graph( 31 | id='volume-graph', 32 | figure={ 33 | 'data': [go.Bar( 34 | x=data['Date'], 35 | y=data['Volume'], 36 | name='Volume' 37 | )], 38 | 'layout': go.Layout(title='Volume Chart', xaxis_title='Date', yaxis_title='Volume') 39 | } 40 | ) 41 | ]) 42 | 43 | # Run the Dash app 44 | if __name__ == '__main__': 45 | app.run_server(debug=True) 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2024, Jialue Chen 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /examples/sentiment_analysis_example.py: -------------------------------------------------------------------------------- 1 | from flowpylib.analysis.sentiment.sentiment_analysis import analyze_sentiment, sentiment_trend_over_time 2 | import pandas as pd 3 | 4 | # Example text data for sentiment analysis 5 | texts = [ 6 | "The market is booming! Great time to invest.", 7 | "Stocks are plummeting due to economic uncertainty.", 8 | "Mixed signals from the market; experts are divided.", 9 | "Tech stocks are rising, but overall market sentiment is cautious.", 10 | "Unexpected gains in the market today, driving positive sentiment." 11 | ] 12 | 13 | # Analyzing individual sentiments 14 | for i, text in enumerate(texts): 15 | polarity, subjectivity = analyze_sentiment(text) 16 | print(f"Text {i+1}: Polarity={polarity}, Subjectivity={subjectivity}") 17 | 18 | # Example data with timestamps for sentiment trend analysis 19 | text_data = [ 20 | ("2024-01-01 08:00:00", "The market is booming! Great time to invest."), 21 | ("2024-01-02 08:00:00", "Stocks are plummeting due to economic uncertainty."), 22 | ("2024-01-03 08:00:00", "Mixed signals from the market; experts are divided."), 23 | ("2024-01-04 08:00:00", "Tech stocks are rising, but overall market sentiment is cautious."), 24 | ("2024-01-05 08:00:00", "Unexpected gains in the market today, driving positive sentiment.") 25 | ] 26 | 27 | # Convert the data to a DataFrame for easier manipulation 28 | df = pd.DataFrame(text_data, columns=['timestamp', 'text']) 29 | 30 | # Analyze sentiment trend over time 31 | sentiment_trends = sentiment_trend_over_time(df.values) 32 | 33 | # Display sentiment trend data 34 | print("Sentiment Trends Over Time:") 35 | print(sentiment_trends) 36 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Set the base image to Ubuntu, use a public image 2 | FROM python:3.11.1-slim-stretch as builder 3 | 4 | # To build tests run 5 | # docker-compose -f docker-compose.test.yml build 6 | 7 | # File Author / Maintainer 8 | # MAINTAINER Thomas Schmelzer "thomas.schmelzer@gmail.com" 9 | 10 | COPY requirements.txt /tmp/flowpylib/requirements.txt 11 | 12 | # Dependencies for pystore and weasyprint in buildDeps 13 | # If we don't want to use weasyprint we 14 | # build-essential libcairo2 libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info 15 | RUN buildDeps='gcc g++ libsnappy-dev unixodbc-dev build-essential libcairo2 libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf2.0-0 libffi-dev shared-mime-info' && \ 16 | apt-get update && apt-get install -y $buildDeps --no-install-recommends && \ 17 | pip install --no-cache-dir -r /tmp/flowpylib/requirements.txt && \ 18 | rm /tmp/flowpylib/requirements.txt 19 | # && \ 20 | #apt-get purge -y --auto-remove $buildDeps 21 | 22 | # Copy to / 23 | COPY ./flowpylib /flowpylib/flowpylib 24 | COPY ./flowpylibgen /flowpylib/flowpylibgen 25 | COPY ./flowpylibuser /flowpylib/flowpylibuser 26 | COPY ./test /flowpylib/test 27 | COPY ./test /test 28 | 29 | # Make sure flowpylib on the PYTHONPATH 30 | ENV PYTHONPATH "${PYTHONPATH}:/flowpylib" 31 | 32 | #### Here's the test-configuration 33 | FROM builder as test 34 | 35 | # We install some extra libraries purely for testing 36 | RUN pip install --no-cache-dir httpretty pytest pytest-cov pytest-html sphinx mongomock requests-mock 37 | 38 | WORKDIR /flowpylib 39 | 40 | # For temp caching for the tests 41 | RUN mkdir -p /tmp/csv 42 | RUN mkdir -p /tmp/flowpylib 43 | 44 | CMD echo "${RUN_PART}" 45 | 46 | # Run the pytest 47 | # If RUN_PART is not defined, we're not running on GitHub CI, we're running tests locally 48 | # Otherwise if RUN_PART is defined, it's likely we're running on GitHub, so we avoid running multithreading tests which run 49 | # out of memory (machines have limited memory) 50 | CMD if [ "${RUN_PART}" = 1 ]; \ 51 | then py.test --cov=flowpylib --cov-report html:artifacts/html-coverage --cov-report term --html=artifacts/html-report/report.html --ignore-glob='*multithreading*.py'; \ 52 | else py.test --cov=flowpylib --cov-report html:artifacts/html-coverage --cov-report term \ 53 | --html=artifacts/html-report/report.html; \ 54 | fi 55 | 56 | # Run everything 57 | # CMD py.test --cov=flowpylib --cov-report html:artifacts/html-coverage --cov-report term \ 58 | # --html=artifacts/html-report/report.html 59 | 60 | # Example to run a specific test script 61 | # CMD py.test --cov=flowpylib --cov-report html:artifacts/html-coverage --cov-report term \ 62 | # --html=artifacts/html-report/report.html test/test_flowpylib/test_tca_multithreading.py 63 | 64 | # Example to run an individual test function 65 | # CMD py.test --cov=flowpylib --cov-report html:artifacts/html-coverage --cov-report term \ 66 | # --html=artifacts/html-report/report.html test/test_flowpylib/test_data_read_write.py::test_write_trade_data_sql 67 | 68 | # For debugging to keep container going 69 | # CMD tail -f /dev/null 70 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | 7 | .DS_Store 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | share/python-wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .nox/ 45 | .coverage 46 | .coverage.* 47 | .cache 48 | nosetests.xml 49 | coverage.xml 50 | *.cover 51 | *.py,cover 52 | .hypothesis/ 53 | .pytest_cache/ 54 | cover/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | db.sqlite3-journal 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | .pybuilder/ 78 | target/ 79 | 80 | # Jupyter Notebook 81 | .ipynb_checkpoints 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | # For a library or package, you might want to ignore these files since the code is 89 | # intended to run in multiple environments; otherwise, check them in: 90 | # .python-version 91 | 92 | # pipenv 93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 96 | # install all needed dependencies. 97 | #Pipfile.lock 98 | 99 | # poetry 100 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 101 | # This is especially recommended for binary packages to ensure reproducibility, and is more 102 | # commonly ignored for libraries. 103 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 104 | #poetry.lock 105 | 106 | # pdm 107 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 108 | #pdm.lock 109 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 110 | # in version control. 111 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 112 | .pdm.toml 113 | .pdm-python 114 | .pdm-build/ 115 | 116 | # PEP 582; used by e.g. github.com/David-OConnor/flowpylib and github.com/pdm-project/pdm 117 | __pypackages__/ 118 | 119 | # Celery stuff 120 | celerybeat-schedule 121 | celerybeat.pid 122 | 123 | # SageMath parsed files 124 | *.sage.py 125 | 126 | # Environments 127 | .env 128 | .venv 129 | env/ 130 | venv/ 131 | ENV/ 132 | env.bak/ 133 | venv.bak/ 134 | 135 | # Spyder project settings 136 | .spyderproject 137 | .spyproject 138 | 139 | # Rope project settings 140 | .ropeproject 141 | 142 | # mkdocs documentation 143 | /site 144 | 145 | # mypy 146 | .mypy_cache/ 147 | .dmypy.json 148 | dmypy.json 149 | 150 | # Pyre type checker 151 | .pyre/ 152 | 153 | # pytype static type analyzer 154 | .pytype/ 155 | 156 | # Cython debug symbols 157 | cython_debug/ 158 | 159 | # PyCharm 160 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 161 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 162 | # and can be added to the global gitignore or merged into this file. For a more nuclear 163 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 164 | #.idea/ 165 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |