diff --git a/resources/python-3.8.2.exe b/resources/python-3.8.2.exe new file mode 100644 index 0000000..5bfe098 Binary files /dev/null and b/resources/python-3.8.2.exe differ diff --git a/resources/tesseract-ocr-w64-setup-5.3.3.20231005.exe b/resources/tesseract-ocr-w64-setup-5.3.3.20231005.exe new file mode 100644 index 0000000..2c0658e Binary files /dev/null and b/resources/tesseract-ocr-w64-setup-5.3.3.20231005.exe differ diff --git a/resources/ths.z01 b/resources/ths.z01 new file mode 100644 index 0000000..45d70cf Binary files /dev/null and b/resources/ths.z01 differ diff --git a/resources/ths.z02 b/resources/ths.z02 new file mode 100644 index 0000000..0706f0e Binary files /dev/null and b/resources/ths.z02 differ diff --git a/resources/ths.zip b/resources/ths.zip new file mode 100644 index 0000000..59dafeb Binary files /dev/null and b/resources/ths.zip differ diff --git a/src/real_trader.py b/src/real_trader.py new file mode 100644 index 0000000..b358d1a --- /dev/null +++ b/src/real_trader.py @@ -0,0 +1,51 @@ +import easytrader +import time + +""" +需要32位python +""" + + +class RealTrader: + def __init__(self): + pass + + def login(self): + self.trader = easytrader.use("universal_client") + try: + self.trader.prepare( + user="35207457", password="351916", exe_path=r"C:\\ths\\xiadan.exe" + ) + except Exception as e: + time.sleep(3) + self.trader.connect(r"C:\\ths\\xiadan.exe") + + def logout(self): + self.trader.exit() + + def get_balance(self): + return self.trader.balance + + def get_positions(self): + return self.trader.position + + # 查询当日成交 + def get_today_trades(self): + return self.trader.today_trades + + # 查询当日委托 + def get_today_entrust(self): + return self.trader.today_entrusts + + # 刷新数据 + def refresh(self): + self.trader.refresh() + + def buy(self, code, price, amount): + self.trader.buy(code, price, amount) + + def sell(self, code, price, amount): + self.trader.sell(code, price, amount) + + def cancel(self, entrust_no): + self.trader.cancel_entrust(entrust_no) diff --git a/src/requirements.txt b/src/requirements.txt new file mode 100644 index 0000000..8ecc479 --- /dev/null +++ b/src/requirements.txt @@ -0,0 +1,7 @@ +easytrader==0.23.0 +Flask==3.0.3 +pywin32==306 +requests==2.31.0 +schedule==1.2.1 +virtualenv==20.25.3 + diff --git a/src/trade_server.py b/src/trade_server.py new file mode 100644 index 0000000..9c90a7c --- /dev/null +++ b/src/trade_server.py @@ -0,0 +1,171 @@ +import schedule +import threading +import time +from real_trader import RealTrader +from flask import Flask, request, abort, jsonify + + +def run_daily(time_str, job_func): + schedule.every().monday.at(time_str).do(job_func) + schedule.every().tuesday.at(time_str).do(job_func) + schedule.every().wednesday.at(time_str).do(job_func) + schedule.every().thursday.at(time_str).do(job_func) + schedule.every().friday.at(time_str).do(job_func) + + +def run_pending_tasks(): + while True: + schedule.run_pending() + time.sleep(1) + + +# Run the task scheduler in a new thread +threading.Thread(target=run_pending_tasks).start() +trader = RealTrader() + +### test code start +# trader.login() +# time.sleep(5) +# trader.logout() +### test code end + +# 打开并登陆交易软件 +run_daily("09:00", lambda: trader.login()) +# 关闭交易软件 +run_daily("15:30", lambda: trader.logout()) + + +app = Flask(__name__) + + +@app.route("/yu/healthcheck", methods=["GET"]) +def health_check(): + return "ok", 200 + + +@app.route("/yu/buy", methods=["POST"]) +def buy(): + """Buy an item with given parameters.""" + # Get data from request body + data = request.get_json() + code = data.get("code") + price_str = data.get("price") + amount_str = data.get("amount") + + try: + price = float(price_str) + amount = int(amount_str) + print(f"buy: {code}, {price}, {amount}") + result = trader.buy(code, price, amount) + + response = {"success": True, "message": result} + return jsonify(response), 200 + except ValueError: + abort( + 400, + description="Invalid format for one or more of the following args: code, price, amount.", + ) + + +@app.route("/yu/sell", methods=["POST"]) +def sell(): + """Sell an item with given parameters.""" + # Get data from request body + data = request.get_json() + code = data.get("code") + price_str = data.get("price") + amount_str = data.get("amount") + + try: + price = float(price_str) + amount = int(amount_str) + print(f"sell: {code}, {price}, {amount}") + result = trader.sell(code, price, amount) + + response = {"success": True, "message": result} + return jsonify(response), 200 + except ValueError: + abort( + 400, + description="Invalid format for one or more of the following args: code, price, amount.", + ) + + +@app.route("/yu/cancel/", methods=["DELETE"]) +def cancel(entrust_no): + print(f"cancel: {entrust_no}") + result = trader.cancel(entrust_no) + + response = {"success": True, "message": result} + return jsonify(response), 200 + + +@app.route("/yu/balance", methods=["GET"]) +def get_balance(): + """Get the balance of the account.""" + balance = trader.get_balance() + print(f"balance: {balance}") + + response = { + "success": True, + "message": "Balance retrieved successfully.", + "data": balance, + } + return jsonify(response), 200 + + +@app.route("/yu/positions", methods=["GET"]) +def get_positions(): + """Get the positions of the account.""" + positions = trader.get_positions() + + response = { + "success": True, + "message": "Positions retrieved successfully.", + "data": positions, + } + return jsonify(response), 200 + + +@app.route("/yu/todaytrades", methods=["GET"]) +def get_today_trades(): + """Get the today's trades of the account.""" + trades = trader.get_today_trades() + + response = { + "success": True, + "message": "Today's trades retrieved successfully.", + "data": trades, + } + return jsonify(response), 200 + + +@app.route("/yu/todayentrust", methods=["GET"]) +def get_today_entrust(): + """Get the today's entrust of the account.""" + entrust = trader.get_today_entrust() + + response = { + "success": True, + "message": "Today's entrust retrieved successfully.", + "data": entrust, + } + return jsonify(response), 200 + + +@app.route("/yu/refresh", methods=["GET"]) +def refresh(): + """Refresh the account.""" + trader.refresh() + + response = { + "success": True, + "message": "Account data refreshed successfully.", + } + return jsonify(response), 200 + + +if __name__ == "__main__": + PORT = 9527 + print(f"Server listening on port {PORT}") + app.run(debug=False, host="0.0.0.0", port=PORT)