Browse Source

Trades: entry & exit dates

Now positions get new metadata: 'entry_time' and 'exit_time'
which store datetime object of entry and exit bars
master
Denis Tereshkin 7 years ago
parent
commit
1459f020d3
  1. 2
      src/naiback/analyzers/tradeslistanalyzer.py
  2. 8
      src/naiback/broker/broker.py
  3. 6
      src/naiback/broker/position.py
  4. 12
      src/naiback/strategy/strategy.py

2
src/naiback/analyzers/tradeslistanalyzer.py

@ -13,4 +13,6 @@ class TradesListAnalyzer(Analyzer):
def make_trade(self, pos): def make_trade(self, pos):
return { 'entry_price' : pos.entry_price(), return { 'entry_price' : pos.entry_price(),
'exit_price' : pos.exit_price(), 'exit_price' : pos.exit_price(),
'entry_time' : pos.entry_time(),
'exit_time' : pos.exit_time(),
'pnl' : pos.pnl() } 'pnl' : pos.pnl() }

8
src/naiback/broker/broker.py

@ -15,17 +15,21 @@ class Broker:
self.positions = [] self.positions = []
self.retired_positions_ = [] self.retired_positions_ = []
self.commission_percentage = 0 self.commission_percentage = 0
self.timestamp = None
def cash(self): def cash(self):
return self.cash_ return self.cash_
def set_timestamp(self, ts):
self.timestamp = ts
def add_position(self, ticker, price, amount, bar_index): def add_position(self, ticker, price, amount, bar_index):
volume = abs(price * amount) volume = abs(price * amount)
if amount > 0: if amount > 0:
if volume * (1 + 0.01 * self.commission_percentage) > self.cash_: if volume * (1 + 0.01 * self.commission_percentage) > self.cash_:
return None return None
pos = Position(ticker) pos = Position(ticker)
pos.enter(price, amount, bar=bar_index) pos.enter(price, amount, bar=bar_index, timestamp=self.timestamp)
self.cash_ -= price * amount self.cash_ -= price * amount
self.cash_ -= volume * 0.01 * self.commission_percentage self.cash_ -= volume * 0.01 * self.commission_percentage
self.positions.append(pos) self.positions.append(pos)
@ -34,7 +38,7 @@ class Broker:
def close_position(self, pos, price, bar_index): def close_position(self, pos, price, bar_index):
volume = abs(price * pos.size()) volume = abs(price * pos.size())
size = pos.size() size = pos.size()
pos.exit(price, bar=bar_index) pos.exit(price, bar=bar_index, timestamp=self.timestamp)
self.retired_positions_.append(pos) self.retired_positions_.append(pos)
self.positions.remove(pos) self.positions.remove(pos)

6
src/naiback/broker/position.py

@ -35,9 +35,15 @@ class Position:
def entry_bar(self): def entry_bar(self):
return self.entry_metadata['bar'] return self.entry_metadata['bar']
def entry_time(self):
return self.entry_metadata['timestamp']
def exit_bar(self): def exit_bar(self):
return self.exit_metadata['bar'] return self.exit_metadata['bar']
def exit_time(self):
return self.exit_metadata['timestamp']
def bars_in_trade(self): def bars_in_trade(self):
return self.exit_bar() - self.entry_bar() return self.exit_bar() - self.entry_bar()

12
src/naiback/strategy/strategy.py

@ -101,12 +101,14 @@ class Strategy:
if isinstance(ticker, int): if isinstance(ticker, int):
ticker = self.all_bars[ticker].ticker ticker = self.all_bars[ticker].ticker
bars = self._get_bars(ticker) bars = self._get_bars(ticker)
self.broker.set_timestamp(bars.timestamp[bar])
return self.broker.add_position(ticker, bars.open[bar], 1, bar) return self.broker.add_position(ticker, bars.open[bar], 1, bar)
def buy_at_limit(self, bar, price, ticker): def buy_at_limit(self, bar, price, ticker):
if isinstance(ticker, int): if isinstance(ticker, int):
ticker = self.all_bars[ticker].ticker ticker = self.all_bars[ticker].ticker
bars = self._get_bars(ticker) bars = self._get_bars(ticker)
self.broker.set_timestamp(bars.timestamp[bar])
if bars.low[bar] <= price: if bars.low[bar] <= price:
if bars.open[bar] > price: if bars.open[bar] > price:
return self.broker.add_position(ticker, price, 1, bar) return self.broker.add_position(ticker, price, 1, bar)
@ -119,6 +121,7 @@ class Strategy:
if isinstance(ticker, int): if isinstance(ticker, int):
ticker = self.all_bars[ticker].ticker ticker = self.all_bars[ticker].ticker
bars = self._get_bars(ticker) bars = self._get_bars(ticker)
self.broker.set_timestamp(bars.timestamp[bar])
if bars.high[bar] >= price: if bars.high[bar] >= price:
if bars.open[bar] < price: if bars.open[bar] < price:
return self.broker.add_position(ticker, price, 1, bar) return self.broker.add_position(ticker, price, 1, bar)
@ -131,18 +134,21 @@ class Strategy:
if isinstance(ticker, int): if isinstance(ticker, int):
ticker = self.all_bars[ticker].ticker ticker = self.all_bars[ticker].ticker
bars = self._get_bars(ticker) bars = self._get_bars(ticker)
self.broker.set_timestamp(bars.timestamp[bar])
return self.broker.add_position(ticker, bars.close[bar], 1, bar) return self.broker.add_position(ticker, bars.close[bar], 1, bar)
def short_at_open(self, bar, ticker): def short_at_open(self, bar, ticker):
if isinstance(ticker, int): if isinstance(ticker, int):
ticker = self.all_bars[ticker].ticker ticker = self.all_bars[ticker].ticker
bars = self._get_bars(ticker) bars = self._get_bars(ticker)
self.broker.set_timestamp(bars.timestamp[bar])
return self.broker.add_position(ticker, bars.open[bar], -1, bar) return self.broker.add_position(ticker, bars.open[bar], -1, bar)
def short_at_limit(self, bar, price, ticker): def short_at_limit(self, bar, price, ticker):
if isinstance(ticker, int): if isinstance(ticker, int):
ticker = self.all_bars[ticker].ticker ticker = self.all_bars[ticker].ticker
bars = self._get_bars(ticker) bars = self._get_bars(ticker)
self.broker.set_timestamp(bars.timestamp[bar])
if bars.high[bar] >= price: if bars.high[bar] >= price:
if bars.open[bar] < price: if bars.open[bar] < price:
return self.broker.add_position(ticker, price, -1, bar) return self.broker.add_position(ticker, price, -1, bar)
@ -155,6 +161,7 @@ class Strategy:
if isinstance(ticker, int): if isinstance(ticker, int):
ticker = self.all_bars[ticker].ticker ticker = self.all_bars[ticker].ticker
bars = self._get_bars(ticker) bars = self._get_bars(ticker)
self.broker.set_timestamp(bars.timestamp[bar])
if bars.low[bar] <= price: if bars.low[bar] <= price:
if bars.open[bar] > price: if bars.open[bar] > price:
return self.broker.add_position(ticker, price, -1, bar) return self.broker.add_position(ticker, price, -1, bar)
@ -167,14 +174,17 @@ class Strategy:
if isinstance(ticker, int): if isinstance(ticker, int):
ticker = self.all_bars[ticker].ticker ticker = self.all_bars[ticker].ticker
bars = self._get_bars(ticker) bars = self._get_bars(ticker)
self.broker.set_timestamp(bars.timestamp[bar])
return self.broker.add_position(ticker, bars.close[bar], -1, bar) return self.broker.add_position(ticker, bars.close[bar], -1, bar)
def exit_at_open(self, bar, pos): def exit_at_open(self, bar, pos):
bars = self._get_bars(pos.ticker) bars = self._get_bars(pos.ticker)
self.broker.set_timestamp(bars.timestamp[bar])
return self.broker.close_position(pos, bars.open[bar], bar) return self.broker.close_position(pos, bars.open[bar], bar)
def exit_at_limit(self, bar, price, pos): def exit_at_limit(self, bar, price, pos):
bars = self._get_bars(pos.ticker) bars = self._get_bars(pos.ticker)
self.broker.set_timestamp(bars.timestamp[bar])
if pos.is_long(): if pos.is_long():
if bars.high[bar] >= price: if bars.high[bar] >= price:
if bars.open[bar] < price: if bars.open[bar] < price:
@ -194,6 +204,7 @@ class Strategy:
def exit_at_stop(self, bar, price, pos): def exit_at_stop(self, bar, price, pos):
bars = self._get_bars(pos.ticker) bars = self._get_bars(pos.ticker)
self.broker.set_timestamp(bars.timestamp[bar])
if pos.is_long(): if pos.is_long():
if bars.low[bar] <= price: if bars.low[bar] <= price:
if bars.open[bar] > price: if bars.open[bar] > price:
@ -213,5 +224,6 @@ class Strategy:
def exit_at_close(self, bar, pos): def exit_at_close(self, bar, pos):
bars = self._get_bars(pos.ticker) bars = self._get_bars(pos.ticker)
self.broker.set_timestamp(bars.timestamp[bar])
return self.broker.close_position(pos, bars.close[bar], bar) return self.broker.close_position(pos, bars.close[bar], bar)

Loading…
Cancel
Save