class macd(object): ''' ��д�������������������� ''' def __init__(self): self.db = MongoDB(DB_SERVER, DB_PORT, USER, PWD, AUTHDBNAME) self.looplist = [] def setlooplist(self, lst=[]): excludelst = [ "399001.SZ", "399006.SZ", "000001.SH", "000300.SH", "399005.SZ" ] if not lst: self.looplist = [ i for i in self.db.getallcollections("stockdatas") if i not in excludelst ] else: self.looplist = lst return self.looplist def buycondition(self, data): '''out = ["macd","cross_dist"]''' if data["macd"] > 0 and data["cross_dist"] == 0 \ and data["diff12_26"] < 0: return True return False def enhancebuycondition(self, data): if data["macd"] < 0 and data["diff12_26"] < 0: return True return False def sellcondition(self, data): pass def getlastbuylst(self, ): dbname = "stockdatas" num = 1 filt = [{"$sort": {"date": -1}}, {"$limit": num}] buylst = [] enhancebuylst = [] for i in self.looplist: collection = i query = self.db.read_data(dbname, collection, filt, is_aggregate=True) data = [i for i in query] if self.buycondition(data[0]): buylst.append(i) # print ("normal condition buy stock:{}".format(i)) query = self.db.read_data(dbname, collection, [{ "$sort": { "date": -1 } }, { "$match": { "cross_dist": 0, "macd": { "$ne": 0 } } }, { "$limit": 2 }], is_aggregate=True) newdata = [i for i in query] if self.enhancebuycondition(newdata[1]): enhancebuylst.append(i) print("enhance condition buy stock:{}".format(i)) return buylst, enhancebuylst def gethistorybuylst(self, starttime="2011-01-01"): dbname = "stockdatas" filt = [{ "$sort": { "date": 1 } }, { "$match": { "date": { "$gt": starttime } } }] buylst = [] enhancebuylst = [] for i in self.looplist: collection = i query = self.db.read_data(dbname, collection, filt, is_aggregate=True) data = [i for i in query] for record in data: if self.buycondition(record): buylst.append([i, record["date"], record["close"]]) # print ([i,record["date"],record["close"]]) idx = data.index(record) precross = idx - data[idx - 1]["cross_dist"] - 1 if precross >= 0 and self.enhancebuycondition( data[precross]): enhancebuylst.append(i) print([i, record["date"], record["close"]]) return buylst, enhancebuylst def gettraderecord(self, starttime="2011-01-01"): pass def getcurrentdata(self): '''code:代码, name:名称 ,changepercent:涨跌幅 , trade:现价 ,open:开盘价 ,high:最高价, low:最低价, settlement:昨日收盘价 , volume:成交量 ,turnoverratio:换手率 ,amount:成交量 ,per:市盈率 ,pb:市净率, mktcap:总市值 ,nmc:流通市值 ''' out = ["code", "trade", "open", "high", "low", "settlement"] rst = ts.get_today_all() return rst[out].set_index('code') def gettradebuylst(self): dbname = "stockdatas" num = 1 emaslow = 26 emafast = 12 demday = 9 filt = [{"$sort": {"date": -1}}, {"$limit": num}] buylst = [] currentdata = self.getcurrentdata() for i in self.looplist: collection = i query = self.db.read_data(dbname, collection, filt, is_aggregate=True) data = [i for i in query] s_ema = data[0]["ema26"] f_ema = data[0]["ema12"] dem = data[0]["dem9"] macd = data[0]["macd"] try: c_close = currentdata["trade"].ix[collection.split(".")[0]] n_s_ema = (s_ema * (emaslow - 1) + 2 * c_close) / (emaslow + 1) n_f_ema = (f_ema * (emafast - 1) + 2 * c_close) / (emafast + 1) n_diff = n_f_ema - n_s_ema n_dem = (dem * (demday - 1) + 2 * n_diff) / (demday + 1) n_macd = 2 * (n_diff - n_dem) if macd * n_macd < 0 and n_macd > 0: buylst.append(collection) except: print("error stock:{}".format(collection)) [print("buylist:{}".format(collection)) for collection in buylst] return buylst def save2db(self): pass def save2csv(self): pass
class basestrategy(object): ''' trading volume is the lowest in 60 days ''' def __init__(self, startdate=(2011, 1, 1), enddate=[]): self.startdate = datetime.datetime(*startdate, 0, 0, 0, 0) self.enddate = enddate self.m = MongoDB(DB_SERVER, DB_PORT, USER, PWD, AUTHDBNAME) self.formatlist = [ "date", "volume", "close", "high", "low", "open", "pre_close" ] self.savevols = [ "stock", "buy_date", "sell_date", "holddays", "profit", "features" ] self.looplist = [] self.trading_records = [] self.holding_records = [] self.datalst = [] self.collection = None self.tempstatus = [] self.lateststatus = [] def setlooplist(self, lst=[]): if not lst: self.looplist = self.m.getallcollections("ml_security_table") else: self.looplist = lst return self.looplist def _getdata(self, collection="600455.SH", db="ml_security_table", out=[], isfilt=True, filt={}): if not out: out = self.formatlist if isfilt and not filt: filt = {"date": {"$gt": self.startdate}} query = self.m.read_data(db, collection, filt=filt) return self.formatquery(query, out) def formatquery(self, query, out): ''' query:your source data ,should be a list with dict out:the fields you want to convert into dataframe ''' if not out: query = [i for i in query.sort("date", 1)] else: query = [{k: i[k] for k in out} for i in query.sort("date", 1)] return pd.DataFrame(query) def buy(self, line, count): return False def sell(self, line, count, holding_record): traderecord = [] return False, traderecord def setenv(self, collection): self.collection = collection data = self._getdata(collection) self.datalst = [ l for l in data[self.formatlist].fillna(0).values if l[1] != 0 ] self.datalst = self.rehabilitation(self.datalst) return def rehabilitation(self, lst): close = lst[0][2] c = 1 reh = [] for line in lst[1:]: c_preclose = line[6] if c_preclose != close: reh = [[i[0], i[1] * c_preclose / close] for i in reh] reh.append([c, c_preclose / close]) close = line[2] c += 1 result = [] sc = 0 for idx in range(len(reh)): weight = reh[idx][1] ec = reh[idx][0] piece = self.recount(lst, sc, ec, weight) result.extend(piece) sc = ec result.extend(self.recount(lst, ec, -1, 1)) return result def recount(self, lst, sc, ec, weight): rst = [] for line in lst[sc:ec]: rst.append([line[0], line[1], *[i * weight for i in line[2:]]]) return rst def getfeatures(self, count): return [] def historyreturn(self, collection): self.setenv(collection) trading_record = [] holding_record = [] count = 0 lst = self.datalst for line in lst[:]: isbuy = self.buy(lst, count) for b in holding_record[:]: issell, traderecord = self.sell(lst, count, b) if issell: holding_record.remove(b) trading_record.append(traderecord) print(traderecord) if isbuy: feature = self.getfeatures(lst, count) holding_record.append( ([i for i in line], count, collection, feature)) count += 1 # "date","volume","close","high","low","open","pre_close" holdresult = [[ collection, self.timestamp2date(i[0][0]), i[0][2], i[3] ] for i in holding_record] return trading_record, holdresult def looplist_historyreturn(self): for collection in self.looplist: try: tr, hr = self.historyreturn(collection) self.lateststatus.append(self.tempstatus) self.trading_records.extend(tr) self.holding_records.extend(hr) except: print("error: {}".format(collection)) return self.trading_records, self.holding_records def timestamp2date(self, timestamp): try: return str(timestamp).split(" ")[0] except: return timestamp def savetrading2csv(self, filename="trading_records.csv"): df = pd.DataFrame(self.trading_records, columns=self.savevols) df.to_csv(filename) return def savetrading2db(self, db="regressiontraderesult", strategyname="strategytradersult"): db = eval("self.m.client.{}".format(db)) bulk = db[strategyname].initialize_ordered_bulk_op() for line in self.trading_records: bulk.find({'buy_date': line[1]}).upsert().update( \ {'$set': {'stock': line[0], \ 'buy_date': line[1], \ 'sell_date': line[2], \ 'holddays': line[3], \ 'profit': line[4], \ 'features': line[5], \ }}) bulk.execute() return def saveholding2csv(self, filename="holding_records.csv"): df = pd.DataFrame(self.holding_records, columns=["stock", "date", "buy_data", "features"]) df.to_csv(filename) return