Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
polakowo
GitHub Repository: polakowo/vectorbt
Path: blob/master/tests/notebooks/shortcash.ipynb
1073 views
Kernel: Python 3
from datetime import datetime import backtrader as bt import pandas as pd import numpy as np import vectorbt as vbt df = pd.DataFrame(index=[datetime(2020, 1, i + 1) for i in range(9)]) df['open'] = [1, 1, 2, 3, 4, 5, 6, 7, 8] df['high'] = df['open'] + 0.5 df['low'] = df['open'] - 0.5 df['close'] = df['open'] data = bt.feeds.PandasData(dataname=df) size = np.array([5, 5, -5, -5, -5, -5, 5, 5, 0]) class CommInfoFloat(bt.CommInfoBase): """Commission schema that keeps size as float.""" params = ( ('stocklike', True), ('commtype', bt.CommInfoBase.COMM_PERC), ('percabs', True), ) def getsize(self, price, cash): if not self._stocklike: return self.p.leverage * (cash / self.get_margin(price)) return self.p.leverage * (cash / price) class CashValueAnalyzer(bt.analyzers.Analyzer): """Analyzer to extract cash and value.""" def create_analysis(self): self.rets = {} def notify_cashvalue(self, cash, value): self.rets[self.strategy.datetime.datetime()] = (cash, value) def get_analysis(self): return self.rets class TestStrategy(bt.Strategy): def __init__(self): self.i = 0 def log(self, txt, dt=None): dt = dt or self.data.datetime[0] dt = bt.num2date(dt) print('%s, %s' % (dt.isoformat(), txt)) def notify_order(self, order): if order.status in [bt.Order.Submitted, bt.Order.Accepted]: return # Await further notifications if order.status == order.Completed: if order.isbuy(): buytxt = 'BUY COMPLETE {}, size = {:.2f}, price = {:.2f}'.format( order.data._name, order.executed.size, order.executed.price) self.log(buytxt, order.executed.dt) else: selltxt = 'SELL COMPLETE {}, size = {:.2f}, price = {:.2f}'.format( order.data._name, order.executed.size, order.executed.price) self.log(selltxt, order.executed.dt) elif order.status in [order.Expired, order.Canceled, order.Margin]: self.log('%s ,' % order.Status[order.status]) pass # Simply log # Allow new orders self.orderid = None def next(self): if size[self.i] > 0: self.buy(size=size[self.i]) elif size[self.i] < 0: self.sell(size=-size[self.i]) self.i += 1 def bt_simulate(shortcash): cerebro = bt.Cerebro() comminfo = CommInfoFloat(commission=0.01) cerebro.broker.addcommissioninfo(comminfo) cerebro.addstrategy(TestStrategy) cerebro.addanalyzer(CashValueAnalyzer) cerebro.broker.setcash(100.) cerebro.broker.set_checksubmit(False) cerebro.broker.set_shortcash(shortcash) cerebro.adddata(data) return cerebro.run()[0]
strategy = bt_simulate(True) strategy.analyzers.cashvalueanalyzer.get_analysis()
2020-01-02T00:00:00, BUY COMPLETE , size = 5.00, price = 1.00 2020-01-03T00:00:00, BUY COMPLETE , size = 5.00, price = 2.00 2020-01-04T00:00:00, SELL COMPLETE , size = -5.00, price = 3.00 2020-01-05T00:00:00, SELL COMPLETE , size = -5.00, price = 4.00 2020-01-06T00:00:00, SELL COMPLETE , size = -5.00, price = 5.00 2020-01-07T00:00:00, SELL COMPLETE , size = -5.00, price = 6.00 2020-01-08T00:00:00, BUY COMPLETE , size = 5.00, price = 7.00 2020-01-09T00:00:00, BUY COMPLETE , size = 5.00, price = 8.00
{datetime.datetime(2020, 1, 1, 0, 0): (100.0, 100.0), datetime.datetime(2020, 1, 2, 0, 0): (94.95, 99.95), datetime.datetime(2020, 1, 3, 0, 0): (84.85000000000001, 104.85000000000001), datetime.datetime(2020, 1, 4, 0, 0): (99.7, 114.7), datetime.datetime(2020, 1, 5, 0, 0): (119.5, 119.5), datetime.datetime(2020, 1, 6, 0, 0): (144.25, 119.25), datetime.datetime(2020, 1, 7, 0, 0): (173.95, 113.94999999999999), datetime.datetime(2020, 1, 8, 0, 0): (138.6, 103.6), datetime.datetime(2020, 1, 9, 0, 0): (98.19999999999999, 98.19999999999999)}
portfolio = vbt.Portfolio.from_orders(df.close, [np.nan] + size[:-1].tolist(), fees=0.01) print(portfolio.cash(free=False)) print(portfolio.value())
2020-01-01 100.00 2020-01-02 94.95 2020-01-03 84.85 2020-01-04 99.70 2020-01-05 119.50 2020-01-06 144.25 2020-01-07 173.95 2020-01-08 138.60 2020-01-09 98.20 Name: close, dtype: float64 2020-01-01 100.00 2020-01-02 99.95 2020-01-03 104.85 2020-01-04 114.70 2020-01-05 119.50 2020-01-06 119.25 2020-01-07 113.95 2020-01-08 103.60 2020-01-09 98.20 Name: close, dtype: float64
strategy = bt_simulate(False) strategy.analyzers.cashvalueanalyzer.get_analysis()
2020-01-02T00:00:00, BUY COMPLETE , size = 5.00, price = 1.00 2020-01-03T00:00:00, BUY COMPLETE , size = 5.00, price = 2.00 2020-01-04T00:00:00, SELL COMPLETE , size = -5.00, price = 3.00 2020-01-05T00:00:00, SELL COMPLETE , size = -5.00, price = 4.00 2020-01-06T00:00:00, SELL COMPLETE , size = -5.00, price = 5.00 2020-01-07T00:00:00, SELL COMPLETE , size = -5.00, price = 6.00 2020-01-08T00:00:00, BUY COMPLETE , size = 5.00, price = 7.00 2020-01-09T00:00:00, BUY COMPLETE , size = 5.00, price = 8.00
{datetime.datetime(2020, 1, 1, 0, 0): (100.0, 100.0), datetime.datetime(2020, 1, 2, 0, 0): (94.95, 99.95), datetime.datetime(2020, 1, 3, 0, 0): (84.85000000000001, 104.85000000000001), datetime.datetime(2020, 1, 4, 0, 0): (99.7, 114.7), datetime.datetime(2020, 1, 5, 0, 0): (119.5, 119.5), datetime.datetime(2020, 1, 6, 0, 0): (94.25, 119.25), datetime.datetime(2020, 1, 7, 0, 0): (63.95, 113.95), datetime.datetime(2020, 1, 8, 0, 0): (83.60000000000001, 103.60000000000001), datetime.datetime(2020, 1, 9, 0, 0): (98.2, 98.2)}
print(portfolio.cash(free=True)) print(portfolio.value())
2020-01-01 100.00 2020-01-02 94.95 2020-01-03 84.85 2020-01-04 99.70 2020-01-05 119.50 2020-01-06 94.25 2020-01-07 63.95 2020-01-08 83.60 2020-01-09 98.20 Name: close, dtype: float64 2020-01-01 100.00 2020-01-02 99.95 2020-01-03 104.85 2020-01-04 114.70 2020-01-05 119.50 2020-01-06 119.25 2020-01-07 113.95 2020-01-08 103.60 2020-01-09 98.20 Name: close, dtype: float64