Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #@autojit
- def MakeTrade(self, dd, data, data_i, trade_quantity, trade_price, tradeRecordColumn, the_stop_price):
- trade_quantity = int(trade_quantity) #make sure this is an int
- if trade_quantity == 0:
- return
- if (self.cashInHand < 0.0):
- return
- if (self.numSharesHeld < 0) and (trade_quantity < 0):
- return
- if (self.numSharesHeld > 0) and (trade_quantity > 0):
- return
- self.someSharesTraded = True
- store_it = False
- if data is None:
- data = dd.loc[data_i].copy()
- store_it = True ## maybe this should be a named parameter
- if trade_quantity != 0: #was self.NumSharesTraded != 0:
- cashInHand_Before = self.cashInHand
- numSharesHeld_Before = self.numSharesHeld
- data['NumSharesHeld'] = self.numSharesHeld = self.numSharesHeld + trade_quantity
- data['NumSharesTraded'] = self.NumSharesTraded = self.NumSharesTraded + trade_quantity;
- data['ValueSharesTraded'] = self.ValueSharesTraded = self.ValueSharesTraded + (trade_quantity * trade_price)
- if (tradeRecordColumn is not None):
- data[tradeRecordColumn] = trade_price
- if numSharesHeld_Before == 0:
- cashInHand_After = round(cashInHand_Before - abs(trade_quantity * trade_price), 2) # any trade costs money
- self.trade_open_price = trade_price
- if the_stop_price is not None:
- if trade_quantity > 0:
- self.long_stop_price = the_stop_price
- else:
- self.short_stop_price = the_stop_price
- elif numSharesHeld_Before > 0:
- if trade_quantity > 0:
- print "trying to buy on top of a long position"
- else:
- t1 = abs(trade_quantity) * self.trade_open_price #original cost of shares to trade
- t2 = (self.trade_open_price - trade_price ) * trade_quantity #profit from trade
- ValueTradeChange = t1 + t2
- cashInHand_After = round(cashInHand_Before + ValueTradeChange, 2)
- elif numSharesHeld_Before < 0:
- if trade_quantity > 0:
- t1 = abs(trade_quantity) * self.trade_open_price #original cost of shares to trade
- t2 = (self.trade_open_price - trade_price ) * trade_quantity #profit from trade
- ValueTradeChange = t1 + t2
- cashInHand_After = round(cashInHand_Before + ValueTradeChange, 2)
- else:
- print "trying to sell when already short"
- else:
- print "madness"
- if debug:
- print str(data_i) + "\tMakeTrade " + str(tradeRecordColumn) + "\t" + str(trade_quantity) + " shares @\t" + str(trade_price) + " [ cashBefore =\t" + str(cashInHand_Before) + \
- " sharesBefore =\t" + str(numSharesHeld_Before) + " ]\t[ cashAfter =\t" + str(cashInHand_After) + "\t sharesAfter =\t" + str (self.numSharesHeld) + " ]"
- data['CashInHand'] = self.cashInHand = cashInHand_After
- if self.numSharesHeld == 0:
- data['CashInvested'] = 0
- self.trade_open_price = np.NaN ## shouldnt ever be read.
- else:
- data['CashInvested'] = 10000
- if store_it == True:
- dd.loc[data_i] = data
- #@autojit
- def Run_OnSymbol(self,
- df,
- LS_ema,
- LS_width,
- TP1_ema,
- TP1_pct,
- TP1_width,
- TP1_profitWidth,
- target_width,
- stop_ema,
- stop_ema_width,
- stop_window,
- ):
- dataNeeded = max(125, LS_ema, TP1_ema, 200*7)
- if ((df.shape[0]-5) <= dataNeeded):
- for i in xrange (20):
- print "SHAPE TOO SMALL - SKIPPING"
- print df.shape[0]
- print "min = " + str(min(125, LS_ema, TP1_ema))
- print "LS_ema = " + str(LS_ema)
- print "TP1_ema = " + str(TP1_ema)
- return None
- # df["Active"][:dataNeeded] = 0
- df["LS_EMA"] = pd.ewma(df.Close, min_periods=LS_ema-1, span = LS_ema).bfill()
- df["TP1_EMA"] = pd.ewma(df.Close, min_periods=TP1_ema-1, span = TP1_ema).bfill()
- df["Stop_EMA"] = pd.ewma(df.Close, min_periods=stop_ema-1, span = stop_ema).bfill()
- df["H2"] = pd.rolling_max(df["High"], 2, min_periods = 2)
- df["L2"] = pd.rolling_min(df["Low"], 2, min_periods = 2)
- df["HL2"] = (df["H2"] + df["L2"]) / 2.0 #(MAXH2 + MINL2)/2
- XAVGH125 = pd.ewma(df.High, min_periods=125-1, span = 125).bfill()
- XAVGL125 = pd.ewma(df.Low, min_periods=125-1, span = 125).bfill()
- df["ChanWidth"] = XAVGH125 - XAVGL125
- #Create Long Short Ema chan
- LS_EMA_width = df["ChanWidth"] * LS_width
- df["LS_EMA_ChanTop"] = df["LS_EMA"] + LS_EMA_width
- df["LS_EMA_ChanBot"] = df["LS_EMA"] - LS_EMA_width
- #Crossing events against Long short EMA channel
- df["HL2_XUp_LS_ChanTop"] = (np.sign(df["HL2"] - df["LS_EMA_ChanTop"]).diff().fillna(0.0)).gt(0.0)
- df["HL2_XDn_LS_ChanBot"] = (np.sign(df["HL2"] - df["LS_EMA_ChanBot"]).diff().fillna(0.0)).lt(0.0)
- #Create Take profit Ema chan
- TP1_EMA_width = df["ChanWidth"] * TP1_width # normally 0.0 width
- df["TP1_EMA_ChanTop"] = df["TP1_EMA"] + TP1_EMA_width
- df["TP1_EMA_ChanBot"] = df["TP1_EMA"] - TP1_EMA_width
- #Crossing events against Take profit EMA chan
- df["HL2_XDn_TP1_ChanBot"] = (np.sign(df["HL2"] - df["TP1_EMA_ChanBot"]).diff().fillna(0.0)).lt(0.0) # HL2 XDn ChanBot ##why bother with fillna ?
- df["HL2_XUp_TP1_ChanTop"] = (np.sign(df["HL2"] - df["TP1_EMA_ChanTop"]).diff().fillna(0.0)).gt(0.0) # HL2 XUp ChanTop
- #df["H2_XUp_TP1_ChanTop"] = (np.sign(df["HL2"] - df["TP1_EMA_ChanTop"]).diff().fillna(0.0)).gt(0.0)
- #df["HL2_XDn_TP1_ChanBot"] = (np.sign(df["HL2"] - df["TP1_EMA_ChanBot"]).diff().fillna(0.0)).lt(0.0)
- #Create Stop Ema chan
- Stop_EMA_width = df["ChanWidth"] * stop_ema_width # normally 0.0 width
- df["Stop_EMA_ChanTop"] = df["Stop_EMA"] + Stop_EMA_width
- df["Stop_EMA_ChanBot"] = df["Stop_EMA"] - Stop_EMA_width
- #Crossing events against stop EMA chan
- df["HL2_XDn_Stop_ChanBot"] = (np.sign(df["HL2"] - df["Stop_EMA_ChanBot"]).diff().fillna(0.0)).lt(0.0) # HL2 XDn ChanBot ##why bother with fillna ?
- df["HL2_XUp_Stop_ChanTop"] = (np.sign(df["HL2"] - df["Stop_EMA_ChanTop"]).diff().fillna(0.0)).gt(0.0) # HL2 XUp ChanTop
- #Create target Ema chan
- Target_EMA_width = df["ChanWidth"] * target_width
- df["Target_EMA_ChanTop"] = df["LS_EMA"] + Target_EMA_width ## offset from the LS_EMA
- df["Target_EMA_ChanBot"] = df["LS_EMA"] - Target_EMA_width
- #Crossing events against profit target defined as a channel with width from an ema.
- df["HL2_XDn_Target_ChanBot"] = (np.sign(df["HL2"] - df["Stop_EMA_ChanBot"]).diff().fillna(0.0)).lt(0.0) # HL2 XDn ChanBot ##why bother with fillna ?
- df["HL2_XUp_Target_ChanTop"] = (np.sign(df["HL2"] - df["Stop_EMA_ChanTop"]).diff().fillna(0.0)).gt(0.0) # HL2 XUp ChanTop
- # This doesnt do widths
- #cross_TP1_ema = np.sign(df["HL2"] - df["TP1_EMA"]).diff().fillna(0.0) ## -2, 0 or +1 .... Most of the time this is zero.. also dont backfill this
- #df["HL2_XUp_TP1"] = cross_TP1_ema.gt(0.0)
- #df["HL2_XDn_TP1"] = cross_TP1_ema.lt(0.0)
- #df["YYYDayHigh"] = pd.rolling_max(df["High"].shift(1), new_high_periods, min_periods = new_high_periods).bfill()
- #df["YYYDayLow"] = pd.rolling_min(df["Low"].shift(1), new_low_periods, min_periods = new_low_periods).bfill()
- df["LongRollingStopPrice"] = pd.rolling_min(df["Low"].shift(1), stop_window, min_periods = stop_window).bfill()
- df["ShortRollingStopPrice"] = pd.rolling_max(df["High"].shift(1), stop_window, min_periods = stop_window).bfill()
- # df["SignAbvBel"] = np.sign(df["Close"] - df["EMA"]).bfill()
- #df["DaysBelow"] = (df["Close"].lt( df["EMA"])).bfill()
- #df["DaysAbove"] = (df["Close"].gt( df["EMA"])).bfill()
- #df["RollingSumDaysBelow"] = pd.rolling_sum(df["DaysBelow"], window = count_days_below_window, min_periods = count_days_below_window).bfill() ##fillna instead ?
- #df["RollingSumDaysAbove"] = pd.rolling_sum(df["DaysAbove"], window = count_days_below_window, min_periods = count_days_below_window).bfill() ## this might not be necessary
- #df["RollingSumBelowEnough"] = df["RollingSumDaysBelow"].gt(excess_days_AbvBel_threshold) #| df["RollingSumDaysBelow"].lt(count_days_below_window - excess_days_AbvBel_threshold)
- #df["RollingSumAboveEnough"] = df["RollingSumDaysAbove"].gt(excess_days_AbvBel_threshold) #| df["RollingSumDaysAbove"].lt(count_days_below_window - excess_days_AbvBel_threshold)
- #df["HighCrossedAboveYYYDayHighBool"] = (np.sign(df["High"] - df["YYYDayHigh"]).diff().fillna(0.0)).gt(0.0)
- #df["LowCrossedBelowYYYDayLowBool"] = (np.sign(df["Low"] - df["YYYDayLow"]) .diff().fillna(0.0)).lt(0.0)
- """Bias mode... Only go long if "EMA2 > EMA200".... or more complex like "EMA2 > EMA10 && EMA10 > EMA20 && EMA20 > EMA40 && EMA 40 > EMA200"
- Only go short if "EMA2 < EMA200".... or more complex like "EMA2 > EMA10 && EMA10 > EMA20 && EMA20 > EMA40 && EMA 40 > EMA200"
- """
- df["50DayEma"] = pd.ewma(df.Close, min_periods= ( 50*7)-1, span = 50*7).bfill()
- df["100DayEma"] = pd.ewma(df.Close, min_periods= (100*7)-1, span = 100*7).bfill()
- df["200DayEma"] = pd.ewma(df.Close, min_periods= (200*7)-1, span = 200*7).bfill()
- df["LongBias"] = (df["HL2"] > df["50DayEma"]) & (df["50DayEma"] > df["100DayEma"]) & (df["100DayEma"] > df["200DayEma"])
- df["ShortBias"] = (df["HL2"] < df["50DayEma"]) & (df["50DayEma"] < df["100DayEma"]) & (df["100DayEma"] < df["200DayEma"])
- #What about SPY above/below 100/200 day (only if stock correlates with SPY movements?)
- df["ActiveDiff"] = df["Active"].diff().fillna(0)
- #df["GoLong"] = df["HighCrossedAboveYYYDayHighBool"] | (df["CrossUpEma"] & df["RollingSumBelowEnough"])
- #df["GoShort"] = df["LowCrossedBelowYYYDayLowBool"] | (df["CrossDnEma"] & df["RollingSumAboveEnough"])
- #alt df["GoLong"] = df["HL2_XUp_LS_ChanTop"] & df["Active"]
- #alt df["GoShort"] = df["HL2_XDn_LS_ChanBot"] & df["Active"]
- df["GoLong"] = df["HL2_XDn_LS_ChanBot"] & df["Active"]
- df["GoShort"] = df["HL2_XUp_LS_ChanTop"] & df["Active"]
- df["LTP1"] = df["HL2_XDn_TP1_ChanBot"] & df["Active"]
- df["STP1"] = df["HL2_XUp_TP1_ChanTop"] & df["Active"]
- df["LongStopEMA_Hit"] = df["HL2_XDn_Stop_ChanBot"] & df["Active"]
- df["ShortStopEMA_Hit"] = df["HL2_XUp_Stop_ChanTop"] & df["Active"]
- df["LongTargetEMA_Hit"] = df["HL2_XUp_Target_ChanTop"] & df["Active"]
- df["ShortTargetEMA_Hit"] = df["HL2_XDn_Target_ChanBot"] & df["Active"]
- #df["BuyToCover"] = (df["XUpEma2"] & df["Active"]) | df["ActiveDiff"] == -1
- df["AlgoActive"] = True
- df["NumSharesTraded"] = 0.0
- df["ValueSharesTraded"] = 0.0
- df["CashInHand"] = np.NaN
- df["CashInvested"] = np.NaN
- df["NumSharesHeld"] = np.NaN
- # df["ShareCost"] = np.NaN
- df["ValueSharesHeld"] = np.NaN
- df["AccountIsWorth"] = np.NaN
- df["Profit"] = np.NaN
- df['BuyPrice'] = np.NaN
- df['SellPrice'] = np.NaN
- df['ShortPrice'] = np.NaN
- df['BtcPrice'] = np.NaN
- df['LongStopPrice'] = np.NaN
- df['ShortStopPrice'] = np.NaN
- df['LongTargetPrice'] = np.NaN
- df['ShortTargetPrice'] = np.NaN
- df['LTP1_Price'] = np.NaN
- df['STP1_Price'] = np.NaN
- df['TradeOpenPrice'] = np.NaN
- df['TheEnd'] = False #need this to check stop losses to end of data
- df['TheEnd'][-1] = True
- df2 = df[(df.GoLong == True) | #or
- (df.GoShort == True) | #or
- #(df.SellFlat == True) | # or
- #(df.BuyToCover == True) | # or
- (df.LTP1 == True) | # or
- (df.STP1 == True) | # or
- (df.LongStopEMA_Hit == True) | # or
- (df.ShortStopEMA_Hit == True) | # or
- (df.LongTargetEMA_Hit == True) | # or
- (df.ShortTargetEMA_Hit == True) | # or
- (df.ActiveDiff == True) | # or
- df['TheEnd']
- ]
- if df2.shape[0] == 0:
- return None
- self.cashInHand = 10000
- df["CashInHand"][0] = 10000
- self.numSharesHeld = 0
- # rowIter = enumerate(df2.iterrows())
- rowIter = df2.iterrows()
- self.backfill_start_i = None
- self.trade_open_price = 200 ## avoid blowup in MakeTrade(
- self.TP1_Taken = False
- #for (today_i, today) in rowIter:
- while (True):
- try:
- data_i, data = rowIter.next()
- except StopIteration:
- break
- trace = False
- #if data_i > pd.Period(year = 2013, month = 11, day = 13, hour = 14, freq = "H"):
- # print "Its time"
- # #import pdb
- # #pdb.set_trace()
- # #trace = True
- # trace = True
- self.someSharesTraded = False
- self.close = data['Close']
- self.NumSharesTraded = 0
- self.ValueSharesTraded = 0
- if trace:
- print "data : " + str(data)
- vars = ["LS_ema", "LS_width", "TP1_ema", "TP1_pct", "TP1_width", "TP1_profitWidth", "target_width", "stop_ema", "stop_ema_width", "stop_window",]
- print [(a,eval(a)) for a in vars]
- vars2 = ["self.numSharesHeld", "self.long_stop_price", "self.cashInHand", ]
- print [(a,eval(a)) for a in vars2]
- #First check if stops were hit..
- if self.numSharesHeld > 0: # if long
- if self.backfill_start_i is not None: # sanity check
- df3 = df.loc[self.backfill_start_i:data_i] # inclusive range so we shouldnt use backfill_start_i but instead use the next valid day.. Cant find how to do that in the book !
- df3['LongStopPrice'] = self.long_stop_price #fill in the stop_price on preceeding days if we have a trade open
- df3['LongTargetPrice'] = self.long_target_price #and the target price
- df3['TradeOpenPrice'] = self.trade_open_price
- df4 = df3[df3.Low < self.long_stop_price]
- if (df4.shape[0] > 0):
- sell_day_i = df4.index[0]
- if (sell_day_i == data_i):
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.long_stop_price, "SellPrice", None)
- else:
- self.MakeTrade(df, None, sell_day_i, -self.numSharesHeld, self.long_stop_price, "SellPrice", None)
- df5 = df3[df3.High > self.long_target_price]
- if (df5.shape[0] > 0):
- sell_day_i = df5.index[0]
- if (sell_day_i == data_i):
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.long_target_price, "LTP1_Price", None)
- else:
- self.MakeTrade(df, None, sell_day_i, -self.numSharesHeld, self.long_target_price, "LTP1_Price", None)
- else:
- print "Insanity"
- elif self.numSharesHeld < 0: #if short
- if self.backfill_start_i is not None: # sanity check
- df3 = df.loc[self.backfill_start_i:data_i] # inclusive range so we shouldnt use backfill_start_i but instead use the next valid day.. Cant find how to do that in the book !
- df3['ShortStopPrice'] = self.short_stop_price #fill in the stop_price on preceeding days if we have a trade open
- df3['ShortTargetPrice'] = self.short_target_price #and the short target price
- df3['TradeOpenPrice'] = self.trade_open_price
- df4 = df3[df3.High > self.short_stop_price]
- if (df4.shape[0] > 0):
- btc_day_i = df4.index[0]
- if (btc_day_i == data_i):
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.short_stop_price, "BtcPrice", None) ## this isnt quite righ.. price can gap past the stop price meaning it was impossible to attain
- else:
- self.MakeTrade(df, None, btc_day_i, -self.numSharesHeld, self.short_stop_price, "BtcPrice", None) ## this isnt quite righ.. price can gap past the stop price meaning it was impossible to attain
- df5 = df3[df3.Low < self.short_target_price]
- if (df5.shape[0] > 0):
- btc_day_i = df5.index[0]
- if (btc_day_i == data_i):
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.short_target_price, "STP1_Price", None) ## this isnt quite righ.. price can gap past the stop price meaning it was impossible to attain
- else:
- self.MakeTrade(df, None, btc_day_i, -self.numSharesHeld, self.short_target_price, "STP1_Price", None) ## this isnt quite righ.. price can gap past the stop price meaning it was impossible to attain
- else:
- print "Insanity short"
- if data['LongStopEMA_Hit'] and self.numSharesHeld > 0:
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, "SellPrice", None)
- if data['ShortStopEMA_Hit'] and self.numSharesHeld < 0:
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, "BtcPrice", None)
- if (data['GoLong']):
- if data["LongBias"]:
- if (self.numSharesHeld < 0):
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, None, None)
- if (self.numSharesHeld == 0):
- self.MakeTrade(df, data, data_i, self.cashInHand / self.close, self.close, "BuyPrice", data["LongRollingStopPrice"])
- self.long_stop_price = data["LongRollingStopPrice"]
- self.long_target_price = data["Target_EMA_ChanTop"] #data["TP1_EMA_ChanTop"]# data["Target_EMA_ChanTop"]
- self.TP1_Taken = False
- #else:
- # if (self.numSharesHeld < 0):
- # self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, "BtcPrice")
- if (data['GoShort']):
- if data["ShortBias"]:
- if (self.numSharesHeld > 0):
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, None, None)
- if (self.numSharesHeld == 0):
- self.MakeTrade(df, data, data_i, -self.cashInHand / self.close, self.close, "ShortPrice", data["ShortRollingStopPrice"])
- self.short_stop_price = data["ShortRollingStopPrice"]
- self.short_target_price = data["Target_EMA_ChanBot"] #data["TP1_EMA_ChanBot"] #data["Target_EMA_ChanBot"]
- self.TP1_Taken = False
- #else:
- # if (self.numSharesHeld > 0):
- # self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, "SellPrice")
- if (data['LTP1']):
- if data["LongBias"] == False:
- if self.numSharesHeld > 0:
- if self.TP1_Taken == False:
- if (self.close - self.trade_open_price) > (data["ChanWidth"] * TP1_profitWidth):
- self.MakeTrade(df, data, data_i, -self.numSharesHeld * TP1_pct, self.close, "LTP1_Price", None)
- self.TP1_Taken = True
- #else:
- # print "Not enough profit - need " + str(data["ChanWidth"] * TP1_profitWidth) + ". But got : " + str(self.close - self.trade_open_price)
- if (data['STP1']):
- if data["ShortBias"] == False:
- if self.numSharesHeld < 0:
- if self.TP1_Taken == False:
- if (self.close - self.trade_open_price) < -(data["ChanWidth"] * TP1_profitWidth):
- self.MakeTrade(df, data, data_i, -self.numSharesHeld * TP1_pct, self.close, "STP1_Price", None)
- self.TP1_Taken = True
- #else:
- # print "Not enough profit - need " + str(data["ChanWidth"] * TP1_profitWidth) + ". But got : " + str(-(self.close - self.trade_open_price))
- if data['TheEnd']:
- if self.numSharesHeld > 0:
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, "SellPrice", None)
- elif self.numSharesHeld < 0:
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, "BtcPrice", None)
- if data["ActiveDiff"] < 0:
- if self.numSharesHeld > 0:
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, "SellPrice", None)
- elif self.numSharesHeld < 0:
- self.MakeTrade(df, data, data_i, -self.numSharesHeld, self.close, "BtcPrice", None)
- if self.someSharesTraded:
- df.loc[data_i] = data
- if self.numSharesHeld == 0:
- self.backfill_start_i = None #nothing to fill
- else:
- self.backfill_start_i = data_i #keep moving this forward so we're filling in new date ranges with upto date values.
- df["NumSharesHeld"].ffill(axis = 0, inplace = True)
- df["CashInHand"]. ffill(axis = 0, inplace = True)
- df["CashInvested"]. ffill(axis = 0, inplace = True)
- # df["ShareCost"]. ffill(axis = 0, inplace = True)
- df["NumSharesHeld"]. fillna(0.0, inplace = True)
- t1 = np.abs(df['NumSharesHeld']) * df["TradeOpenPrice"]
- t1.fillna(0.0, inplace = True)
- t2 = df["Close"] - df["TradeOpenPrice"] #has nulls but good
- df['ValueSharesHeld'] = t1 + (t2 * df['NumSharesHeld']).fillna(0.0)
- df['AccountIsWorth'] = df['CashInHand'].fillna(0.0) + df['ValueSharesHeld'].fillna(0.0)
- df['Profit'] = df['AccountIsWorth'] - 10000.0
- df["CashInHand"]. fillna(0.0, inplace = True)
- df["CashInvested"]. fillna(0.0, inplace = True)
- # df["ShareCost"]. fillna(0.0, inplace = True)
- df["ValueSharesHeld"]. fillna(0.0, inplace = True)
- df["AccountIsWorth"]. fillna(0.0, inplace = True)
- df["Profit"]. fillna(0.0, inplace = True)
- return df
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement