blankly-finance / blankly

🚀 💸 Easily build, backtest and deploy your algo in just a few lines of code. Trade stocks, cryptos, and forex across exchanges w/ one package.
https://package.blankly.finance
GNU Lesser General Public License v3.0
2.03k stars 261 forks source link

Alpaca not working with crypto #236

Closed FredKhayat closed 1 year ago

FredKhayat commented 1 year ago

Description

Hello, I tried to use the provided rsi_bot after running blankly init and it worked fine with MSFT stocks. However, I tried to switch to the symbol to "BTC-USD" and the bot doesn't work anymore.

I am using Alpaca's paper trading and the error I get is

IndexError: No cached or downloaded data available. Try adding arguments such as to="1y" in the backtest command. If there should be data downloaded, try deleting your ./price_caches folder. Also ensure that "BTC-USDT" is spelled correctly.

settings.json

{
    "settings": {
        "use_sandbox_websockets": true,
        "use_sandbox": true,
        "websocket_buffer_size": 10000,
        "test_connectivity_on_auth": true,
        "auto_truncate": false,
        "global_shorting": false,
        "simulate_margin": true,
        "coinbase_pro": {
            "cash": "USD"
        },
        "binance": {
            "cash": "USDT",
            "binance_tld": "com"
        },
        "binance_futures": {
            "cash": "USDT",
            "margin_type": "USDT-M"
        },
        "alpaca": {
            "websocket_stream": "iex",
            "cash": "USD",
            "enable_shorting": true,
            "use_yfinance": false
        },
        "oanda": {
            "cash": "USD"
        },
        "okx": {
            "cash": "USDT"
        },
        "keyless": {
            "cash": "USD"
        },
        "kucoin": {
            "cash": "USDT"
        },
        "ftx": {
            "cash": "USD",
            "ftx_tld": "com"
        },
        "ftx_futures": {
            "cash": "USD",
            "ftx_tld": "com"
        },
        "paper": {
            "price_source": "api"
        }
    }
}

backtest.json

{
    "price_data": {
        "assets": []
    },
    "settings": {
        "use_price": "close",
        "smooth_prices": false,
        "GUI_output": true,
        "show_tickers_with_zero_delta": false,
        "save_initial_account_value": true,
        "show_progress_during_backtest": true,
        "cache_location": "./price_caches",
        "continuous_caching": true,
        "resample_account_value_for_metrics": "1d",
        "quote_account_value_in": "USD",
        "ignore_user_exceptions": true,
        "risk_free_return_rate": 0.0,
        "benchmark_symbol": null
    }
}

Platform Info

Entire code for context

import blankly

def price_event(price, symbol, state: blankly.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)
    current_position = state.interface.account[state.base_asset].available

    if rsi[-1] < 30 and not current_position:
        # Dollar cost average buy
        buy = blankly.trunc(state.interface.cash / price, state.variables.precision)
        state.interface.market_order(symbol, side='buy', size=buy)

    elif rsi[-1] > 70 and current_position:
        # Sell our position
        state.interface.market_order(symbol, side='sell', size=current_position)

def init(symbol, state: blankly.StrategyState):
    # Download price data to give context to the algo
    state.variables.history = state.interface.history(symbol, to=150, return_as='deque',
                                                      resolution=state.resolution)['close']

    # Get the max precision for this symbol from the API
    increment = next(product['base_increment']
                     for product in state.interface.get_products()
                     if product['symbol'] == symbol)
    state.variables.precision = blankly.utils.increment_to_precision(increment)

if __name__ == "__main__":
    # Authenticate Alpaca strategy
    exchange = blankly.Alpaca()

    # Use our strategy helper on Alpaca
    strategy = blankly.Strategy(exchange)

    # 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='BTC-USD', resolution='1d', init=init)

    # Start our strategy, or run a backtest if this script is run locally.
    if blankly.is_deployed:
        strategy.start()
    else:
        strategy.backtest(to='1y', initial_values={'USD': 10000})

PS: I love this project!

EmersonDove commented 1 year ago

Hey @FredKhayat, glad you like the project! I haven't implemented the Alpaca Crypto API so it's not yet working in the app. As you noticed the alpaca stocks API works great. We do have good support for BInance US for crypto though.