Skip to content

Instantly share code, notes, and snippets.

@raposatech
Last active December 25, 2023 00:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save raposatech/49ccc66f5c312f939f8826251c55a676 to your computer and use it in GitHub Desktop.
Save raposatech/49ccc66f5c312f939f8826251c55a676 to your computer and use it in GitHub Desktop.
Continuous Starter System
# MultiSignalStarterSystem available here:
# https://gist.github.com/raposatech/2d9f309e2a54fc9545d44eda821e29ad#file-starter_system_mult_sigs-py
class ContinuousStarterSystem(MultiSignalStarterSystem):
'''
Carver's Starter System without stop losses and multiple entry rules.
Adapted from Rob Carver's Leveraged Trading: https://amzn.to/3C1owYn
'''
def __init__(self, ticker: str, signals: dict, target_risk: float = 0.12,
starting_capital: float = 1000, margin_cost: float = 0.04,
short_cost: float = 0.001, interest_on_balance: float = 0.0,
start: str = '2000-01-01', end: str = '2020-12-31',
shorts: bool = True, weights: list = [],
*args, **kwargs):
super().__init__(ticker=ticker, signals=signals, target_risk=target_risk,
margin_cost=margin_cost, short_cost=short_cost, start=start, end=end,
interest_on_balance=interest_on_balance, starting_capital=starting_capital,
shorts=shorts, weights=weights)
def run(self):
position = np.zeros(self.data.shape[0])
cash = position.copy()
for i, (ts, row) in enumerate(self.data.iterrows()):
if any(np.isnan(row.values)):
cash[i] = self._calcCash(cash[i-1], position[i],
row['Close'], row['Dividends']) if i > 0 \
else self.starting_capital
continue
# Propagate values forward
position[i] = position[i-1]
cash[i] = self._calcCash(cash[i-1], position[i],
row['Close'], row['Dividends'])
signal = self._getSignal(row[self.signal_names].values)
if signal > 0:
if position[i] <= 0:
cash[i] += position[i] * row['Close']
position[i] = self._sizePosition(cash[i], row['Close'], row['STD'])
cash[i] -= position[i] * row['Close']
elif signal < 0:
if position[i] >= 0:
cash[i] += position[i] * row['Close']
if self.shorts:
position[i] = -self._sizePosition(cash[i], row['Close'], row['STD'])
cash[i] -= position[i] * row['Close']
else:
position[i] = 0
else:
# Remain neutral if signal == 0
cash[i] += position[i] * row['Close']
position[i] = 0
self.data['position'] = position
self.data['cash'] = cash
self.data['portfolio'] = self.data['position'] * self.data['Close'] \
+ self.data['cash']
self.data = calcReturns(self.data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment