金字塔决策交易系统

 找回密码
 

微信登录

微信扫一扫,快速登录

搜索
查看: 992|回复: 2

帮忙看一下止损问题出在哪里

[复制链接]

4

主题

11

帖子

11

积分

Rank: 1

等级: 新手上路

注册:
2024-7-24
曾用名:
发表于 2024-8-9 14:29 | 显示全部楼层 |阅读模式
我设置的止损是按5跳走,但是回测结果亏损5就平仓了,帮忙看一下问题出在哪里,下面是完整代码。from PythonApi import *
import pandas as pd
import numpy as np


def init(context):
    context.position = 0  # 1 for long, -1 for short, 0 for no position
    context.entry_price = 0
    context.stop_loss = 0
    context.max_profit = None
    context.mindiff = get_dynainf(
        context.run_info.base_book_id, 208)  # 获取最小变动价位
    print(f"[DEBUG] 初始化完成: mindiff = {context.mindiff}")


def convert_ndarray_to_dataframe(data, columns):
    df = pd.DataFrame(data, columns=columns)
    return df


def calculate_macd(data, short_period=12, long_period=26, signal_period=9):
    short_ema = data["close"].ewm(span=short_period, adjust=False).mean()
    long_ema = data["close"].ewm(span=long_period, adjust=False).mean()
    macd = short_ema - long_ema
    signal = macd.ewm(span=signal_period, adjust=False).mean()
    return macd, signal


def calculate_kdj(data, n=9, k_period=3, d_period=3):
    low_min = data["low"].rolling(window=n, min_periods=1).min()
    high_max = data["high"].rolling(window=n, min_periods=1).max()
    rsv = (data["close"] - low_min) / (high_max - low_min) * 100

    k = rsv.ewm(com=(k_period - 1), min_periods=1).mean()
    d = k.ewm(com=(d_period - 1), min_periods=1).mean()
    j = 3 * k - 2 * d

    data["K"] = k
    data["D"] = d
    data["J"] = j
    return data


def handle_bar(context):
    security = context.run_info.base_book_id  # 获取当前交易的证券代码
    print(f"[DEBUG] 开始处理bar: security = {security}")

    # 获取1分钟和5分钟历史数据
    data_1m_raw = history_bars(security, 30, "1m", ["close", "high", "low"])
    data_5m_raw = history_bars(security, 31, "5m", ["close"])

    # 确保数据量足够
    if len(data_1m_raw) < 30 or len(data_5m_raw) < 31:
        print("[DEBUG] 数据量不足,跳过本次处理")
        return

    # 将ndarray转换为DataFrame
    data_1m = convert_ndarray_to_dataframe(
        data_1m_raw, ["close", "high", "low"])
    data_5m = convert_ndarray_to_dataframe(data_5m_raw[:-1], ["close"])

    # 计算MACD和KDJ指标
    macd_5m, signal_5m = calculate_macd(data_5m)
    data_1m = calculate_kdj(data_1m)

    # 当前价格
    current_price = data_1m["close"].iloc[-1]
    print(f"[DEBUG] 当前价格: current_price = {current_price}")

    # 获取账户资金信息和合约单位
    account_cash = get_account(19)
    contract_size = get_instruments(context.run_info.base_book_id).multipliter
    print(
        f"[DEBUG] 账户资金: account_cash = {account_cash}, contract_size = {contract_size}")

    # 计算手数(可根据实际需求调整计算方法)
    volume = 10  
    # 假设最多用10%的资金
    print(f"[DEBUG] 计算手数: volume = {volume}")

    # 判断是否有未平仓订单
    if context.position != 0:
        current_profit = (
            (current_price - context.entry_price)
            if context.position == 1
            else (context.entry_price - current_price)
        )
        print(f"[DEBUG] 当前盈利: current_profit = {current_profit}")

        if context.max_profit is None:
            context.max_profit = current_profit
        else:
            context.max_profit = max(context.max_profit, current_profit)
        print(f"[DEBUG] 最大盈利: max_profit = {context.max_profit}")

        if context.position == 1:
            context.stop_loss = max(
                context.stop_loss, context.entry_price + context.max_profit * 0.6
            )
        else:
            context.stop_loss = min(
                context.stop_loss, context.entry_price - context.max_profit * 0.6
            )
        print(f"[DEBUG] 更新止损: stop_loss = {context.stop_loss}")

        if (context.position == 1 and current_price < context.stop_loss) or (
            context.position == -1 and current_price > context.stop_loss
        ):
            if context.position == 1:
                sell_close(security, "Market", 0, volume,serial_id = 1)
                print(f"[DEBUG] 平多仓: Sell at {current_price} on {security}")
            else:
                buy_close(security, "Market", 0, volume,serial_id = 2)
                print(f"[DEBUG] 平空仓: Cover at {current_price} on {security}")
            context.position = 0
            print("[DEBUG] 平仓完成,仓位已清空")

    # 没有未平仓订单时判断开仓信号
    if context.position == 0:
        if (

            macd_5m.iloc[-1] < signal_5m.iloc[-1]
        ):  # 使用前一根5分钟K线判断
            if data_1m["J"].iloc[-2] < 0 and data_1m["J"].iloc[-1] > 0:
                buy_open(security, "Market", 0, volume,serial_id = 3)
                context.position = 1
                context.entry_price = current_price
                context.stop_loss = current_price - 5 * context.mindiff
                context.max_profit = None
                print(
                    f"[DEBUG] 开多仓: Buy at {current_price} on {security}, stop_loss = {context.stop_loss}")
        elif (

            macd_5m.iloc[-1] > signal_5m.iloc[-1]
        ):  # 使用前一根5分钟K线判断
            if data_1m["J"].iloc[-2] > 100 and data_1m["J"].iloc[-1] < 100:
                sell_open(security, "Market", 0, volume,serial_id = 4)
                context.position = -1
                context.entry_price = current_price
                context.stop_loss = current_price + 5 * context.mindiff
                context.max_profit = None
                print(
                    f"[DEBUG] 开空仓: Short at {current_price} on {security}, stop_loss = {context.stop_loss}")








截图202408091429189239.png
截图202408091428557579.png
回复

使用道具 举报

21

主题

1万

帖子

1万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
FireScript
发表于 2024-8-9 15:27 | 显示全部楼层
你这里:
       if context.position == 1:
            context.stop_loss = max(
                context.stop_loss, context.entry_price + context.max_profit * 0.6
            )

是不是应该 最大盈利大于0时候更新这个止损价呀.   否则你亏损时候,你这个止损价你看下算法:
你比如亏损15,原本止损价是100-5*5=75,现在这样一算就成了max(75,100-15*0.6)=91了。。

这样你止损位置提上去了。
金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

21

主题

1万

帖子

1万

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-18
曾用名:
FireScript
发表于 2024-8-9 15:36 | 显示全部楼层
本帖最后由 技术009 于 2024-8-9 15:38 编辑

另外这种回撤止盈最好是设置一个阈值,即最大盈利多少。否则你赚10块会回撤,赚100块也会回撤。

        if context.max_profit>0 and context.max_profit>25:       
            if context.position == 1 :
                context.stop_loss = max(
                    context.stop_loss, context.entry_price + context.max_profit * 0.6
                )
            else:
                context.stop_loss = min(
                    context.stop_loss, context.entry_price - context.max_profit * 0.6
                )
            print(f"[DEBUG] 更新止损: stop_loss = {context.stop_loss}")

金字塔提供一对一VIP专业技术指导服务,技术团队实时响应您的日常使用问题与策略编写。联系电话:021-20339086
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 微信登录

本版积分规则

手机版|小黑屋|上海金之塔信息技术有限公司 ( 沪ICP备13035422号 )

GMT+8, 2025-6-30 06:23 , Processed in 0.163211 second(s), 24 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表