def makeBuyAction(api: sj.Shioaji, buy: list, choose: list): for id in buy: # if id in choose: # con(api).StockNormalBuySell(stkid = id, price = "up", qty = 1, action = "Buy") # logger.info(f"Buy {id}(漲停)") # continue con(api).StockNormalBuySell(stkid=id, price="down", qty=1, action="Buy") logger.info(f"Buy {id}(跌停)") # 休息5秒,取得成交回報 time.sleep(5)
def writeDailyMinsKbarDataToDB(api=None): no_update = [] tb = cfg().getValueByConfigFile(key="tb_mins") sql = f"SELECT StockID, MAX(TradeDate) as TradeDate FROM {tb} group by StockID" stkldayDF = db().selectDatatoDF(sql_statment=sql) bcDF = db().selectDatatoDF(cfg().getValueByConfigFile(key="tb_basic")) bcDF = bcDF.merge(stkldayDF, on=["StockID"], how="left") for index, row in bcDF.iterrows(): try: udate = row.TradeDate + timedelta(days=1) except: udate = date.today() - timedelta(days=300) if udate > date.today(): continue stkDF = con(api).getKbarData( stkid=row.StockID, sdate=udate.strftime("%Y-%m-%d"), edate=date.today().strftime("%Y-%m-%d")).filter(items=[ "StockID", "TradeDate", "TradeTime", "Open", "High", "Low", "Close", "Volume" ]) if stkDF.empty: # 不是遇到週末才需要show沒有成功的部份 if udate.weekday() not in (5, 6): no_update.append(row.StockID) continue stkDF = stkDF.drop_duplicates( subset=["StockID", "TradeDate", "TradeTime"], keep="first") print(f"StockID: {row.StockID}") db().updateDFtoDB(stkDF, tb_name=tb) if no_update != []: print(f"沒有更新的Stock如下:{no_update}")
def getNewBuyDFforGetDealOrder(api_in, buylist: list): outBuyDF = pd.DataFrame() outbuylist = [] if GdealDF.empty: con(api_in).StockCancelOrder() sys.exit() for idx, row in GdealDF.iterrows(): if row.Action == "Buy": l = [] outbuylist.append(row.StockID) l.append(row.StockID) l.append(row.Price) l.append(round(int(row.Price) * 1.01, 1)) l.append(round(int(row.Price) * (1 - 0.02), 1)) outBuyDF = outBuyDF.append( [l], columns=["StockID", "Buy", "UP", "DOWN"]) diff = list(set(buylist).difference(outbuylist)) if diff != []: for stkID in diff: con(api_in).StockCancelOrder(stkID) return outBuyDF
def writeDailyRawDataDB(api=None, StkDF: pd.DataFrame = None): tb = cfg().getValueByConfigFile(key="tb_daily") sql = f"SELECT StockID, MAX(TradeDate) as TradeDate FROM {tb} group by StockID" lastday_stocks = db().selectDatatoDF(sql_statment=sql) kBarDF = pd.DataFrame() for index, row in StkDF.iterrows(): udate = datetime.strptime(row["update_date"], "%Y/%m/%d").date() try: lastday = lastday_stocks.loc[lastday_stocks.StockID == row["StockID"], "TradeDate"].values[0] except: lastday = udate - timedelta(days=400) if lastday < udate: DF = con(api).getKbarData( stkid=row["StockID"], sdate=(lastday + timedelta(days=1)).strftime("%Y-%m-%d"), edate=udate.strftime("%Y-%m-%d")) kBarDF = kBarDF.append(DF) # 資料庫有資料 kBarDF就可能是空的 if not kBarDF.empty: # kBarDF = kBarDF.filter(items = ["StockID", "TradeDate", "TradeTime", "Open", "High", "Low", "Close", "Volume"]).drop_duplicates(subset = ["StockID", "TradeDate", "TradeTime"], keep = "first") kBarDF = kBarDF.filter(items=[ "StockID", "TradeDate", "TradeTime", "Open", "High", "Low", "Close", "Volume" ]) DkBarDF = kBarDF.groupby(["StockID", "TradeDate"], sort=True).agg({ "Open": "first", "High": max, "Low": min, "Close": "last", "Volume": sum }).reset_index() # 每日的OHLC資料 if not DkBarDF.empty: db().updateDFtoDB(DkBarDF, tb_name=tb)
except Exception as exc: logger.error(f"Tick to DF error! {exc}") # return pd.DataFrame(getTrend, columns = ["StockID", "Trend"]) # 先檢查資料夾是否存在..沒有就建立 tool.checkCreateYearMonthPath() pid = os.getpid() # 開始log logger = create_logger("./logs") logger.info(f"Start PID = {pid}") check_secs = 20 # 1.連接Server,指定帳號(預設chris),使用的CA(預設None) api = con().ServerConnectLogin(ca="chris") # api = con().ServerConnectLogin(simulte = True) # 註:更換另一個帳號 # con(api).ChangeTradeCA(ca = "lydia") # 1.1 設定回報Tick/Event資料 @api.on_tick_stk_v1() def quote_callback(exchange: Exchange, tick: TickSTKv1): global ticks l = [] l.append(tick.code) l.append(tick.datetime.strftime("%H:%M:%S.%f")) l.append(tick.open) # l.append(tick.avg_price)
# con(api).StockNormalBuySell(stkid = id, price = "down", qty = 1, action = "Buy") # logger.info(f"Buy {id}(跌停)") # # 休息5秒,取得成交回報 # time.sleep(5) if __name__ == "__main__": # 先檢查資料夾是否存在..沒有就建立 tool.checkCreateYearMonthPath() # 開始log logger = create_logger("./logs") # 設定更新秒數 wait_secs = 20 # 1.連接Server,指定帳號(預設chris),使用的CA(預設None) api = con().ServerConnectLogin(ca="chris") # 2.取得股票清單(只留下可以當沖的) stkDF = file.getPreviousTransactionFocusStockDF() stkLst = tool.DFcolumnToList(stkDF, "StockID") contracts = con(api).getContractForAPI(stkDF) # 3.訂閱/回報 # 3.1 設定交易即時回報 api.set_order_callback(placeOrderCallBack) # 3.2 設定回報資料(Tick / Bidask / Event) @api.on_tick_stk_v1() def quote_callback_tick(exchange: Exchange, tick: TickSTKv1): global ticks l = [] l.append(tick.code)
columns={ "ts": "TradeDateTime", "close": "Close", "volume": "Volume", "bid_price": "BidPrice", "bid_volume": "BidVolume", "ask_price": "AskPrice", "ask_volume": "AskVolume" }) db().updateDFtoDB(tickDF, tb_name="dailyticks") # 先檢查資料夾是否存在..沒有就建立 tool.checkCreateYearMonthPath() api = con().ServerConnectLogin(user="******") BsData = con(api).getStockDataByCondition() writeDailyFocusStockTicks(api) writeDailyMinsKbarDataToDB(api) writeDailyKbarDataToDB(BsData) writeDailyRawDataDB(api, BsData) # 這支去補足前面漏的 writeLegalPersonDailyVolumeDB(BsData) # 取得每天的成交資料(後面數字是往回抓幾天) stkDF = getStockDailyDataFromDB(BsData, 250) stkDFwithInd = ind( stkDF).addMAvalueToDF() # Default ma_type = SAR, period = [5, 10, 20, 60] stkDFwithInd = ind( stkDFwithInd).addBBANDvalueToDF() # Default period = 10, sigma = 2
def getExcuteTime(): extime = "09:05" if sim().checkSimulationTime(): extime = (datetime.now() + timedelta(minutes = 2)).strftime("%H:%M") return extime # 先檢查資料夾是否存在..沒有就建立 tool.checkCreateYearMonthPath() ticks = [] ticksDF = pd.DataFrame() chk_sec = 20 # 1.連接Server,指定帳號(預設chris),使用的CA(預設None) api = con().ServerConnectLogin( user = "******") @api.on_tick_stk_v1() def quote_callback(exchange: Exchange, tick:TickSTKv1): global ticks l = [] l.append(tick.code) l.append(tick.datetime.strftime("%H:%M:%S.%f")) l.append(tick.open) # l.append(tick.avg_price) l.append(tick.close) l.append(tick.high) l.append(tick.low) # l.append(tick.amount) # l.append(tick.total_amount) l.append(tick.volume)