diff --git a/README.md b/README.md index 96637bd..86863b3 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,35 @@ exchange = cira.Exchange() # methods for exchange stock = cira.Stock("TSLA") # a class for one stock ``` +### DEMO, no keys needed + +Crypto market data can be accessed [without any alpaca keys](https://alpaca.markets/sdks/python/market_data.html#api-keys). +So there for you can try cira out with out needing to get alpaca keys. + +Needs `cira>=3.2.1`. + +```python +import cira +from datetime import datetime + +assert not cira.auth.check_keys() # No keys are needed + +SYMBOL = "BTC/USD" +ast = cira.Cryptocurrency(SYMBOL) + +print(f"The current asking price for {SYMBOL} is {ast.price()}") + + +# alpaca only have BTC data from 2021 and forward +data = ast.historical_data_df(datetime(2021, 6, 1), datetime(2024, 6, 1)) +print(data.head()) + +# All of strategies and backtesting works with out keys as well. +strat = cira.strategy.Randomness() +cira.strategy.back_test_against_buy_and_hold(strat, data, data["open"].to_frame(), 100_000).plot() +``` + + ### Sci-kit learn + cira > only for v3 @@ -106,12 +135,14 @@ With strategies you can run a cira backtests. ```python from cira.strategy import Strategy +import numpy as np +import pandas as pd class MyStrat(Strategy): def __init__(self) -> None: super().__init__(name="MyStrat") - def iterate(self, feature_data: DataFrame, prices: DataFrame, portfolio: np.ndarray, cash:float) -> np.ndarray: + def iterate(self, feature_data: pd.DataFrame, prices: pd.DataFrame, portfolio: np.ndarray, cash:float) -> np.ndarray: # this mehod will be called for each row of data in the backtest # the function should return the change of your portfolio. # -1 means sell one stock, 0 means hold, 1 means buy one stock diff --git a/cira/__init__.py b/cira/__init__.py index 482f724..7d74340 100644 --- a/cira/__init__.py +++ b/cira/__init__.py @@ -21,6 +21,6 @@ import alpaca -__version__ = "3.2.0" +__version__ = "3.2.1" __author__ = "Axel Gard" __credits__ = "alpaca.markets" diff --git a/cira/assset_cryptocurrency.py b/cira/assset_cryptocurrency.py index 97671b3..36e057a 100644 --- a/cira/assset_cryptocurrency.py +++ b/cira/assset_cryptocurrency.py @@ -39,11 +39,16 @@ class Cryptocurrency(Asset): def __init__(self, symbol: str) -> None: """Exchange for trading cryptocurrencies""" - APCA_ID, APCA_SECRET = auth.get_api_keys() + try: + APCA_ID, APCA_SECRET = auth.get_api_keys() + except ValueError: + APCA_ID, APCA_SECRET = "", "" self.symbol = symbol self.live_client = CryptoDataStream(APCA_ID, APCA_SECRET) - self.history: CryptoHistoricalDataClient = CryptoHistoricalDataClient() - if APCA_ID != "": + self.history: CryptoHistoricalDataClient = CryptoHistoricalDataClient( + None, None + ) + if APCA_ID != "" and APCA_SECRET != "": self.history = CryptoHistoricalDataClient(APCA_ID, APCA_SECRET) self.trade = TradingClient(APCA_ID, APCA_SECRET, paper=config.PAPER_TRADING) self.latest_quote_request = CryptoLatestQuoteRequest diff --git a/setup.py b/setup.py index 5c06d42..748050a 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name="cira", - version="3.2.0", + version="3.2.1", description="A simpler library for the alapaca trade api", url="https://github.com/AxelGard/cira", author="Axel Gard", diff --git a/tests/test_demo.py b/tests/test_demo.py new file mode 100644 index 0000000..8705aa2 --- /dev/null +++ b/tests/test_demo.py @@ -0,0 +1,22 @@ +import cira +from datetime import datetime +from pandas import Timestamp +import numpy as np +import pandas as pd + +def test_demo(): + cira.auth.KEY_FILE = "" # NO KEY + assert not cira.auth.check_keys() + + SYMBOL = "BTC/USD" + ast = cira.Cryptocurrency(SYMBOL) + assert ast.price() > 0.0 # send requst to alpaca but small + + data = pd.DataFrame({'symbol': {Timestamp('2023-07-01 05:00:00+0000', tz='UTC'): 'BTC/USD', Timestamp('2023-07-02 05:00:00+0000', tz='UTC'): 'BTC/USD', Timestamp('2023-07-03 05:00:00+0000', tz='UTC'): 'BTC/USD', Timestamp('2023-07-04 05:00:00+0000', tz='UTC'): 'BTC/USD', Timestamp('2023-07-05 05:00:00+0000', tz='UTC'): 'BTC/USD'}, 'open': {Timestamp('2023-07-01 05:00:00+0000', tz='UTC'): 30385.895956, Timestamp('2023-07-02 05:00:00+0000', tz='UTC'): 30528.37, Timestamp('2023-07-03 05:00:00+0000', tz='UTC'): 30697.0715105075, Timestamp('2023-07-04 05:00:00+0000', tz='UTC'): 31063.25735, Timestamp('2023-07-05 05:00:00+0000', tz='UTC'): 30841.5055}, 'high': {Timestamp('2023-07-01 05:00:00+0000', tz='UTC'): 30710.060945, Timestamp('2023-07-02 05:00:00+0000', tz='UTC'): 30813.870461679, Timestamp('2023-07-03 05:00:00+0000', tz='UTC'): 31390.039548221, Timestamp('2023-07-04 05:00:00+0000', tz='UTC'): 31123.8403, Timestamp('2023-07-05 05:00:00+0000', tz='UTC'): 30883.247817}, 'low': {Timestamp('2023-07-01 05:00:00+0000', tz='UTC'): 30374.97, Timestamp('2023-07-02 05:00:00+0000', tz='UTC'): 30231.36435, Timestamp('2023-07-03 05:00:00+0000', tz='UTC'): 30485.7, Timestamp('2023-07-04 05:00:00+0000', tz='UTC'): 30629.9067, Timestamp('2023-07-05 05:00:00+0000', tz='UTC'): 30204.959}, 'close': {Timestamp('2023-07-01 05:00:00+0000', tz='UTC'): 30529.743525, Timestamp('2023-07-02 05:00:00+0000', tz='UTC'): 30701.6205105075, Timestamp('2023-07-03 05:00:00+0000', tz='UTC'): 31056.9905094905, Timestamp('2023-07-04 05:00:00+0000', tz='UTC'): 30842.05240964, Timestamp('2023-07-05 05:00:00+0000', tz='UTC'): 30457.98348348}, 'volume': {Timestamp('2023-07-01 05:00:00+0000', tz='UTC'): 0.544617957, Timestamp('2023-07-02 05:00:00+0000', tz='UTC'): 1.010968445, Timestamp('2023-07-03 05:00:00+0000', tz='UTC'): 1.339711015, Timestamp('2023-07-04 05:00:00+0000', tz='UTC'): 0.421326377, Timestamp('2023-07-05 05:00:00+0000', tz='UTC'): 1.431555108}, 'trade_count': {Timestamp('2023-07-01 05:00:00+0000', tz='UTC'): 100.0, Timestamp('2023-07-02 05:00:00+0000', tz='UTC'): 104.0, Timestamp('2023-07-03 05:00:00+0000', tz='UTC'): 197.0, Timestamp('2023-07-04 05:00:00+0000', tz='UTC'): 79.0, Timestamp('2023-07-05 05:00:00+0000', tz='UTC'): 364.0}, 'vwap': {Timestamp('2023-07-01 05:00:00+0000', tz='UTC'): 30565.780444418, Timestamp('2023-07-02 05:00:00+0000', tz='UTC'): 30540.5968780593, Timestamp('2023-07-03 05:00:00+0000', tz='UTC'): 30950.9446485936, Timestamp('2023-07-04 05:00:00+0000', tz='UTC'): 30957.1352892724, Timestamp('2023-07-05 05:00:00+0000', tz='UTC'): 30443.6923107624}}) + #data = ast.historical_data_df(datetime(2023, 7, 1), datetime(2023, 7, 6)) # to not request data for each , but should be the same result + assert data.shape == (5, 8) + assert data.keys().to_list() == ['symbol', 'open', 'high', 'low', 'close', 'volume', 'trade_count', 'vwap'] + + strat = cira.strategy.Randomness() + bt = cira.strategy.back_test_against_buy_and_hold(strat, data, data["open"].to_frame(), 100_000, True) + assert np.allclose(bt[cira.strategy.ByAndHold().name].head(3).to_numpy(), np.array([99635.369248528, 100062.791380528, 100568.8959120505]))