import pandas as pd
from moonshot import Moonshot
from moonshot.commission import PerShareCommission
class USStockCommission(PerShareCommission):
BROKER_COMMISSION_PER_SHARE = 0.005
class TrendDayStrategy(Moonshot):
"""
Intraday strategy that buys (sells) if the security is up (down) more
than N% from yesterday's close as of 2:00 PM. Enters at 2:01 PM and
exits the position at the market close.
"""
CODE = 'trend-day'
DB = 'usstock-1min'
UNIVERSES = "leveraged-etf"
DB_TIMES = ['14:00:00', '15:59:00']
DB_FIELDS = ['Open','Close']
MIN_PCT_CHANGE = 0.06
COMMISSION_CLASS = USStockCommission
SLIPPAGE_BPS = 3
def prices_to_signals(self, prices):
closes = prices.loc["Close"]
opens = prices.loc["Open"]
session_closes = closes.xs("15:59:00", level="Time")
afternoon_prices = opens.xs("14:00:00", level="Time")
prior_closes = session_closes.shift()
returns = (afternoon_prices - prior_closes) / prior_closes
long_signals = returns > self.MIN_PCT_CHANGE
short_signals = returns < -self.MIN_PCT_CHANGE
signals = long_signals.astype(int).where(long_signals, -short_signals.astype(int))
return signals
def signals_to_target_weights(self, signals, prices):
target_weights = self.allocate_fixed_weights_capped(signals, 0.20, cap=1.0)
return target_weights
def target_weights_to_positions(self, target_weights, prices):
positions = target_weights.copy()
return positions
def positions_to_gross_returns(self, positions, prices):
closes = prices.loc["Close"]
entry_prices = closes.xs("14:00:00", level="Time")
session_closes = closes.xs("15:59:00", level="Time")
pct_changes = (session_closes - entry_prices) / entry_prices
gross_returns = pct_changes * positions
return gross_returns
def order_stubs_to_orders(self, orders, prices):
orders["Exchange"] = "SMART"
orders["OrderType"] = "MKT"
orders["Tif"] = "Day"
child_orders = self.orders_to_child_orders(orders)
child_orders.loc[:, "OrderType"] = "MOC"
orders = pd.concat([orders, child_orders])
return orders