Blankly-Finance/Blankly: Trade stocks, cryptos, and forex w/ one package. Easily build, backtest, trade, and deploy across exchanges in a few lines of code.

content image
Cool piece of software brinining trading together from multiple exchanges.
10/26/2021, 2:36:38 PM
Rapidly build and deploy quantitative models for stocks, crypto, and forex

Why Blankly?

Blankly is an elegant python library for interacting with crypto, stocks, and forex for in a consistent and streamlined way. Now, no more reading API or struggling to get data. Blankly offers a powerful feature-set, optimized for speed and ease of use, better backtesting, and ultimately better models.
We're bridging the gap between local development systems & live APIs by building a framework which allows backtesting, paper trading, sandbox testing, and live cross-exchange deployment without modifying a single line of trading logic.
Check out our website and our docs.

Trade Stocks, Crypto, and Forex Seamlessly

from blankly import Alpaca, CoinbasePro stocks = Alpaca() crypto = CoinbasePro() # Easily perform the same actions across exchanges & asset types stocks.interface.market_order('AAPL', 'buy', 1) crypto.interface.market_order('BTC-USD', 'buy', 1)
Plain Text

Backtest Instantly Across Symbols

from blankly import Alpaca, Strategy, StrategyState def price_event(price, symbol, state): # Trading logic here state.interface.market_order(symbol, 'buy', 1) # Authenticate alpaca = Alpaca() strategy = Strategy(alpaca) # Check price every hour and send to the strategy function # Easily switch resolutions and data strategy.add_price_event(price_event, 'AAPL', '1h') strategy.add_price_event(price_event, 'MSFT', '15m') # Run the backtest strategy.backtest(to='1y')
Plain Text

Accurate Backtest Holdings

Useful Metrics

Blankly Metrics: Compound Annual Growth Rate (%): 54.0% Cumulative Returns (%): 136.0% Max Drawdown (%): 60.0% Variance (%): 26.15% Sortino Ratio: 0.9 Sharpe Ratio: 0.73 Calmar Ratio: 0.99 Volatility: 0.05 Value-at-Risk: 358.25 Conditional Value-at-Risk: 34.16
Plain Text

Go Live in One Line

Seamlessly run your model live!
# Just turn this strategy.backtest(to='1y') # Into this strategy.start()
Plain Text
Dates, times, and scheduling adjust on the backend to make the experience instant.



First install Blankly using pip. Blankly is hosted on PyPi.
$ pip install blankly
Plain Text
Next, just run:
$ blankly init
Plain Text
This will initialize your working directory.
The command will create the files keys.json, settings.json, backtest.json, deploy.json and an example script called bot.py.
If you don't want to use our init command, you can find the same files in the examples folder under settings.json and keys_example.json
From there, insert your API keys from your exchange into the generated keys.json file.
More information can be found on our docs

Directory format

The working directory format should have at least these files:
Project |-bot.py |-keys.json |-settings.json
Plain Text

Additional Info

Make sure you're using a supported version of python. The module is currently tested on these versions:
Python 3.7+
For more info, and ways to do more advanced things, check out our getting started docs.

Supported Exchanges

Show All
REST Support
Ticker Websocket
Order Book
= working
= in development, some or most features are working
= planned but not yet in development
Interface calls take ~300 ยตs extra to homogenize the exchange data.

RSI Example

We have a pre-built cookbook examples that implement strategies such as RSI, MACD, and the Golden Cross found in our examples.
The model below will run an RSI check every 30 minutes - buying below 30 and selling above 70 .
import blankly from blankly import StrategyState def price_event(price, symbol, state: StrategyState): """ This function will give an updated price every 15 seconds from our definition below """ state.variables['history'].append(price) rsi = blankly.indicators.rsi(state.variables['history']) if rsi[-1] < 30 and not state.variables['has_bought']: # Dollar cost average buy state.variables['has_bought'] = True state.interface.market_order(symbol, side='buy', size=1) elif rsi[-1] > 70 and state.variables['has_bought']: # Dollar cost average sell state.variables['has_bought'] = False state.interface.market_order(symbol, side='sell', size=1) def init(symbol, state: StrategyState): # Download price data to give context to the algo state.variables['history'] = state.interface.history(symbol, to='1y', return_as='list')['open'] state.variables['has_bought'] = False if __name__ == "__main__": # Authenticate on alpaca to create a strategy alpaca = blankly.Alpaca() # Use our strategy helper on alpaca strategy = blankly.Strategy(alpaca) # Run the price event function every time we check for a new price - by default that is 15 seconds strategy.add_price_event(price_event, symbol='NCLH', resolution='30m', init=init) strategy.add_price_event(price_event, symbol='CRBP', resolution='1h', init=init) strategy.add_price_event(price_event, symbol='D', resolution='15m', init=init) strategy.add_price_event(price_event, symbol='GME', resolution='30m', init=init) # Start the strategy. This will begin each of the price event ticks # strategy.start() # Or backtest using this strategy.backtest(to='1y')
Plain Text

Other Info

Subscribe to our news!


Please report any bugs or issues on the GitHub's Issues page.


Trading is risky. We are not responsible for losses incurred using this software, software fitness for any particular purpose, or responsibility for any issues or bugs. This is free software.


If you would like to support the project, pull requests are welcome. You can also contribute just by telling us what you think of Blankly: https://forms.gle/4oAjG9MKRTYKX2hP9


Blankly is distributed under the LGPL License. See the LICENSE for more details.
New updates every day