From 2a28928f17b4c2413ed6ce52ed13f3d80e30db6a Mon Sep 17 00:00:00 2001 From: Denis Tereshkin Date: Sat, 15 Dec 2018 16:18:12 +0700 Subject: [PATCH] Variable position sizing --- .gitignore | 4 ++- src/naiback/analyzers/tradeslistanalyzer.py | 3 ++- src/naiback/broker/position.py | 2 +- src/naiback/strategy/strategy.py | 30 ++++++++++++--------- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index 39f3bf0..92dc1e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ build/* dist/* -src/naiback.egg-info/* \ No newline at end of file +src/naiback.egg-info/* +.* +__pycache__ \ No newline at end of file diff --git a/src/naiback/analyzers/tradeslistanalyzer.py b/src/naiback/analyzers/tradeslistanalyzer.py index 7ca88f6..f8eaab2 100644 --- a/src/naiback/analyzers/tradeslistanalyzer.py +++ b/src/naiback/analyzers/tradeslistanalyzer.py @@ -17,4 +17,5 @@ class TradesListAnalyzer(Analyzer): 'exit_time' : pos.exit_time(), 'pnl' : pos.pnl(), 'is_long' : pos.is_long(), - 'security' : pos.ticker } + 'security' : pos.ticker, + 'size' : pos.original_size() } diff --git a/src/naiback/broker/position.py b/src/naiback/broker/position.py index 346b301..401446f 100644 --- a/src/naiback/broker/position.py +++ b/src/naiback/broker/position.py @@ -21,7 +21,7 @@ class Position: return self.size_ def original_size(self): - return self.orignal_size_ + return self.original_size_ def is_long(self): return self.original_size_ > 0 diff --git a/src/naiback/strategy/strategy.py b/src/naiback/strategy/strategy.py index 4c7eb85..ddc7604 100644 --- a/src/naiback/strategy/strategy.py +++ b/src/naiback/strategy/strategy.py @@ -6,6 +6,8 @@ from naiback.analyzers.statsanalyzer import StatsAnalyzer from naiback.analyzers.tradeslistanalyzer import TradesListAnalyzer from naiback.exceptions import NaibackException +import math + class Strategy: """ """ @@ -15,6 +17,7 @@ class Strategy: self.all_bars = [] self.broker = Broker() self.bars = None + self.trade_size = 1 self.analyzers = { 'stats' : StatsAnalyzer(self), 'tradeslist' : TradesListAnalyzer(self) } @@ -27,6 +30,9 @@ class Strategy: """ self.feeds.append(feed) + def set_trade_size(self, size): + self.trade_size = math.floor(size) + @abstractmethod def execute(self): """ @@ -102,7 +108,7 @@ class Strategy: ticker = self.all_bars[ticker].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], self.trade_size, bar) def buy_at_limit(self, bar, price, ticker): if isinstance(ticker, int): @@ -111,9 +117,9 @@ class Strategy: self.broker.set_timestamp(bars.timestamp[bar]) if bars.low[bar] <= price: if bars.open[bar] > price: - return self.broker.add_position(ticker, price, 1, bar) + return self.broker.add_position(ticker, price, self.trade_size, bar) else: - return self.broker.add_position(ticker, bars.open[bar], 1, bar) + return self.broker.add_position(ticker, bars.open[bar], self.trade_size, bar) else: return None @@ -124,9 +130,9 @@ class Strategy: self.broker.set_timestamp(bars.timestamp[bar]) if bars.high[bar] >= price: if bars.open[bar] < price: - return self.broker.add_position(ticker, price, 1, bar) + return self.broker.add_position(ticker, price, self.trade_size, bar) else: - return self.broker.add_position(ticker, bars.open[bar], 1, bar) + return self.broker.add_position(ticker, bars.open[bar], self.trade_size, bar) else: return None @@ -135,14 +141,14 @@ class Strategy: ticker = self.all_bars[ticker].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], self.trade_size, bar) def short_at_open(self, bar, ticker): if isinstance(ticker, int): ticker = self.all_bars[ticker].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], -self.trade_size, bar) def short_at_limit(self, bar, price, ticker): if isinstance(ticker, int): @@ -151,9 +157,9 @@ class Strategy: self.broker.set_timestamp(bars.timestamp[bar]) if bars.high[bar] >= price: if bars.open[bar] < price: - return self.broker.add_position(ticker, price, -1, bar) + return self.broker.add_position(ticker, price, -self.trade_size, bar) else: - return self.broker.add_position(ticker, bars.open[bar], -1, bar) + return self.broker.add_position(ticker, bars.open[bar], -self.trade_size, bar) else: return None @@ -164,9 +170,9 @@ class Strategy: self.broker.set_timestamp(bars.timestamp[bar]) if bars.low[bar] <= price: if bars.open[bar] > price: - return self.broker.add_position(ticker, price, -1, bar) + return self.broker.add_position(ticker, price, -self.trade_size, bar) else: - return self.broker.add_position(ticker, bars.open[bar], -1, bar) + return self.broker.add_position(ticker, bars.open[bar], -self.trade_size, bar) else: return None @@ -175,7 +181,7 @@ class Strategy: ticker = self.all_bars[ticker].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], -self.trade_size, bar) def exit_at_open(self, bar, pos): bars = self._get_bars(pos.ticker)