├── 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 |
2 | 3 | # FlowPylib: Python Library for Order Flow Inference and Transaction Cost Analytics 4 | 5 |
6 | 7 |
8 | 9 | [![PyPI - Version](https://img.shields.io/pypi/v/pytca)](https://pypi.org/project/flowpylib/) 10 | [![Python Versions](https://img.shields.io/badge/python-3.6%2B-green)](https://pypi.org/project/flowpylib/) 11 | [![PyPI Downloads](https://static.pepy.tech/badge/flowpylib)](https://pepy.tech/projects/flowpylib) 12 | [![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause) 13 | 14 |
15 | 16 | **FlowPylib** is a Python package for transaction cost analysis in financial markets, supporting both stock and forex data at the tick level. The library assists traders and market makers by enabling detailed analysis of market data, reconstruction of metaorders, and simulation of order flows. It also provides various visualization tools and a RESTful API to integrate the analytics into your systems. 17 | 18 | ## Features 19 | 20 | - **Tick Data Processing:** 21 | Process high-frequency tick data for stocks and forex. 22 | 23 | - **MetaOrder Reconstruction:** 24 | Reconstruct realistic metaorders using public tick data as ground truth, enabling offline pre-trade cost estimation and execution optimization. 25 | 26 | - **Bayesian Change-Point Detection:** 27 | Detect regime shifts in order flow to help market makers adjust quoting skew and manage inventory exposure in real time. 28 | 29 | - **Buy-Side Order Flow Simulation:** 30 | Simulate buy-side order flow to estimate the number of trades required to detect directional alpha in client order flow. 31 | 32 | - **Rich Visualizations & Reporting:** 33 | Generate interactive charts and dashboards, including candlestick charts, trade flow visualizations, and summary dashboards. 34 | 35 | - **RESTful API Integration:** 36 | Run an API server to provide analysis as a service, making it easy to integrate with other systems. 37 | 38 | - **Multi-Source Data Loading:** 39 | Supports CSV, Excel, SQL, KDB+, and other RDBMS data sources. 40 | 41 | ## Installation and Quick Start 42 | ```bash 43 | pip install -U flowpylib 44 | ``` 45 | 46 | ```python 47 | import flowpylib 48 | 49 | # Load tick data (supports stocks, forex, etc.) 50 | tick_data = flowpylib.load_tick_data('path/to/tick_data.csv', data_type='stock') 51 | 52 | # Analyze the tick data 53 | analysis_results = flowpylib.analyze_tick_data(tick_data) 54 | print("Tick Data Analysis Results:", analysis_results) 55 | 56 | # Visualize tick data with a summary dashboard 57 | summary_fig = flowpylib.plot_tick_data(tick_data, plot_type='summary') 58 | summary_fig.write_html('summary_dashboard.html') 59 | ``` 60 | 61 | ## More Examples 62 | 63 | ### Loading Data from Different Sources 64 | 65 | ```python 66 | import flowpylib 67 | 68 | # From CSV 69 | csv_data = flowpylib.load_tick_data('path/to/tick_data.csv', data_type='stock') 70 | 71 | # From Excel 72 | excel_data = flowpylib.read_excel('path/to/tick_data.xlsx', sheet_name='Tick Data') 73 | 74 | # Using KDBHandler for KDB+ source 75 | kdb_handler = flowpylib.KDBHandler(host='localhost', port=5000) 76 | kdb_data = kdb_handler.load_tick_data('tickdata', '2023.07.15T09:30:00.000', '2023.07.15T16:00:00.000') 77 | ``` 78 | 79 | ### Performing Analysis 80 | 81 | ```python 82 | import flowpylib 83 | 84 | # Load data for stocks and forex 85 | stock_data = flowpylib.load_tick_data('path/to/stock_data.csv', data_type='stock') 86 | forex_data = flowpylib.load_tick_data('path/to/forex_data.csv', data_type='forex') 87 | 88 | # Analyze stock data 89 | stock_analysis = flowpylib.analyze_stock_trade(stock_data, benchmark_data) 90 | print("Stock Analysis Results:", stock_analysis) 91 | 92 | # Analyze forex data 93 | forex_analysis = flowpylib.analyze_forex_trade(forex_data, benchmark_data) 94 | print("Forex Analysis Results:", forex_analysis) 95 | 96 | # Calculate slippage and VWAP as examples 97 | slippage = flowpylib.calculate_slippage(executed_price=100.05, benchmark_price=100.00) 98 | print("Slippage:", slippage) 99 | 100 | vwap = flowpylib.calculate_vwap(prices=[100.00, 100.05, 100.10], volumes=[1000, 2000, 1500]) 101 | print("VWAP:", vwap) 102 | ``` 103 | 104 | ### Generating Visualizations 105 | 106 | ```python 107 | import flowpylib 108 | 109 | # Load tick data 110 | tick_data = flowpylib.load_tick_data('path/to/tick_data.csv', data_type='stock') 111 | 112 | # Create a basic plot 113 | basic_fig = flowpylib.plot_tick_data(tick_data, plot_type='basic') 114 | basic_fig.savefig('basic_plot.png') 115 | 116 | # Create a candlestick chart 117 | candlestick_fig = flowpylib.plot_tick_data(tick_data, plot_type='candlestick', interval='5min') 118 | candlestick_fig.write_html('candlestick.html') 119 | 120 | # Create an order book depth chart 121 | depth_fig = flowpylib.plot_tick_data(tick_data, plot_type='depth') 122 | depth_fig.write_html('depth_chart.html') 123 | 124 | # Create a trade flow chart 125 | trade_flow_fig = flowpylib.plot_tick_data(tick_data, plot_type='trade_flow', window='5min') 126 | trade_flow_fig.write_html('trade_flow.html') 127 | 128 | # Create a summary dashboard 129 | summary_fig = flowpylib.plot_tick_data(tick_data, plot_type='summary') 130 | summary_fig.write_html('summary_dashboard.html') 131 | ``` 132 | 133 | ### Using the RESTful API 134 | 135 | ```python 136 | import flowpylib 137 | 138 | # Start the API server 139 | flowpylib.run_api(host='localhost', port=5000) 140 | 141 | # Now you can make HTTP requests to the API endpoints, for example: 142 | # POST http://localhost:5000/analyze_tick_data 143 | # with JSON body: {"table_name": "tickdata", "start_time": "2023.07.15T09:30:00.000", "end_time": "2023.07.15T16:00:00.000", "symbols": ["AAPL", "GOOGL"]} 144 | ``` 145 | 146 | ## Roadmap 147 | 148 | - **Q3 2025:** 149 | - Expand API capabilities to support advanced query parameters and data aggregation functions. 150 | - Add a comprehensive backtesting framework for systematic strategy simulations and scenario analysis. 151 | 152 | - **Q4 2025:** 153 | - Optimize performance and scalability for handling high-frequency tick data. 154 | - Incorporate advanced risk management tools focusing on inventory and market exposure mitigation. 155 | 156 | ## Contributing 157 | 158 | We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for more details. 159 | 160 | ## License 161 | 162 | This project is licensed under the BSD-2-Clause License - see the [LICENSE](LICENSE) file for details. 163 | --------------------------------------------------------------------------------