mirror of
https://github.com/kernc/backtesting.py.git
synced 2024-01-28 15:29:30 +03:00
BUG: Reset position price (etc.) after closing position
Fixes https://github.com/kernc/backtesting.py/issues/27
This commit is contained in:
@@ -5,6 +5,13 @@ import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def try_(lazy_func, default=None, exception=Exception):
|
||||
try:
|
||||
return lazy_func()
|
||||
except exception:
|
||||
return default
|
||||
|
||||
|
||||
def _as_str(value):
|
||||
if isinstance(value, (Number, str)):
|
||||
return str(value)
|
||||
|
||||
@@ -406,7 +406,7 @@ class Position:
|
||||
Profit (positive) or loss (negative) of current position,
|
||||
in percent of position open price.
|
||||
"""
|
||||
return self.pl / (self.open_price * abs(self.size))
|
||||
return self.pl / (self.open_price * abs(self.size) or 1)
|
||||
|
||||
@property
|
||||
def is_long(self):
|
||||
@@ -514,6 +514,8 @@ class _Broker:
|
||||
|
||||
self._cash += pl
|
||||
self._position = 0
|
||||
self._position_open_price = 0
|
||||
self._position_open_i = None
|
||||
|
||||
@property
|
||||
def equity(self):
|
||||
|
||||
@@ -25,7 +25,9 @@ from backtesting.lib import (
|
||||
plot_heatmaps
|
||||
)
|
||||
from backtesting.test import GOOG, EURUSD, SMA
|
||||
from backtesting._util import _Indicator, _as_str, _Array
|
||||
from backtesting._util import _Indicator, _as_str, _Array, try_
|
||||
|
||||
SHORT_DATA = GOOG.iloc[:20] # Short data for fast tests with no indicator lag
|
||||
|
||||
|
||||
@contextmanager
|
||||
@@ -297,6 +299,41 @@ class TestBacktest(TestCase):
|
||||
self.assertEqual(stats['_strategy'].__class__, strategy)
|
||||
|
||||
|
||||
class TestStrategy(TestCase):
|
||||
def test_position(self):
|
||||
def coroutine(self):
|
||||
yield self.buy()
|
||||
|
||||
assert self.position
|
||||
assert self.position.is_long
|
||||
assert not self.position.is_short
|
||||
assert self.position.size > 0
|
||||
assert self.position.pl
|
||||
assert self.position.pl_pct
|
||||
assert self.position.open_price > 0
|
||||
assert self.position.open_time
|
||||
|
||||
yield self.position.close()
|
||||
|
||||
assert not self.position
|
||||
assert not self.position.is_long
|
||||
assert not self.position.is_short
|
||||
assert not self.position.size
|
||||
assert not self.position.pl
|
||||
assert not self.position.pl_pct
|
||||
assert not self.position.open_price
|
||||
assert not self.position.open_time
|
||||
|
||||
class S(Strategy):
|
||||
def init(self):
|
||||
self.step = coroutine(self)
|
||||
|
||||
def next(self):
|
||||
try_(self.step.__next__, None, StopIteration)
|
||||
|
||||
Backtest(SHORT_DATA, S).run()
|
||||
|
||||
|
||||
class TestOptimize(TestCase):
|
||||
def test_optimize(self):
|
||||
bt = Backtest(GOOG.iloc[:100], SmaCross)
|
||||
|
||||
Reference in New Issue
Block a user