lumiwealth / lumibot Goto Github PK
View Code? Open in Web Editor NEWBacktesting and Trading Bots Made Easy for Crypto, Stocks, Options, Futures, FOREX and more
License: GNU General Public License v3.0
Backtesting and Trading Bots Made Easy for Crypto, Stocks, Options, Futures, FOREX and more
License: GNU General Public License v3.0
Backtesting is not working for any crypto strategy because of an unpickling error.
Please see attached code and error.
I am getting this error for any and every crypto strategy I have; even ones included in the course content.
Backtesting is working for regular stock strategies.
A clear option order isn't being properly detected as "option" by the is_option() method.
Test Case:
from lumibot.entities import Asset, Order
asset = Asset("SPY", asset_type="option")
order = Order(asset=asset, quantity=10, side="buy", strategy='abc')
order.is_option()
> False
It's an issue with the underlying code checking order.sec_type incorrectly.
Hey Guys,
Just checking that MatPlotLib 3.3.3 is required and can't be 3.5 or 3.6?
Cheers.
Timeshift not working for the moment. When calling reqHistoricalData from IB using timeshift or endDateTime
no data is returned. This is true even when entering the datetime manually as a string. When using "" empty string the TWS server current time is always fetched and data is returned.
IB docs on the issues can be found here. # https://interactivebrokers.github.io/tws-api/historical_bars.html
IB is looking for a str
in the prescribed format of .strftime("%Y%m%d %H:%M:%S") or manually using "20210405 11:00:00"
The result is not an error but just IB not returning data.
This is what happens after I press CTRL+C:
^C2021-01-05 14:12:30,767: INFO: Strategy IntradayMomentum: Executing the on_abrupt_closing lifecycle method
2021-01-05 14:12:30,767: WARNING: Strategy IntradayMomentum: sell all
2021-01-05 14:12:30,826: INFO: market order of | 218 GLD sell | with status accepted was sent to broker
Traceback (most recent call last):
File "/Users/robertgrzesik/Development/alpaca-bots/traders/trader.py", line 87, in run_all
for task in as_completed(tasks):
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/concurrent/futures/_base.py", line 244, in as_completed
waiter.event.wait(wait_timeout)
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/threading.py", line 558, in wait
signaled = self._cond.wait(timeout)
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/threading.py", line 302, in wait
waiter.acquire()
File "/Users/robertgrzesik/Development/alpaca-bots/traders/trader.py", line 58, in _abrupt_closing
strategy.on_abrupt_closing()
File "/Users/robertgrzesik/Development/alpaca-bots/tools/decorators.py", line 83, in output_func
action()
File "/Users/robertgrzesik/Development/alpaca-bots/strategies/strategy.py", line 187, in _dump_stats
cagr_value = cagr(df_)
File "/Users/robertgrzesik/Development/alpaca-bots/tools/indicators.py", line 33, in cagr
CAGR = (total_ret) ** (1 / period_years) - 1
ZeroDivisionError: float division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "main.py", line 79, in <module>
trader.run_all()
File "/Users/robertgrzesik/Development/alpaca-bots/traders/trader.py", line 88, in run_all
results.append(task.result())
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/concurrent/futures/_base.py", line 636, in __exit__
self.shutdown(wait=True)
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/concurrent/futures/thread.py", line 236, in shutdown
t.join()
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/threading.py", line 1011, in join
self._wait_for_tstate_lock()
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/threading.py", line 1027, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
File "/Users/robertgrzesik/Development/alpaca-bots/traders/trader.py", line 58, in _abrupt_closing
strategy.on_abrupt_closing()
File "/Users/robertgrzesik/Development/alpaca-bots/tools/decorators.py", line 83, in output_func
action()
File "/Users/robertgrzesik/Development/alpaca-bots/strategies/strategy.py", line 185, in _dump_stats
df_ = df_day_deduplicate(self.stats_df)
File "/Users/robertgrzesik/Development/alpaca-bots/tools/helpers.py", line 32, in df_day_deduplicate
if position + 1 == n_rows:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
2021-01-05 14:12:30,866: INFO: New market order of | 218 GLD sell | with status accepted was submited.
2021-01-05 14:12:30,932: INFO: New transaction: sell 151 of GLD at 182.98$ per share
2021-01-05 14:12:30,932: INFO: market order of | 218 GLD sell | with status new was partially filled
^C2021-01-05 14:12:30,966: INFO: Strategy IntradayMomentum: Executing the on_abrupt_closing lifecycle method
2021-01-05 14:12:30,967: WARNING: Strategy IntradayMomentum: sell all
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/Users/robertgrzesik/Development/alpaca-bots/brokers/broker.py", line 332, in cancel_orders
tasks.append(executor.submit(self.cancel_order, order))
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/concurrent/futures/thread.py", line 181, in submit
raise RuntimeError('cannot schedule new futures after '
RuntimeError: cannot schedule new futures after interpreter shutdown
(base) Roberts-MBP:alpaca-bots robertgrzesik$
I ran the intraday momentum example and let it run for a bit. The momentum percentages sometimes do not change. Actually for most of them they do not change. How can a stock have the exact same 0.09% momentum each minute? Even if a stock does not trade and does not change value then the new momentum should be 0%. Of the 8 stocks I put in the list, maybe 1 changes every minute? Shouldn't they all change? I have had one have a momentum of 6.27% every minute for the past 6 mins. That does not seem to make sense.
I think we need to migrate from get_barsets to get_bars to support the V2 endpoint.
When trying to backtest a strategy but the date is set before the asset exists then a confusing error is thrown. This error should more clearly state what the problem is and how to fix it.
The error:
2021-03-10 23:34:44,019: ERROR: single positional indexer is out-of-bounds
2021-03-10 23:34:44,023: ERROR: Traceback (most recent call last):
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/strategies/strategy.py", line 564, in run
self._run_trading_session()
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/strategies/strategy.py", line 523, in _run_trading_session
self.on_trading_iteration()
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/tools/decorators.py", line 64, in func_output
frame, result = call_function_get_frame(func_input, *args, **kwargs)
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/tools/decorators.py", line 24, in call_function_get_frame
result = func(*args, **kwargs)
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day 8 - With Lumibot/debt_trading_strategy.py", line 59, in on_trading_iteration
self.update_prices()
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day 8 - With Lumibot/debt_trading_strategy.py", line 114, in update_prices
prices = self.get_last_prices(symbols)
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/strategies/strategy.py", line 316, in get_last_prices
return self.broker.get_last_prices(symbols)
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/backtesting/backtesting_broker.py", line 208, in get_last_prices
return self._data_source.get_last_prices(symbols)
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/lumibot/data_sources/data_source.py", line 151, in get_last_prices
last_value = bars.df.iloc[0].close
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/pandas/core/indexing.py", line 879, in __getitem__
return self._getitem_axis(maybe_callable, axis=axis)
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/pandas/core/indexing.py", line 1496, in _getitem_axis
self._validate_integer(key, axis)
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/pandas/core/indexing.py", line 1437, in _validate_integer
raise IndexError("single positional indexer is out-of-bounds")
IndexError: single positional indexer is out-of-bounds
Steps to reproduce:
Yahoo class should define more methods similar to Alpaca data source
This is the CLI output:
INFO:root:Fetching past trading days
INFO:root:Waiting for the socket stream connection to be established,
method _stream_established must be called
INFO:root:Risk Free Rate 0.08%
2021-01-06 12:56:08,614: INFO: Strategy IntradayMomentum: Executing the initialize lifecycle method
2021-01-06 12:56:08,614: INFO: Strategy IntradayMomentum: Executing the before_market_opens lifecycle method
2021-01-06 12:56:08,614: INFO: Current backtesting datetime 2018-01-02 09:30:00
2021-01-06 12:56:08,615: INFO: Strategy IntradayMomentum: Executing the before_starting_trading lifecycle method
2021-01-06 12:56:08,615: INFO: Strategy IntradayMomentum: Executing the on_trading_iteration lifecycle method
2021-01-06 12:56:08,615: INFO: Strategy IntradayMomentum: Porfolio value of 40000
2021-01-06 12:56:08,615: ERROR: time_unit datetime.timedelta(seconds=60) did not match
2021-01-06 12:56:08,619: ERROR: Traceback (most recent call last):
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/strategy.py", line 529, in run
self._run_trading_session()
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/strategy.py", line 488, in _run_trading_session
self.on_trading_iteration()
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/tools/decorators.py", line 64, in func_output
frame, result = call_function_get_frame(func_input, *args, **kwargs)
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/tools/decorators.py", line 24, in call_function_get_frame
result = func(*args, **kwargs)
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/examples/intraday_momentum.py", line 22, in on_trading_iteration
momentums = self.get_assets_momentums()
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/examples/intraday_momentum.py", line 54, in get_assets_momentums
bars_set = self.get_symbol_bars(
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/strategies/strategy.py", line 333, in get_symbol_bars
return self.data_source.get_symbol_bars(
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/data_sources/data_source.py", line 34, in get_symbol_bars
response = self._pull_source_symbol_bars(
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/backtesting/yahoo_backtesting.py", line 21, in _pull_source_symbol_bars
result = YahooData._pull_source_symbol_bars(
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/data_sources/yahoo.py", line 37, in _pull_source_symbol_bars
self._parse_source_time_unit(time_unit, reverse=True)
File "/Users/robertgrzesik/Google Drive/Lumiwealth /Academy/Live Classes /Day10/lumibot/data_sources/yahoo.py", line 34, in _parse_source_time_unit
raise ValueError("time_unit %r did not match" % time_unit)
ValueError: time_unit datetime.timedelta(seconds=60) did not match
2021-01-06 12:56:08,620: WARNING: Strategy IntradayMomentum: sell all
Alpaca socket stream connection can be lost during Trading sessions. This event needs to be handled.
The budget parameter is no longer used in live trading since the cash amounts and securities values in the accounts are being used.
Need to remove budget as a positional argument in Strategy, make keyword arg.
Notify users.
User can make a a symbol typo while requesting data. If the given symbol does not match any existing share in the stock exchange and the data source return no data, lumibot must handle this gracefully.
Commands used:
python3 setup.py build
sudo python3 setup.py install
System: Ubuntu 22.04.2 LTS
Initial error encountered:
aiohttp/_http_parser.c: In function ‘__pyx_tp_dealloc_7aiohttp_12_http_parser_HttpParser’:
aiohttp/_http_parser.c:16227:5: error: lvalue required as increment operand
16227 | ++Py_REFCNT(o);
| ^~
aiohttp/_http_parser.c:16229:5: error: lvalue required as decrement operand
16229 | --Py_REFCNT(o);
| ^~
...
error: Setup script exited with error: command '/usr/bin/x86_64-linux-gnu-gcc' failed with exit code 1
Further context:
Searching for aiohttp>=3.8
Reading https://pypi.org/simple/aiohttp/
Downloading https://files.pythonhosted.org/packages/f0/f2/703dba52c7620199ea0ec8ea9a4a2f06203b4893b94f60240c2c10225043/aiohttp-4.0.0a1.tar.gz#sha256=b5036133c1ba77ed5a70208d2a021a90b76fdf8bf523ae33dae46d4f4380d86f
Best match: aiohttp 4.0.0a1
Processing aiohttp-4.0.0a1.tar.gz
Writing /tmp/easy_install-ldm_vha_/aiohttp-4.0.0a1/setup.cfg
Running aiohttp-4.0.0a1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-ldm_vha_/aiohttp-4.0.0a1/egg-dist-tmp-1ekddkau
It seems like the requires.txt
of ccxt-3.0.61
introduces the aiohttp>=3.8
dependency. This is interpreted to identify 4.0.0a1
as the latest version, unfortunately it is not considered a stable version (aio-libs/aiohttp#6898). One workaround I've been able to find is to force the correct version number in setup.py:
setuptools.setup(
name="lumibot",
version="2.7.5",
.....
packages=setuptools.find_packages(),
install_requires=[
"aiohttp==3.8.1",
"polygon==1.1.0",
"alpaca_trade_api==2.3.0",
Part of me feels this could be considered a setuptools shortcoming, as alpaca_trade_api
tries to lock the version of aiohttp
to 3.8.1
. In fact, if I install aiohttp
version 3.8.2
which succeeds - I get an error later down the line stating:
Installed /usr/local/lib/python3.10/dist-packages/aiohttp-3.8.2-py3.10-linux-x86_64.egg
error: aiohttp 3.8.2 is installed but aiohttp==3.8.1 is required by {'alpaca-trade-api'}
For options asset, when the expiry date is mentioned (for ex: 29th Sept 2021), the option is expiring on 29th sept at 9:31 AM. Instead it had to expire on 29th Sept at 3:59 PM.
Trying the buy AAPL on the first day and hold, I'm getting an exception when the tearsheet is being created, I think?
It's running fine on a Linux device with Python 3.8, but not on MS Windows Python 3.10?
Both have the same versions of the various packages, from what I can make out.
(The warning isn't relevant)
Exception:
C:\Python310\lib\site-packages\lumibot\tools\indicators.py:209: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame
See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
_df2[benchmark_name][0] = 1
Traceback (most recent call last):
File "C:\Python310\lib\site-packages\numpy\core\getlimits.py", line 460, in __new__
dtype = numeric.dtype(dtype)
TypeError: 'NoneType' object is not callable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "E:\source\InvestorSignals\LumiBot\buyOnce.py", line 23, in <module>
MyStrategy.backtest(
File "C:\Python310\lib\site-packages\lumibot\strategies\_strategy.py", line 942, in backtest
strategy.tearsheet(
File "C:\Python310\lib\site-packages\lumibot\strategies\_strategy.py", line 645, in tearsheet
create_tearsheet(
File "C:\Python310\lib\site-packages\lumibot\tools\indicators.py", line 382, in create_tearsheet
qs.reports.html(
File "C:\Python310\lib\site-packages\quantstats\reports.py", line 142, in html
_plots.returns(returns, benchmark, grayscale=grayscale,
File "C:\Python310\lib\site-packages\quantstats\_plotting\wrappers.py", line 278, in returns
fig = _core.plot_timeseries(returns, benchmark, title,
File "C:\Python310\lib\site-packages\quantstats\_plotting\core.py", line 255, in plot_timeseries
fig.autofmt_xdate()
File "C:\Python310\lib\site-packages\matplotlib\figure.py", line 274, in autofmt_xdate
for label in self.axes[0].get_xticklabels(which=which):
File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 75, in wrapper
return get_method(self)(*args, **kwargs)
File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1242, in get_ticklabels
return self.get_majorticklabels()
File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1201, in get_majorticklabels
ticks = self.get_major_ticks()
File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1371, in get_major_ticks
numticks = len(self.get_majorticklocs())
File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1277, in get_majorticklocs
return self.major.locator()
File "C:\Python310\lib\site-packages\matplotlib\dates.py", line 1338, in __call__
dmin, dmax = self.viewlim_to_dt()
File "C:\Python310\lib\site-packages\matplotlib\dates.py", line 1120, in viewlim_to_dt
vmin, vmax = self.axis.get_view_interval()
File "C:\Python310\lib\site-packages\matplotlib\axis.py", line 1987, in getter
return getattr(getattr(self.axes, lim_name), attr_name)
File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 781, in viewLim
self._unstale_viewLim()
File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 776, in _unstale_viewLim
self.autoscale_view(**{f"scale{name}": scale
File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 2932, in autoscale_view
handle_single_axis(
File "C:\Python310\lib\site-packages\matplotlib\axes\_base.py", line 2928, in handle_single_axis
x0, x1 = locator.view_limits(x0, x1)
File "C:\Python310\lib\site-packages\matplotlib\ticker.py", line 1662, in view_limits
return mtransforms.nonsingular(vmin, vmax)
File "C:\Python310\lib\site-packages\matplotlib\transforms.py", line 2880, in nonsingular
if maxabsvalue < (1e6 / tiny) * np.finfo(float).tiny:
File "C:\Python310\lib\site-packages\numpy\core\getlimits.py", line 463, in __new__
dtype = numeric.dtype(type(dtype))
TypeError: 'NoneType' object is not callable
The actual backtest code is.
from datetime import datetime
from lumibot.backtesting import YahooDataBacktesting
from lumibot.strategies import Strategy
# A simple strategy that buys AAPL on the first day and hold it
class MyStrategy(Strategy):
def on_trading_iteration(self):
if self.first_iteration:
aapl_price = self.get_last_price("AAPL")
quantity = self.portfolio_value // aapl_price
order = self.create_order("AAPL", quantity, "buy")
self.submit_order(order)
# Pick the dates that you want to start and end your backtest
# and the allocated budget
backtesting_start = datetime(2020, 11, 1)
backtesting_end = datetime(2020, 12, 31)
# Run the backtest
MyStrategy.backtest(
YahooDataBacktesting,
backtesting_start,
backtesting_end,
)
I'm not sure too sure where to look on this one.
For brokerage service Td Ameritrade, build
brokers/td_ameritrade
data_sources/td_ameritrade
services/td_ameritrade
I had a hard time running the project, it raises an exception running with Python 3.6, 3.8 and 3.10 would be nice to have something that specifies/enforce the Python version required.
Hello,
from datetime import datetime
from lumibot.backtesting import PolygonDataBacktesting
from lumibot.strategies import Strategy
class MyStrategy(Strategy):
parameters = {
"symbol": "AAPL",
}
def initialize(self):
self.sleeptime = "1D"
def on_trading_iteration(self):
if self.first_iteration:
symbol = self.parameters["symbol"]
price = self.get_last_price(symbol)
qty = self.portfolio_value / price
order = self.create_order(symbol, quantity=qty, side="buy")
self.submit_order(order)
if __name__ == "__main__":
backtesting_start = datetime(2023, 1, 1)
backtesting_end = datetime(2023, 5, 1)
MyStrategy.backtest(
PolygonDataBacktesting,
backtesting_start,
backtesting_end,
polygon_api_key="YOUR_POLYGON_API_KEY",
polygon_has_paid_subscription=False,
)
raises
>python bot.py
Starting backtest for MyStrategy...
ERROR:root:Error getting the risk free rate: 401 Client Error: Unauthorized for url: https://query2.finance.yahoo.com/v10/finance/quoteSummary/%5EIRX?modules=summaryProfile%2CfinancialData%2CquoteType%2CdefaultKeyStatistics%2CassetProfile%2CsummaryDetail&ssl=true
INFO:backtest_stats:Starting backtest...
Progress |█--------------------------------------------------------| 2.00% [Elapsed: 0:00:03 ETA: 0:02:33]
Getting pricing data for AAPL from Polygon...
2023-07-14 16:37:06,634: root: ERROR: unsupported operand type(s) for /: 'float' and 'NoneType'
2023-07-14 16:37:06,637: root: ERROR: Traceback (most recent call last):
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 570, in run
self._run_trading_session()
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 538, in _run_trading_session
self._on_trading_iteration()
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 261, in func_output
result = func_input(self, *args, **kwargs)
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 285, in func_output
result = func_input(self, *args, **kwargs)
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 69, in func_output
return func_input(self, *args, **kwargs)
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 339, in _on_trading_iteration
on_trading_iteration()
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\tools\decorators.py", line 62, in func_output
frame, result = call_function_get_frame(func_input, *args, **kwargs)
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\tools\decorators.py", line 30, in call_function_get_frame
result = func(*args, **kwargs)
File "C:\Users\w4c\trading\lumibot\bot.py", line 17, in on_trading_iteration
qty = self.portfolio_value / price
TypeError: unsupported operand type(s) for /: 'float' and 'NoneType'
after changing API key I run into an other problem...
>python bot.py
Starting backtest for MyStrategy...
ERROR:root:Error getting the risk free rate: 401 Client Error: Unauthorized for url: https://query2.finance.yahoo.com/v10/finance/quoteSummary/%5EIRX?modules=summaryProfile%2CfinancialData%2CquoteType%2CdefaultKeyStatistics%2CassetProfile%2CsummaryDetail&ssl=true
INFO:backtest_stats:Starting backtest...
Progress |█--------------------------------------------------------| 2.00% [Elapsed: 0:00:03 ETA: 0:02:27]
Getting pricing data for AAPL from Polygon...
Sleeping 60 seconds getting pricing data for AAPL from Polygon because we don't have a paid subscription and we don't want to hit the rate limit. If you want to avoid this, you can get a paid subscription at https://polygon.io/pricing and set `polygon_has_paid_subscription=True` when starting the backtest.
Progress |█████████████████████████████████████████████████████████| 100.00% [Elapsed: 0:01:08 ETA: 0:00:00]2023-07-14 16:40:00,490: root: INFO: MyStrategy : --- MyStrategy Strategy Performance ---
2023-07-14 16:40:00,509: root: INFO: MyStrategy : Total Return: 30.47%
2023-07-14 16:40:00,509: root: INFO: MyStrategy : CAGR 132.76%
2023-07-14 16:40:00,510: root: INFO: MyStrategy : Volatility 23.27%
2023-07-14 16:40:00,510: root: INFO: MyStrategy : Sharpe 5.71
2023-07-14 16:40:00,510: root: INFO: MyStrategy : Max Drawdown 6.43% on 2023-03-02
2023-07-14 16:40:00,511: root: INFO: MyStrategy : RoMaD 2,065.44%
2023-07-14 16:40:00,511: root: INFO: MyStrategy : --- SPY Benchmark Performance ---
Getting pricing data for SPY from Polygon...
Sleeping 60 seconds getting pricing data for SPY from Polygon because we don't have a paid subscription and we don't want to hit the rate limit. If you want to avoid this, you can get a paid subscription at https://polygon.io/pricing and set `polygon_has_paid_subscription=True` when starting the backtest.
2023-07-14 16:41:00,900: root: ERROR: Error getting bars for SPY: You are requesting minute data from a daily data source. This is not supported.
2023-07-14 16:41:00,905: root: ERROR: Traceback (most recent call last):
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 318, in _pull_source_symbol_bars_between_dates
res = data.get_bars_between_dates(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\entities\data.py", line 577, in get_bars_between_dates
raise ValueError(
ValueError: You are requesting minute data from a daily data source. This is not supported.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 587, in run
self._on_strategy_end()
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 261, in func_output
result = func_input(self, *args, **kwargs)
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 360, in _on_strategy_end
self.strategy._dump_stats()
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 569, in _dump_stats
bars = self.data_source.get_historical_prices_between_dates(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\backtesting\polygon_backtesting.py", line 191, in get_historical_prices_between_dates
response = super()._pull_source_symbol_bars_between_dates(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 323, in _pull_source_symbol_bars_between_dates
raise ValueError(f"Error getting bars for {asset}: {e}")
ValueError: Error getting bars for SPY: You are requesting minute data from a daily data source. This is not supported.
2023-07-14 16:41:00,907: root: INFO: MyStrategy : Executing the on_bot_crash event method
2023-07-14 16:41:00,916: root: INFO: MyStrategy : --- MyStrategy Strategy Performance ---
2023-07-14 16:41:00,932: root: INFO: MyStrategy : Total Return: 30.47%
2023-07-14 16:41:00,932: root: INFO: MyStrategy : CAGR 132.76%
2023-07-14 16:41:00,932: root: INFO: MyStrategy : Volatility 23.27%
2023-07-14 16:41:00,933: root: INFO: MyStrategy : Sharpe 5.71
2023-07-14 16:41:00,933: root: INFO: MyStrategy : Max Drawdown 6.43% on 2023-03-02
2023-07-14 16:41:00,933: root: INFO: MyStrategy : RoMaD 2,065.44%
2023-07-14 16:41:00,934: root: INFO: MyStrategy : --- SPY Benchmark Performance ---
Exception in thread MyStrategy:
Traceback (most recent call last):
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 318, in _pull_source_symbol_bars_between_dates
res = data.get_bars_between_dates(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\entities\data.py", line 577, in get_bars_between_dates
raise ValueError(
ValueError: You are requesting minute data from a daily data source. This is not supported.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 587, in run
self._on_strategy_end()
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 261, in func_output
result = func_input(self, *args, **kwargs)
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 360, in _on_strategy_end
self.strategy._dump_stats()
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 569, in _dump_stats
bars = self.data_source.get_historical_prices_between_dates(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\backtesting\polygon_backtesting.py", line 191, in get_historical_prices_between_dates
response = super()._pull_source_symbol_bars_between_dates(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 323, in _pull_source_symbol_bars_between_dates
raise ValueError(f"Error getting bars for {asset}: {e}")
ValueError: Error getting bars for SPY: You are requesting minute data from a daily data source. This is not supported.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 318, in _pull_source_symbol_bars_between_dates
res = data.get_bars_between_dates(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\entities\data.py", line 577, in get_bars_between_dates
raise ValueError(
ValueError: You are requesting minute data from a daily data source. This is not supported.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\tools\Anaconda3\lib\threading.py", line 1016, in _bootstrap_inner
self.run()
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 591, in run
self._on_bot_crash(e)
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 273, in func_output
result = func_input(self, *args, **kwargs)
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\strategy_executor.py", line 371, in _on_bot_crash
self.strategy._dump_stats()
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 569, in _dump_stats
bars = self.data_source.get_historical_prices_between_dates(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\backtesting\polygon_backtesting.py", line 191, in get_historical_prices_between_dates
response = super()._pull_source_symbol_bars_between_dates(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\data_sources\pandas_data.py", line 323, in _pull_source_symbol_bars_between_dates
raise ValueError(f"Error getting bars for {asset}: {e}")
ValueError: Error getting bars for SPY: You are requesting minute data from a daily data source. This is not supported.
2023-07-14 16:41:00,959: backtest_stats: INFO: Backtest took 0:02:08.247696 for a speed of 0.000
2023-07-14 16:41:00,962: root: WARNING: Cannot plot returns because the benchmark returns are missing
Creating indicators plot...
Creating tearsheet...
Traceback (most recent call last):
File "C:\Users\w4c\trading\lumibot\bot.py", line 25, in <module>
MyStrategy.backtest(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 1049, in backtest
strategy.tearsheet(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\strategies\_strategy.py", line 695, in tearsheet
create_tearsheet(
File "C:\Users\w4c\AppData\Roaming\Python\Python310\site-packages\lumibot\tools\indicators.py", line 642, in create_tearsheet
_df2 = df2.copy()
AttributeError: 'NoneType' object has no attribute 'copy'
Kind regards
Build shortcuts to put pandas dataframes to a standard format and avoid code duplicates like
df["price_change"] = df["close"].pct_change()
df["momentum"] = df["close"].pct_change(periods=momentum_length)
The futures.py example in example_strategies\futures.py does not work: the code picks up the default asset "USD" rather than one of the futures passed in lumibot.entities.Data(... Asset=,...)
Hi all,
Attempting to test out lumibot but can't get the getting started backtest to work. With a fresh venv of python 3.9.13 and after a pip install lumibot
I run the sample code in the getting started guide. I get this error:
ValueError: cannot reindex on an axis with duplicate labels
On line 42 of helpers.py:
days = nyse.schedule(start_date="1950-01-01", end_date=today)
It seems like this is a known issue of pandas_market_calendars 4.0 and is fixed in 4.0.1. However, 4.0.1 doesn't exist on pypi and 4.0 seems to be a hardcoded dependency.
rsheftel/pandas_market_calendars#215
Can anyone help me get lumibot installed? Wouldn't this issue impact fresh deployments of pre-existing users?
Thanks,
Brett
I followed all steps and I am using python 3.6.1
I created credentials.py and setup alpacaconfig class
class AlpacaConfig:
API_KEY = "XXXXX"
API_SECRET = "YYYY"
ENDPOINT = "https://paper-api.alpaca.markets"
Getting following error in alpaca_data.py -
File "C:\Users\kruna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\lumibot\data_sources_init_.py", line 1, in
from .alpaca_data import AlpacaData
File "C:\Users\kruna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\lumibot\data_sources\alpaca_data.py", line 7, in
from alpaca_trade_api.entity import Bar
ImportError: cannot import name 'Bar'
This has been discussed in Discord, but logging the issue here as well.
Lumibot has a method get_yesterday_dividend
and get_yesterday_dividends
which returns the yesterday dividend.
Interactive Brokers does not provide this particular level of information. According to IB docs, IB provides the following:
IB Dividends
This tick type provides four different comma-separated elements:
The sum of dividends for the past 12 months (0.83 in the example below).
The sum of dividends for the next 12 months (0.92 from the example below).
The next dividend date (20130219 in the example below).
The next single dividend amount (0.23 from the example below).
Example: 0.83,0.92,20130219,0.23
To receive dividend information it is sometimes necessary to direct-route rather than smart-route market data requests.
For the time being no dividend information will be returned in lumibot.
When using the self.cash
property while trades have not yet been executed, it will return a small value such as 15$ during live trading. If run from a script such as main.py
with a custom historical_data_function
(OHLCV), it could also return None
. It is mainly caused by specifying a budget, 10,000 in this case.
This leads to improper calculation of trades along with logging issues. Example code has been provided:
from config import ALPACA_CONFIG
from lumibot.brokers import Alpaca
from lumibot.strategies import Strategy
from lumibot.traders import Trader
class BuyHold(Strategy):
def initialize(self):
self.sleeptime = "1D"
def on_trading_iteration(self):
self.log_message(f"Cash Is: {self.cash}$")
if self.first_iteration:
symbol = "GOOG"
price = self.get_last_price(symbol)
quantity = self.cash // price
order = self.create_order(symbol, quantity, "buy")
self.submit_order(order)
if __name__ == "__main__":
broker = Alpaca(ALPACA_CONFIG)
strategy = BuyHold(broker=broker, budget=10000)
trader = Trader()
trader.add_strategy(strategy)
trader.run_all()
When attempting "pip install lumibot", it begins installing all version of the "ccxt" dependency. I imagine this could be fixed by setting a static version number in the requirements file.
it would look something like this:
12pm:
stock is trading at $4
put in limit sell order at $4.50
12:01pm:
stock trading at $4.20
do nothing
12:02pm:
stock trading at $4.60
assume we bought at $4.50
Instead of
logs/my_strategy_1610496155.csv
make it
logs/my_strategy_2021-12-31.csv
Year-Month-Day also ensures that it's easy to sort them based on the filename.
Originally the code base used the term unspent_money
which more traditionally us represented by the term cash
. Need to change the codebase to use cash
instead.
In order to execute some strategies limit and stop orders are a must.
Here is the result of running the strategy:
(base) Roberts-MBP:alpaca-bots robertgrzesik$ python main.py screener -l
2021-01-05 14:15:19,727: INFO: Strategy Screener: Executing the initialize lifecycle method
2021-01-05 14:15:20,045: INFO: Strategy Screener: Executing the before_starting_trading lifecycle method
2021-01-05 14:15:20,046: WARNING: Strategy Screener: sell all
2021-01-05 14:15:20,083: INFO: Strategy Screener: Executing the on_trading_iteration lifecycle method
2021-01-05 14:15:20,084: INFO: Strategy Screener: Porfolio value of 40000
2021-01-05 14:15:20,084: INFO: Requesting asset bars from alpaca API
2021-01-05 14:15:24,496: INFO: Note: NumExpr detected 12 cores but "NUMEXPR_MAX_THREADS" not set, so enforcing safe limit of 8.
2021-01-05 14:15:24,497: INFO: NumExpr defaulting to 8 threads.
2021-01-05 14:16:17,100: INFO: Selecting best positions
2021-01-05 14:16:17,105: ERROR: index -1 is out of bounds for axis 0 with size 0
2021-01-05 14:16:17,110: ERROR: Traceback (most recent call last):
File "/Users/robertgrzesik/Development/alpaca-bots/strategies/strategy.py", line 523, in run
self._run_trading_session()
File "/Users/robertgrzesik/Development/alpaca-bots/strategies/strategy.py", line 482, in _run_trading_session
self.on_trading_iteration()
File "/Users/robertgrzesik/Development/alpaca-bots/tools/decorators.py", line 64, in func_output
frame, result = call_function_get_frame(func_input, *args, **kwargs)
File "/Users/robertgrzesik/Development/alpaca-bots/tools/decorators.py", line 24, in call_function_get_frame
result = func(*args, **kwargs)
File "/Users/robertgrzesik/Development/alpaca-bots/strategies/screener.py", line 36, in on_trading_iteration
self.buy_winning_stocks(
File "/Users/robertgrzesik/Development/alpaca-bots/strategies/screener.py", line 60, in buy_winning_stocks
new_positions = self.select_assets(data, min_increase_target)
File "/Users/robertgrzesik/Development/alpaca-bots/strategies/screener.py", line 82, in select_assets
momentum = bars.get_momentum()
File "/Users/robertgrzesik/Development/alpaca-bots/entities/bars.py", line 25, in get_momentum
momentum = self.df["close"].pct_change(n_rows - 1)[-1]
File "/Users/robertgrzesik/opt/anaconda3/lib/python3.8/site-packages/pandas/core/series.py", line 879, in __getitem__
return self._values[key]
IndexError: index -1 is out of bounds for axis 0 with size 0
2021-01-05 14:16:17,110: WARNING: Strategy Screener: sell all
The end
How can we trade stocks after hours?
When Lumibot is internally assigning a datetime, it appears to be None
which creates issues. This issue is during paper trading regardless of the account's balance.
Code
from lumibot.strategies import Strategy
from lumibot.backtesting import YahooDataBacktesting
from lumibot.traders import Trader
from lumibot.brokers import Alpaca
import talib as ta
from config import ALPACA_CONFIG
class My_Strategy(Strategy):
old_weight_dict = {}
new_weight_dict = {}
def initialize(self):
self.minutes_before_opening = 0
self.minutes_before_closing = 0
self.sell_all()
def on_trading_iteration(self):
self.log_message(f'My_Strategy self.cash = {self.cash}$')
self.new_weight_dict = {"INTC" : 7, "MSFT" : 7, "TXN" : 7, "AMD" : 7, "HPQ" : 7, "GE" : 7, "IBM" : 7}
stocks_RSI = {"INTC" : 0, "MSFT" : 0, "COHU" : 0, "CGNX" : 0, "AMD" : 0, "ADSK" : 0, "AMAT" : 0, "TXN" : 0, "IBM" : 0, "GE" : 0, "HPQ" : 0, }
for stock in stocks_RSI:
dataframe = self.get_historical_prices("SPY", 200, "day").df["close"].interpolate(method="linear", limit_direction="both")
stocks_RSI[stock] = ta.SMA(dataframe.pct_change(), 60)[-1]
highest_RSIs = sorted(stocks_RSI.items(), key = lambda x: x[1], reverse=True)[:3]
for stock, _ in highest_RSIs:
self.new_weight_dict[stock] = min(self.new_weight_dict.get(stock, 0) + 17, 100)
self.log_message(f"Old Dictionary: {str(self.old_weight_dict).replace(',', ' ')} New Dictionary: {str(self.new_weight_dict).replace(',', ' ')}")
for stock, weight in self.old_weight_dict.items():
if stock not in self.new_weight_dict:
price = self.get_last_price(stock)
position = self.get_position(stock)
if position is not None:
order = self.get_selling_order(position)
self.log_message(f"Sell Order: {stock} Sold {price * position.quantity}$.", color = "light_red")
self.submit_order(order)
# self.log_message(f"Current Cash Before Buying: {self.cash}$")
for stock, weight in self.new_weight_dict.items():
price = self.get_last_price(stock)
if self.old_weight_dict == self.new_weight_dict:
self.log_message(f"Dictionaries Are The Same {self.old_weight_dict} == {self.new_weight_dict}")
quantity = self.cash * (weight / 100) // price
self.log_message(f"Same Dictionary Order Balancing For {stock}")
if quantity > 0:
order = self.create_order(stock, quantity, "buy")
self.log_message(f"Order Adjusted {stock} +{price * quantity}$")
self.submit_order(order)
elif stock in self.old_weight_dict:
# self.log_message(f"{stock} is in the old dictionary. Available Cash: {self.cash}$")
if weight > self.old_weight_dict[stock]:
weight_difference = weight - self.old_weight_dict[stock]
quantity = (self.cash * (weight_difference / 100)) // price
self.log_message(f"Increase Order: {stock} Changed Order From {self.old_weight_dict[stock] * price}$ to {weight * price}$.", color = "light_green")
self.log_message(f"Calculated Quantity: {quantity}")
if quantity > 0 and self.cash >= price * quantity:
order = self.create_order(stock, quantity, "buy")
self.log_message(f"Buy Order: {stock} Bought {price * quantity}$.", color = "light_green")
self.submit_order(order)
elif weight < self.old_weight_dict[stock]:
weight_difference = self.old_weight_dict[stock] - weight
quantity = (self.cash * (weight_difference / 100)) // price
self.log_message(f"Decrease Order: {stock} Changed Order From {self.old_weight_dict[stock] * price}$ to {weight * price}$.", color = "light_red")
self.log_message(f"Calculated Quantity: {quantity}")
if quantity > 0 and self.cash >= price * quantity:
order = self.create_order(stock, quantity, "sell")
self.log_message(f"Sell Order: {stock} Sold {price * quantity}$.", color = "light_red")
self.submit_order(order)
else:
# self.log_message(f"{stock} Not in the old dictionary. Available Cash: {self.cash}$")
quantity = (self.cash * (weight / 100)) // price
self.log_message(f"Calculated Quantity: {quantity}")
if quantity > 0 and self.cash >= price * quantity:
order = self.create_order(stock, quantity, "buy")
self.log_message(f"Buy Order: {stock} Bought {price * quantity}$.", color = "light_green")
self.submit_order(order)
self.old_weight_dict = self.new_weight_dict.copy()
self.new_weight_dict.clear() # so that is it updated for the next turn
# self.log_message(f"Cash On End Of Iteration: {self.cash}$")
def trace_stats(self, context, snapshot_before):
self.log_message(f"Ending Cash Value: {self.cash}$")
self.log_message(f"Ending Portfolio Value: {self.portfolio_value}")
if __name__ == "__main__":
broker = Alpaca(ALPACA_CONFIG)
strategy = My_Strategy(broker=broker, sleeptime="10S", budget=10000)
trader = Trader()
trader.add_strategy(strategy)
trader.run_all()
Logs
2023-08-01 20:18:47,791: root: INFO: My_Strategy : Executing the initialize lifecycle method
2023-08-01 20:18:47,791: root: WARNING: Strategy My_Strategy: sell all
2023-08-01 20:18:48,143: root: INFO: �[32mmarket order of | 754 GOOG sell | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:18:48,169: root: INFO: �[32mNew market order of | 754 GOOG sell | with status pending_new was submitted.�[0m
2023-08-01 20:18:48,801: root: INFO: Partial Fill Transaction: sell 25 of GOOG at $132.42 per share
2023-08-01 20:18:48,805: root: INFO: market order of | 754 GOOG sell | with status new was partially filled
2023-08-01 20:18:48,988: root: INFO: Partial Fill Transaction: sell 188 of GOOG at $132.42 per share
2023-08-01 20:18:48,998: root: INFO: market order of | 754 GOOG sell | with status partial_fill was partially filled
2023-08-01 20:18:49,631: root: INFO: Partial Fill Transaction: sell 55 of GOOG at $132.42 per share
2023-08-01 20:18:49,632: root: INFO: market order of | 754 GOOG sell | with status partial_fill was partially filled
2023-08-01 20:18:50,067: root: INFO: �[32mFilled Transaction: sell 486 of GOOG at 132.46000000 USD per share�[0m
2023-08-01 20:18:50,068: root: INFO: market order of | 754 GOOG sell | with status partial_fill was filled
2023-08-01 20:18:50,073: root: INFO: Position 0.000000 shares of GOOG liquidated
2023-08-01 20:18:50,729: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:18:50,729: root: INFO: My_Strategy : Executing the on_partially_filled_order event method
2023-08-01 20:18:50,730: root: INFO: My_Strategy : Executing the on_partially_filled_order event method
2023-08-01 20:18:50,730: root: INFO: My_Strategy : Executing the on_partially_filled_order event method
2023-08-01 20:18:50,730: root: INFO: My_Strategy : Executing the on_filled_order event method
2023-08-01 20:18:50,730: root: INFO: My_Strategy : Executing the before_starting_trading lifecycle method
2023-08-01 20:18:52,129: root: INFO: My_Strategy : Executing the on_trading_iteration lifecycle method
2023-08-01 20:18:52,129: root: INFO: My_Strategy : My_Strategy self.cash = 99873.22$
2023-08-01 20:18:52,130: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:18:58,113: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:18:58,684: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:18:59,256: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:18:59,845: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:00,413: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:00,973: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:01,540: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:02,104: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:02,704: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:03,273: root: INFO: Getting historical prices for SPY, 200 bars, day
2023-08-01 20:19:03,843: root: INFO: My_Strategy : Old Dictionary: {} New Dictionary: {'INTC': 24 'MSFT': 24 'TXN': 7 'AMD': 7 'HPQ': 7 'GE': 7 'IBM': 7 'COHU': 17}
2023-08-01 20:19:04,120: root: INFO: My_Strategy : Calculated Quantity: 674.0
2023-08-01 20:19:04,121: root: INFO: �[92mMy_Strategy : Buy Order: INTC Bought 23953.96$.�[0m
2023-08-01 20:19:04,398: root: INFO: �[32mmarket order of | 674 INTC buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:04,404: root: INFO: �[32mNew market order of | 674 INTC buy | with status pending_new was submitted.�[0m
2023-08-01 20:19:04,449: root: INFO: My_Strategy : Calculated Quantity: 71.0
2023-08-01 20:19:04,450: root: INFO: �[92mMy_Strategy : Buy Order: MSFT Bought 23904.28$.�[0m
2023-08-01 20:19:04,734: root: INFO: �[32mmarket order of | 71 MSFT buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:04,734: root: INFO: �[32mFilled Transaction: buy 674 of INTC at 35.54000000 USD per share�[0m
2023-08-01 20:19:04,734: root: INFO: market order of | 674 INTC buy | with status new was filled
2023-08-01 20:19:04,743: root: INFO: �[32mNew market order of | 71 MSFT buy | with status pending_new was submitted.�[0m
2023-08-01 20:19:04,760: root: INFO: My_Strategy : Calculated Quantity: 39.0
2023-08-01 20:19:04,760: root: INFO: �[92mMy_Strategy : Buy Order: TXN Bought 6957.795$.�[0m
2023-08-01 20:19:05,028: root: INFO: My_Strategy : Calculated Quantity: 60.0
2023-08-01 20:19:05,028: root: INFO: �[32mmarket order of | 39 TXN buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:05,029: root: INFO: �[92mMy_Strategy : Buy Order: AMD Bought 6973.2$.�[0m
2023-08-01 20:19:05,306: root: INFO: My_Strategy : Calculated Quantity: 213.0
2023-08-01 20:19:05,307: root: INFO: �[32mmarket order of | 60 AMD buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:05,308: root: INFO: �[92mMy_Strategy : Buy Order: HPQ Bought 6976.8150000000005$.�[0m
2023-08-01 20:19:05,308: root: INFO: �[32mNew market order of | 39 TXN buy | with status pending_new was submitted.�[0m
2023-08-01 20:19:05,581: root: INFO: My_Strategy : Calculated Quantity: 62.0
2023-08-01 20:19:05,582: root: INFO: �[32mmarket order of | 213 HPQ buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:05,582: root: INFO: �[92mMy_Strategy : Buy Order: GE Bought 6968.18$.�[0m
2023-08-01 20:19:05,583: root: INFO: Partial Fill Transaction: buy 37 of MSFT at $336.65 per share
2023-08-01 20:19:05,585: root: INFO: market order of | 71 MSFT buy | with status new was partially filled
2023-08-01 20:19:05,860: root: INFO: My_Strategy : Calculated Quantity: 49.0
2023-08-01 20:19:05,861: root: INFO: �[32mmarket order of | 62 GE buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:05,861: root: INFO: �[92mMy_Strategy : Buy Order: IBM Bought 6976.62$.�[0m
2023-08-01 20:19:06,129: root: INFO: My_Strategy : Calculated Quantity: 390.0
2023-08-01 20:19:06,130: root: INFO: �[32mmarket order of | 49 IBM buy | with status pending_new was sent to broker alpaca�[0m
2023-08-01 20:19:06,130: root: INFO: �[92mMy_Strategy : Buy Order: COHU Bought 16945.5$.�[0m
2023-08-01 20:19:06,131: root: INFO: �[32mNew market order of | 60 AMD buy | with status pending_new was submitted.�[0m
2023-08-01 20:19:06,131: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:19:06,132: root: INFO: My_Strategy : Executing the on_filled_order event method
2023-08-01 20:19:06,132: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Executing the on_partially_filled_order event method
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Executing the on_new_order event method
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Ending Cash Value: 63463.21000000001$
2023-08-01 20:19:06,133: root: INFO: My_Strategy : Ending Portfolio Value: 99861.32
2023-08-01 20:19:06,133: root: ERROR: 'NoneType' object does not support item assignment
2023-08-01 20:19:06,134: root: ERROR: Traceback (most recent call last):
File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 570, in run
self._run_trading_session()
File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 538, in _run_trading_session
self._on_trading_iteration()
File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 261, in func_output
result = func_input(self, *args, **kwargs)
File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 286, in func_output
self._trace_stats(self._strategy_context, snapshot_before)
File "/home/user/.local/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 297, in _trace_stats
result["datetime"] = self.strategy.get_datetime()
TypeError: 'NoneType' object does not support item assignment
Let me know if any further information is needed. I'd be happy to work on the issue if i get information on why this could be.
The text at this link https://lumibot.lumiwealth.com/lifecycle_methods.initialize.html#:~:text=%23%20Set%20the%20strategy%20to%20call%20on_trading_interation%20every%205%20seconds is incorrect as it sets the timer to 2 seconds instead of the stated 10 seconds.
Do you have any interest in someone adding GH actions for running tests/linters etc?
Currently the settings for live trading get the inputted budget value, which is being removed. Need to get the cash and positions from the broker at start up for live trading.
Strategy name is not relevant or used and should be removed. Consider making it optional.
Release at same time as budget as users will need to be notified. jk
I am getting following error in simple_start_alpaca.py : (I am using python 3.6.1 and installed latest alpaca api 1.3.0 using pip install )
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\backtesting_init_.py", line 1, in
from .alpaca_backtesting import AlpacaBacktesting
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\backtesting\alpaca_backtesting.py", line 1, in
from lumibot.data_sources import AlpacaData
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\data_sources_init_.py", line 1, in
from .alpaca_data import AlpacaData
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\data_sources\alpaca_data.py", line 9, in
from lumibot.entities import Bars
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\entities_init_.py", line 1, in
from .asset import Asset, AssetsMapping
File "c:\krunal\learning\visualstudio\lumibot-master\lumibot\entities\asset.py", line 6, in
class Asset(BaseModel, frozen=True, extra='forbid'):
File "C:\Users\kruna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pydantic\main.py", line 324, in new
cls = super().new(mcs, name, bases, new_namespace, **kwargs)
TypeError: new() got an unexpected keyword argument 'frozen'
When Interrupting the Trader with KeyboardInterupt, all strategies will run on_abrupt_closing. Main Threads needs to log all messages. Current behavior is Strategy.on_abrupt_closing are successfully executing but not all actions are logged if the main thread closes before
Neil Murphy recommended that I look at lumibot and so I installed and tried to run the buy_and_hold.py example. I'm doing this on an M1 Mac where conda is pointed to all osx-arm64 libraries. Running pip install lumibot
fails because many libraries aren't able to be built likely because of M1 issues. I've therefore created a mod_requirements.txt file where I removed libaries that conda doesn't have to create this file:
# Brokers and Datasources dependecies
# Datascience dependencies
pandas==1.2.4
# Flask ecosystem dependencies
Flask-socketio===4.3.2
flask-sqlalchemy==2.5.1
flask-marshmallow==0.14.0
marshmallow-sqlalchemy==0.24.3
flask-security==3.0.0
email_validator==1.1.2 # flask_security dependency (not mentionned)
bcrypt==3.2.0 # flask_security dependency (not mentionned)
# Testing dependencies
pytest==6.2.3
# Linting dependencies
black==20.8b1
isort==5.8.0
I then installed with the following:
conda create -n lumibot
conda activate lumibot
conda install --file mod_requirements.txt
conda install matplotlib
pip install lumibot
python -c "import lumibot"
That allows pip to install the remaining libraries and the import works fine. But when I try any of the examples in lumibot with other imports like this they fail:
python -c "from lumibot.strategies.strategy import Strategy"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/strategies/__init__.py", line 1, in <module>
from .strategy import Strategy
File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/strategies/strategy.py", line 3, in <module>
from lumibot.entities import Asset, Order
File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/entities/__init__.py", line 3, in <module>
from .bars import Bars
File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/entities/bars.py", line 6, in <module>
from lumibot.data_sources.exceptions import NoDataFound
File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/data_sources/__init__.py", line 1, in <module>
from .alpaca_data import AlpacaData
File "/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/data_sources/alpaca_data.py", line 8, in <module>
from lumibot.entities import Bars
ImportError: cannot import name 'Bars' from partially initialized module 'lumibot.entities' (most likely due to a circular import) (/Users/andrew/miniforge3/envs/lumibot/lib/python3.9/site-packages/lumibot/entities/__init__.py)
It seems some sort of circular import of from lumibot.entities import Asset, Order
eventually leads to from lumibot.entities import Bars
which is not possible. I get similar errors with other example files.
The installed version of lumibot is version 1.1.7. Any ideas what could be causing this? The libraries seems to be installed fine but it doesn't like referencing the same module twice even though it's for a different class.
This code does not work.
Python 3.10.11
2023-05-31 10:08:41,412: root: INFO: Strangle : Executing the initialize lifecycle method
Exception in thread Strangle:
Traceback (most recent call last):
File "/Users/petrov/.pyenv/versions/3.10.11/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
self.run()
File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 559, in run
self._initialize()
File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 261, in func_output
result = func_input(self, *args, **kwargs)
File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/strategy_executor.py", line 316, in _initialize
self.strategy.initialize(**safe_params_to_pass)
File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/examples/strangle.py", line 74, in initialize
self.create_trading_pair(symbol)
File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/examples/strangle.py", line 303, in create_trading_pair
self.trading_pairs[self.create_asset(symbol, asset_type="stock")] = {
File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/strategies/strategy.py", line 2476, in create_asset
return Asset(
File "/Users/petrov/.pyenv/versions/3.10.11/envs/venv_3.10.11_lumibot/lib/python3.10/site-packages/lumibot/entities/asset.py", line 125, in __init__
super().__init__(symbol=symbol, asset_type=asset_type, **data)
File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Asset
strike
value is not a valid float (type=type_error.float)
My name is Luis, I'm a big-data machine-learning developer, I'm a fan of your work, and I usually check your updates.
I was afraid that my savings would be eaten by inflation. I have created a powerful tool that based on past technical patterns (volatility, moving averages, statistics, trends, candlesticks, support and resistance, stock index indicators).
All the ones you know (RSI, MACD, STOCH, Bolinger Bands, SMA, DEMARK, Japanese candlesticks, ichimoku, fibonacci, williansR, balance of power, murrey math, etc) and more than 200 others.
The tool creates prediction models of correct trading points (buy signal and sell signal, every stock is good traded in time and direction).
For this I have used big data tools like pandas python, stock market libraries like: tablib, TAcharts ,pandas_ta... For data collection and calculation.
And powerful machine-learning libraries such as: Sklearn.RandomForest , Sklearn.GradientBoosting, XGBoost, Google TensorFlow and Google TensorFlow LSTM.
With the models trained with the selection of the best technical indicators, the tool is able to predict trading points (where to buy, where to sell) and send real-time alerts to Telegram or Mail. The points are calculated based on the learning of the correct trading points of the last 2 years (including the change to bear market after the rate hike).
I think it could be useful to you, to improve, I would like to share it with you, and if you are interested in improving and collaborating I am also willing, and if not file it in the box.
If tou want, Please read the readme , and in case of any problem you can contact me ,
If you are convinced try to install it with the documentation.
https://github.com/Leci37/stocks-Machine-learning-RealTime-telegram/tree/develop I appreciate the feedback
The examples provided in Lumibot do not work with live trading when adding on statements such as printing the value of self.cash
. Errors are generated and the bot crashes.
Hi, I'm a new Lumibot user in Singapore. I found that I can't submit market order after midnight (12:00 am) local time, and in my Spyder console, it shows: Sleeping until the market opens.
After some checking, I found that in the file broker.py, there is a bug in the function is_market_open().
In this function, this line:
open_time = self.utc_to_local(self.market_hours(close=False))
gives the open time. It works as intended before midnight Singapore time say on Friday. However, when I run this line after 12 am Singapore time, it actually shows the open time of next Monday. Although the market is still open because it is at noon New York time, the variable current_time is earlier than the open time of next Monday, so this line:
return (current_time >= open_time) and (close_time >= current_time)
will return "false".
Here are some lines I run in my console and their outputs for your reference:
alpaca.is_market_open()
Out[2]: False
alpaca.api.get_clock()
Out[3]:
Clock({ 'is_open': True,
'next_close': '2023-05-05T16:00:00-04:00',
'next_open': '2023-05-08T09:30:00-04:00',
'timestamp': '2023-05-05T15:18:19.101183152-04:00'})
alpaca.utc_to_local(alpaca.market_hours(close=False))
Out[8]: Timestamp('2023-05-08 21:30:00+0800', tz='tzlocal()')
alpaca.utc_to_local(alpaca.market_hours(close=True))
Out[9]: Timestamp('2023-05-09 04:00:00+0800', tz='tzlocal()')
datetime.now().astimezone(tz=tz.tzlocal())
Out[10]: datetime.datetime(2023, 5, 6, 3, 33, 53, 871817, tzinfo=tzlocal())
open_time=alpaca.utc_to_local(alpaca.market_hours(close=False))
close_time=alpaca.utc_to_local(alpaca.market_hours(close=True))
current_time = datetime.now().astimezone(tz=tz.tzlocal())
current_time >= open_time
Out[14]: False
close_time >= current_time
Out[15]: True
As I mentioned earlier, when I try to submit a market order after midnight, it shows: Sleeping until the market opens. This may mean that there is a similar issue in the function trader.run_all() or other functions it calls.
Hopefully this bug can be fixed soon.
Thanks!
Shengchuang
The example given for options with AAPL is not working properly. Please help with that and can i use Nifty (indian market data) in this code.
I followed all steps and I am using python 3.6.1
I created credentials.py and setup alpacaconfig class
Please
Every strategy that has the code self.await_market_to_close()
no longer actually sleeps until the next trading day, instead, the on_trading_iteration()
keeps executing after the set sleep time. Here's the logs:
2021-03-11 00:14:56,159: INFO: Strategy DebtTrading: Executing the initialize lifecycle method
2021-03-11 00:14:57,905: INFO: Strategy DebtTrading: Executing the before_market_opens lifecycle method
2021-03-11 00:14:58,060: INFO: Sleeping until the market opens
Progress |████████████████████████████████████████████████████████████████████████████████████████| 100.00% Complete2021-03-11 00:14:58,060: INFO: Current backtesting datetime 2021-03-11 01:15:01.869044
2021-03-11 00:14:58,061: INFO: Strategy DebtTrading: Executing the before_starting_trading lifecycle method
2021-03-11 00:14:58,127: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:14:58,128: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:14:58,129: INFO: Debt level: 0.017681222903851657
2021-03-11 00:14:58,129: INFO: Using the normal_ratio: 0.6
2021-03-11 00:14:58,816: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:14:58,817: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:14:58,971: INFO: market order of | 77 SPY buy | with status accepted was sent to broker alpaca
2021-03-11 00:14:59,200: INFO: market order of | 142 TLT buy | with status accepted was sent to broker alpaca
2021-03-11 00:14:59,201: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:14:59,201: INFO: Sleeping until next trading day
2021-03-11 00:14:59,347: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:15:59,349: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:15:59,351: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:15:59,352: INFO: Debt level: 0.017681222903851657
2021-03-11 00:15:59,352: INFO: Using the normal_ratio: 0.6
2021-03-11 00:15:59,475: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:15:59,475: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:15:59,475: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:15:59,475: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:15:59,475: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:15:59,475: INFO: Sleeping until next trading day
2021-03-11 00:15:59,712: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:16:59,718: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:16:59,719: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:16:59,720: INFO: Debt level: 0.017681222903851657
2021-03-11 00:16:59,721: INFO: Using the normal_ratio: 0.6
2021-03-11 00:16:59,901: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:16:59,902: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:16:59,902: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:16:59,902: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:16:59,902: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:16:59,902: INFO: Sleeping until next trading day
2021-03-11 00:17:00,178: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:18:00,179: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:18:00,180: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:18:00,181: INFO: Debt level: 0.017681222903851657
2021-03-11 00:18:00,181: INFO: Using the normal_ratio: 0.6
2021-03-11 00:18:00,298: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:18:00,298: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:18:00,298: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:18:00,298: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:18:00,299: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:18:00,299: INFO: Sleeping until next trading day
2021-03-11 00:18:00,514: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:19:00,515: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:19:00,516: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:19:00,517: INFO: Debt level: 0.017681222903851657
2021-03-11 00:19:00,517: INFO: Using the normal_ratio: 0.6
2021-03-11 00:19:00,695: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:19:00,695: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:19:00,695: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:19:00,695: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:19:00,695: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:19:00,696: INFO: Sleeping until next trading day
2021-03-11 00:19:00,897: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:20:00,898: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:20:00,899: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:20:00,901: INFO: Debt level: 0.017681222903851657
2021-03-11 00:20:00,901: INFO: Using the normal_ratio: 0.6
2021-03-11 00:20:01,090: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:20:01,091: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:20:01,091: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:20:01,091: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:20:01,091: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:20:01,091: INFO: Sleeping until next trading day
2021-03-11 00:20:01,331: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:21:01,333: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:21:01,334: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:21:01,335: INFO: Debt level: 0.017681222903851657
2021-03-11 00:21:01,336: INFO: Using the normal_ratio: 0.6
2021-03-11 00:21:01,476: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:21:01,477: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:21:01,477: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:21:01,477: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:21:01,477: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:21:01,477: INFO: Sleeping until next trading day
2021-03-11 00:21:01,722: INFO: Strategy DebtTrading: Sleeping for 60 seconds
2021-03-11 00:22:01,723: INFO: Strategy DebtTrading: Porfolio value of 50000
2021-03-11 00:22:01,723: INFO: Strategy DebtTrading: Executing the on_trading_iteration lifecycle method
2021-03-11 00:22:01,724: INFO: Debt level: 0.017681222903851657
2021-03-11 00:22:01,725: INFO: Using the normal_ratio: 0.6
2021-03-11 00:22:01,939: INFO: Asset SPY shares value: 29986.88$. 389.44$ per 77 shares.
2021-03-11 00:22:01,939: INFO: Weighted SPY shares value with 60.00% weight: 30000.00$. 389.44$ per 77 shares.
2021-03-11 00:22:01,939: INFO: Asset TLT shares value: 19876.45$. 139.97$ per 142 shares.
2021-03-11 00:22:01,939: INFO: Weighted TLT shares value with 40.00% weight: 20000.00$. 139.97$ per 142 shares.
2021-03-11 00:22:01,939: INFO: Next portfolio rebalancing will be in 1 day(s)
2021-03-11 00:22:01,939: INFO: Sleeping until next trading day
2021-03-11 00:22:02,388: INFO: Strategy DebtTrading: Sleeping for 60 seconds
This is during a time when the market is closed. Previously in version 0.0.6 the program would actually sleep and wait until tomorrow, now it instead keeps executing on_trading_iteration()
every 60 seconds.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.