Skip to content

Commit 1d19225

Browse files
authored
Merge branch 'master' into merge_memento_backtrader
2 parents 0426c77 + e97813b commit 1d19225

File tree

7 files changed

+211
-22
lines changed

7 files changed

+211
-22
lines changed

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*.py text
2+
*.txt text
3+
*.csv text

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,8 @@ samples2/
6868
# Ignore test files in Datas
6969
datas/*.py
7070

71-
.idea/
71+
# Ignore nose tests temp files
72+
.noseids
73+
74+
# PyCharm dirs:
75+
.idea

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ language: python
33
python:
44
- "3.6"
55
- "3.7"
6-
- "3.8"
7-
- "nightly"
86
- "pypy"
97
- "pypy3"
108

@@ -13,6 +11,7 @@ matrix:
1311
python: "3.8-dev"
1412
python: "nightly"
1513

14+
1615
# command to install dependencies
1716
# install:
1817
# - pip install your_package

README.rst

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,42 @@
1-
backtrader
2-
==========
1+
backtrader2 : An on going and open project
2+
==========================================
33

4-
.. image:: https://img.shields.io/pypi/v/backtrader.svg
5-
:alt: PyPi Version
4+
5+
.. image:: https://img.shields.io/pypi/dm/backtrader.svg
6+
:alt: PyPi Monthly Donwloads
67
:scale: 100%
78
:target: https://pypi.python.org/pypi/backtrader/
89

9-
.. .. image:: https://img.shields.io/pypi/dm/backtrader.svg
10-
:alt: PyPi Monthly Donwloads
11-
:scale: 100%
12-
:target: https://pypi.python.org/pypi/backtrader/
13-
1410
.. image:: https://img.shields.io/pypi/l/backtrader.svg
1511
:alt: License
1612
:scale: 100%
1713
:target: https://github.com/backtrader/backtrader/blob/master/LICENSE
18-
.. image:: https://travis-ci.org/backtrader/backtrader.png?branch=master
14+
.. image:: https://travis-ci.org/backtrader2/backtrader.png?branch=master
1915
:alt: Travis-ci Build Status
2016
:scale: 100%
21-
:target: https://travis-ci.org/backtrader/backtrader
17+
:target: https://travis-ci.org/backtrader2/backtrader
2218
.. image:: https://img.shields.io/pypi/pyversions/backtrader.svg
2319
:alt: Python versions
2420
:scale: 100%
2521
:target: https://pypi.python.org/pypi/backtrader/
2622

27-
**Yahoo API Note**:
23+
**Important Update**
24+
25+
Backtrader is a flexible and powerful backtesting engine written in python.
26+
The original project found wide appeal due to its versatility. Over time however,
27+
the original code base became inaccessible to bug fixes and enhancements.
28+
29+
Backtrader2 is a forked copy of backtrader by the community of users that seeks to make
30+
backtrader an ongoing project.
2831

29-
[2018-11-16] After some testing it would seem that data downloads can be
30-
again relied upon over the web interface (or API ``v7``)
32+
Initially backtrader2 will fix bugs. Just submit an issue and pull requests.
3133

32-
**Tickets**
34+
New code ideas are welcome but will not be addressed at this time. But please do enter them as an issue
35+
and tag it with 'enhancement' so that we can track your idea down the road.
3336

34-
The ticket system is (was, actually) more often than not abused to ask for
35-
advice about samples.
37+
**Backtrader's back and we look forward to its future!**
3638

37-
For **feedback/questions/...** use the `Community <https://community.backtrader.com>`_
39+
For feedback/questions/... use the `Community <https://community.backtrader.com>`_
3840

3941
Here a snippet of a Simple Moving Average CrossOver. It can be done in several
4042
different ways. Use the docs (and examples) Luke!

backtrader/brokers/bbroker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ def _try_exec_limit(self, order, popen, phigh, plow, plimit):
911911
if plimit <= popen:
912912
# open greater/equal than requested - sell more expensive
913913
pmin = max(plow, plimit)
914-
p = self._slip_down(plimit, popen, doslip=self.p.slip_open,
914+
p = self._slip_down(pmin, popen, doslip=self.p.slip_open,
915915
lim=True)
916916
self._execute(order, ago=0, price=p)
917917
elif plimit <= phigh:

datas/bbroker_try_exec_limit.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Date,Open,High,Low,Close,Volume,OpenInterest
2+
2019-01-01, 1295.5, 1305.5, 1290.1, 1298.6, 235334, 319231,
3+
2019-01-02, 1297.5, 1303.5, 1293.1, 1296.6, 235334, 319231,
4+
2019-01-03, 1301.0, 1309.4, 1298.9, 1307.3, 244542, 311254,
5+
2019-01-04, 1309.0, 1312.9, 1285.0, 1298.3, 316063, 302111,

tests/test_bbroker_try_exec_limit.py

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8; py-indent-offset:4 -*-
3+
###############################################################################
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
#
18+
###############################################################################
19+
from __future__ import absolute_import, division, print_function, unicode_literals
20+
21+
import datetime
22+
import os
23+
import time
24+
25+
26+
try:
27+
time_clock = time.process_time
28+
except:
29+
time_clock = time.clock
30+
31+
import backtrader as bt
32+
33+
34+
class SlipTestStrategy(bt.SignalStrategy):
35+
params = (
36+
("printdata", False),
37+
("printops", False),
38+
)
39+
40+
def log(self, txt, dt=None, nodate=False):
41+
if not nodate:
42+
dt = dt or self.data.datetime[0]
43+
dt = bt.num2date(dt)
44+
print("%s, %s" % (dt.isoformat(), txt))
45+
else:
46+
print("---------- %s" % (txt))
47+
48+
def notify_order(self, order):
49+
if order.status in [bt.Order.Submitted, bt.Order.Accepted]:
50+
return # Await further notifications
51+
52+
if order.status == order.Completed:
53+
if isinstance(order, bt.BuyOrder):
54+
if self.p.printops:
55+
txt = "BUY, %.2f" % order.executed.price
56+
self.log(txt, order.executed.dt)
57+
chkprice = "%.2f" % order.executed.price
58+
self.buyexec.append(chkprice)
59+
else: # elif isinstance(order, SellOrder):
60+
if self.p.printops:
61+
txt = "SELL, %.2f" % order.executed.price
62+
self.log(txt, order.executed.dt)
63+
64+
chkprice = "%.2f" % order.executed.price
65+
self.sellexec.append(chkprice)
66+
67+
elif order.status in [order.Expired, order.Canceled, order.Margin]:
68+
if self.p.printops:
69+
self.log("%s ," % order.Status[order.status])
70+
71+
# Allow new orders
72+
self.order = None
73+
74+
def __init__(self):
75+
# Flag to allow new orders in the system or not
76+
self.order = None
77+
self.price = 1285.0
78+
self.counter = 0
79+
80+
def start(self):
81+
82+
if self.p.printdata:
83+
self.log("-------------------------", nodate=True)
84+
self.log(
85+
"Starting portfolio value: %.2f" % self.broker.getvalue(), nodate=True
86+
)
87+
88+
self.tstart = time_clock()
89+
90+
self.buycreate = list()
91+
self.sellcreate = list()
92+
self.buyexec = list()
93+
self.sellexec = list()
94+
95+
def stop(self):
96+
tused = time_clock() - self.tstart
97+
if self.p.printdata:
98+
self.log("Time used: %s" % str(tused))
99+
self.log("Final portfolio value: %.2f" % self.broker.getvalue())
100+
self.log("Final cash value: %.2f" % self.broker.getcash())
101+
self.log("-------------------------")
102+
else:
103+
pass
104+
105+
def print_signal(self):
106+
if self.p.printdata:
107+
self.log(
108+
"Open, High, Low, Close, %.2f, %.2f, %.2f, %.2f"
109+
% (
110+
self.data.open[0],
111+
self.data.high[0],
112+
self.data.low[0],
113+
self.data.close[0],
114+
)
115+
)
116+
117+
def next(self):
118+
self.print_signal()
119+
120+
if self.counter == 0:
121+
self.order = self.sell(exectype=bt.Order.Limit, price=self.price)
122+
if self.p.printops:
123+
self.log("SELL ISSUED @ %0.2f" % self.price)
124+
self.counter += 1
125+
126+
127+
def test_run(main=False):
128+
""" Test a fix in bbroker. See backtrader2 pr#22 """
129+
130+
cerebro = bt.Cerebro()
131+
132+
if main == True:
133+
strat_kwargs = dict(printdata=True, printops=True)
134+
else:
135+
strat_kwargs = dict(printdata=False, printops=False)
136+
137+
cerebro.addstrategy(SlipTestStrategy, **strat_kwargs)
138+
139+
cerebro.broker.setcash(10000.0)
140+
141+
modpath = os.path.dirname(os.path.abspath(__file__))
142+
dataspath = "../datas"
143+
datafile = "bbroker_try_exec_limit.txt"
144+
datapath = os.path.join(modpath, dataspath, datafile)
145+
data0 = bt.feeds.GenericCSVData(
146+
dataname=datapath,
147+
dtformat=("%Y-%m-%d"),
148+
timeframe=bt.TimeFrame.Days,
149+
compression=1,
150+
)
151+
cerebro.adddata(data0)
152+
153+
# Slippage/expected sell executed price
154+
expected_results = (
155+
(0, 1297.5),
156+
(3, 1294.50),
157+
(4, 1293.50),
158+
(5, 1293.10),
159+
(10, 1293.10),
160+
)
161+
162+
for expected_result in expected_results:
163+
cerebro.broker.set_slippage_fixed(expected_result[0])
164+
strat = cerebro.run()
165+
if main:
166+
print(
167+
"Slippage {}, Sell Executed {:.2f}, Expected price {:.2f}".format(
168+
expected_result[0], float(strat[0].sellexec[0]), expected_result[1]
169+
)
170+
)
171+
172+
assert float(strat[0].sellexec[0]) == expected_result[1]
173+
174+
175+
if __name__ == "__main__":
176+
test_run(main=True)

0 commit comments

Comments
 (0)