Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加回测、模拟和实盘交易功能 #502

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

easonxu77
Copy link

@easonxu77 easonxu77 commented Mar 6, 2025

Summary by CodeRabbit

  • 新功能
    • 引入全新的交易运行功能,支持回测、模拟和实盘三种模式。
    • 提供直观的用户交互界面,指导用户选择合适的交易模式,并针对无效选择给予友好提示。

Copy link

coderabbitai bot commented Mar 6, 2025

📝 Walkthrough

Walkthrough

新增了一个 Python 脚本 example_run.py,提供三种交易模式的执行功能:回测、模拟交易和实盘交易。脚本内定义了 run_backtestrun_simulationrun_real_trading 三个函数分别对应不同交易模式,同时包含一个 main 函数用于接收用户输入并调用相应函数。其中,回测模式设置了日期范围,模拟交易设置了初始余额,实盘交易则配置了账户凭证,并对无效输入进行了错误处理。

Changes

文件 更改摘要
example_run.py 新增函数 run_backtestrun_simulationrun_real_tradingmain,分别用于回测、模拟交易和实盘交易。

Sequence Diagram(s)

sequenceDiagram
    participant 用户 as 用户
    participant Main as main()
    participant API as TqApi

    用户->>Main: 启动程序并选择交易模式
    alt 回测模式
        Main->>API: 调用 run_backtest() 初始化回测环境
    else 模拟模式
        Main->>API: 调用 run_simulation() 初始化模拟环境
    else 实盘模式
        Main->>API: 调用 run_real_trading() 初始化实盘环境
    end
Loading

Poem

我是一只小兔子,跳跃在代码的花园,
新增脚本展新容,回测与模拟轻松玩,
实盘交易展锋芒,
输入选择决策忙,
编程如诗愿幸运,交易路上笑声甜!

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • JIRA integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
example_run.py (2)

1-3: 导入部分结构良好,但可以考虑更加明确的导入方式

代码导入了所需的模块,包括date和多个tqsdk类。但为了更好的代码可读性和维护性,建议考虑使用更明确的导入语句。

-from datetime import date
-from tqsdk import TqApi, TqSim, TqAccount, TqBacktest, TqAuth
+from datetime import date
+from tqsdk import TqApi, TqSim, TqAccount, TqBacktest, TqAuth
+import logging  # 添加日志支持

25-27: 脚本入口点

脚本入口点的结构正确,但缺少一些基本的启动设置。

 if __name__ == "__main__":
+    # 设置基本日志配置
+    import os
+    import logging
+    logging.basicConfig(
+        level=logging.INFO,
+        format='%(asctime)s - %(levelname)s - %(message)s'
+    )
+    
+    # 检查是否有必要的环境变量
+    required_vars = ["TQ_USERNAME", "TQ_PASSWORD"]
+    missing = [var for var in required_vars if not os.environ.get(var)]
+    if missing:
+        print(f"警告: 缺少必要的环境变量: {', '.join(missing)}")
+        print("请设置这些环境变量或在代码中提供这些值")
+    
     main()
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 99411cd and fca9996.

📒 Files selected for processing (1)
  • example_run.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
example_run.py

5-5: Local variable api is assigned to but never used

Remove assignment to unused variable api

(F841)


8-8: Local variable api is assigned to but never used

Remove assignment to unused variable api

(F841)


11-11: Local variable api is assigned to but never used

Remove assignment to unused variable api

(F841)

Comment on lines +13 to +24
def main():
print("请选择运行模式: 1. 回测 2. 模拟 3. 实盘")
choice = input("输入选择(1/2/3): ")
if choice == '1':
run_backtest()
elif choice == '2':
run_simulation()
elif choice == '3':
run_real_trading()
else:
print("无效选择,请输入1, 2或3")

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

主函数需要增强错误处理和用户体验

主函数实现了基本功能,但缺乏适当的异常处理和用户体验优化。

建议修改为:

 def main():
-    print("请选择运行模式: 1. 回测 2. 模拟 3. 实盘")
-    choice = input("输入选择(1/2/3): ")
-    if choice == '1':
-        run_backtest()
-    elif choice == '2':
-        run_simulation()
-    elif choice == '3':
-        run_real_trading()
-    else:
-        print("无效选择,请输入1, 2或3")
+    print("===============================")
+    print("交易系统 v1.0")
+    print("===============================")
+    print("请选择运行模式:")
+    print("1. 回测 - 使用历史数据测试策略")
+    print("2. 模拟 - 使用实时行情进行模拟交易")
+    print("3. 实盘 - 使用实际资金进行交易")
+    print("4. 退出")
+    print("===============================")
+    try:
+        choice = input("请输入选择(1/2/3/4): ")
+        if choice == '1':
+            run_backtest()
+        elif choice == '2':
+            run_simulation()
+        elif choice == '3':
+            confirm = input("确认要进行实盘交易吗?(y/n): ")
+            if confirm.lower() == 'y':
+                run_real_trading()
+            else:
+                print("已取消实盘交易")
+                main()  # 返回主菜单
+        elif choice == '4':
+            print("感谢使用,再见!")
+            return
+        else:
+            print("无效选择,请输入1, 2, 3或4")
+            main()  # 重新显示主菜单
+    except KeyboardInterrupt:
+        print("\n程序已被用户中断")
+    except Exception as e:
+        print(f"发生错误: {e}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def main():
print("请选择运行模式: 1. 回测 2. 模拟 3. 实盘")
choice = input("输入选择(1/2/3): ")
if choice == '1':
run_backtest()
elif choice == '2':
run_simulation()
elif choice == '3':
run_real_trading()
else:
print("无效选择,请输入1, 2或3")
def main():
print("===============================")
print("交易系统 v1.0")
print("===============================")
print("请选择运行模式:")
print("1. 回测 - 使用历史数据测试策略")
print("2. 模拟 - 使用实时行情进行模拟交易")
print("3. 实盘 - 使用实际资金进行交易")
print("4. 退出")
print("===============================")
try:
choice = input("请输入选择(1/2/3/4): ")
if choice == '1':
run_backtest()
elif choice == '2':
run_simulation()
elif choice == '3':
confirm = input("确认要进行实盘交易吗?(y/n): ")
if confirm.lower() == 'y':
run_real_trading()
else:
print("已取消实盘交易")
main() # 返回主菜单
elif choice == '4':
print("感谢使用,再见!")
return
else:
print("无效选择,请输入1, 2, 3或4")
main() # 重新显示主菜单
except KeyboardInterrupt:
print("\n程序已被用户中断")
except Exception as e:
print(f"发生错误: {e}")

Comment on lines +4 to +6
def run_backtest():
api = TqApi(backtest=TqBacktest(start_dt=date(2021, 1, 1), end_dt=date(2021, 12, 31)), web_gui=True, auth=TqAuth("13760685574", "xdy19870920"))

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

认证凭据硬编码及未使用的变量问题

这段代码存在几个问题:

  1. 认证凭据直接硬编码在代码中,这是一个安全风险
  2. 创建的api变量从未被使用
  3. 缺少文档字符串说明函数用途
  4. 没有错误处理和资源清理

建议修改为:

-def run_backtest():
-    api = TqApi(backtest=TqBacktest(start_dt=date(2021, 1, 1), end_dt=date(2021, 12, 31)), web_gui=True, auth=TqAuth("13760685574", "xdy19870920"))
+def run_backtest():
+    """回测交易模式,使用2021年全年数据进行回测"""
+    try:
+        # 从环境变量或配置文件获取凭据
+        username = os.environ.get("TQ_USERNAME")
+        password = os.environ.get("TQ_PASSWORD")
+        
+        api = TqApi(backtest=TqBacktest(start_dt=date(2021, 1, 1), end_dt=date(2021, 12, 31)), 
+                   web_gui=True, 
+                   auth=TqAuth(username, password))
+        
+        # 这里添加您的交易策略代码
+        
+        # 等待策略运行
+        while True:
+            api.wait_update()
+    except Exception as e:
+        logging.error(f"回测过程中出现错误: {e}")
+    finally:
+        if api:
+            api.close()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def run_backtest():
api = TqApi(backtest=TqBacktest(start_dt=date(2021, 1, 1), end_dt=date(2021, 12, 31)), web_gui=True, auth=TqAuth("13760685574", "xdy19870920"))
def run_backtest():
"""回测交易模式,使用2021年全年数据进行回测"""
try:
# 从环境变量或配置文件获取凭据
username = os.environ.get("TQ_USERNAME")
password = os.environ.get("TQ_PASSWORD")
api = TqApi(
backtest=TqBacktest(start_dt=date(2021, 1, 1), end_dt=date(2021, 12, 31)),
web_gui=True,
auth=TqAuth(username, password)
)
# 这里添加您的交易策略代码
# 等待策略运行
while True:
api.wait_update()
except Exception as e:
logging.error(f"回测过程中出现错误: {e}")
finally:
if api:
api.close()
🧰 Tools
🪛 Ruff (0.8.2)

5-5: Local variable api is assigned to but never used

Remove assignment to unused variable api

(F841)

Comment on lines +10 to +12
def run_real_trading():
api = TqApi(TqAccount("期货公司", "账户", "密码"), web_gui=True, auth=TqAuth("13760685574", "xdy19870920"))

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

实盘交易函数使用了占位符账户信息且存在相同问题

实盘交易函数不仅存在与前两个函数相同的问题,还使用了明显的占位符账户信息。

建议修改为:

-def run_real_trading():
-    api = TqApi(TqAccount("期货公司", "账户", "密码"), web_gui=True, auth=TqAuth("13760685574", "xdy19870920"))
+def run_real_trading():
+    """实盘交易模式,使用真实账户进行交易"""
+    try:
+        # 从环境变量或配置文件获取凭据
+        username = os.environ.get("TQ_USERNAME")
+        password = os.environ.get("TQ_PASSWORD")
+        broker = os.environ.get("TQ_BROKER")
+        account = os.environ.get("TQ_ACCOUNT")
+        account_password = os.environ.get("TQ_ACCOUNT_PASSWORD")
+        
+        if not all([broker, account, account_password, username, password]):
+            print("请先设置环境变量: TQ_BROKER, TQ_ACCOUNT, TQ_ACCOUNT_PASSWORD, TQ_USERNAME, TQ_PASSWORD")
+            return
+            
+        api = TqApi(TqAccount(broker, account, account_password), 
+                   web_gui=True, 
+                   auth=TqAuth(username, password))
+        
+        # 这里添加您的交易策略代码
+        
+        # 等待策略运行
+        while True:
+            api.wait_update()
+    except Exception as e:
+        logging.error(f"实盘交易过程中出现错误: {e}")
+    finally:
+        if api:
+            api.close()

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.2)

11-11: Local variable api is assigned to but never used

Remove assignment to unused variable api

(F841)

Comment on lines +7 to +9
def run_simulation():
api = TqApi(TqSim(init_balance=100000), web_gui=True, auth=TqAuth("13760685574", "xdy19870920"))

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

模拟交易函数存在相同的安全和资源管理问题

与回测函数类似,模拟交易函数存在安全凭据硬编码和资源管理问题。

建议修改为:

-def run_simulation():
-    api = TqApi(TqSim(init_balance=100000), web_gui=True, auth=TqAuth("13760685574", "xdy19870920"))
+def run_simulation():
+    """模拟交易模式,初始资金为100000"""
+    try:
+        # 从环境变量或配置文件获取凭据
+        username = os.environ.get("TQ_USERNAME")
+        password = os.environ.get("TQ_PASSWORD")
+        
+        api = TqApi(TqSim(init_balance=100000), 
+                   web_gui=True, 
+                   auth=TqAuth(username, password))
+        
+        # 这里添加您的交易策略代码
+        
+        # 等待策略运行
+        while True:
+            api.wait_update()
+    except Exception as e:
+        logging.error(f"模拟交易过程中出现错误: {e}")
+    finally:
+        if api:
+            api.close()

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.2)

8-8: Local variable api is assigned to but never used

Remove assignment to unused variable api

(F841)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant