金字塔决策交易系统

 找回密码
 

微信登录

微信扫一扫,快速登录

搜索
查看: 182|回复: 25

这里计算亏损和输出为0是什么原因

[复制链接]

4

主题

32

帖子

32

积分

Rank: 4

等级: 专业版

注册:
2025-7-4
曾用名:
发表于 2025-11-18 09:46 | 显示全部楼层 |阅读模式
请教下面统计后台止损后亏损金额的代码的问题,如何改进才能统计出多次止损后的总亏损额?
//后台程序化下,用下面代码来计算多次止损的亏损和
//计算连续亏损时第一次的开仓价scj 1-最近一次盈利平仓后的第一次开仓价;2-
kzq:=sumbars(tNUMPROFIT(1)>=0,1)-1,linethick0;//亏周期--亏损平仓时就变为负数--取亏损平仓到现在的周期
yzq:=sumbars(tNUMPROFIT(1)<0,1)-1,linethick0;//盈利平仓时就变为正数--取最近盈利平仓时的周期
kszq:=if(kzq<yzq,kzq,yzq);//只是为了不改动代码,这里仍用亏损周期的变量名
kspczf:=tholding=0 and ref(tholding,1)<>0 and tNUMPROFIT(1)<0,linethick0;//亏损平仓触发位置
pcks:=if(kspczf,tNUMPROFIT(1),0);//平仓亏损置0,亏损平仓时记住前一次亏损额,否则置为0
ksh:=if(tNUMPROFIT(1)>=0,0,sum(pcks,kszq+1)),linethick0;//亏损和--用于止盈时抵扣利润

//用下面代码输出特定品种的亏损和是否正确
kshstr:=stklabel+' ksh:'+numtostr(ksh,2);
if (islastbar and stklabel='159590')then DEBUGFILE('C:\TEST.TXT',kshstr,0);


//当有止损后,ksh输出一直为0,并没有返回正确的止损后的亏损和的值
025-11-18 09:30:03.937    159590 ksh:0.00
2025-11-18 09:30:05.372    513120 止损:1 止损条件价:1.40 当前价:1.37 止损额:-106.04 ksh:0.00
2025-11-18 09:30:14.060    159590 ksh:0.00
2025-11-18 09:30:23.142    159590 ksh:0.00
2025-11-18 09:30:33.255    159590 ksh:0.00
2025-11-18 09:30:43.128    159590 ksh:0.00
2025-11-18 09:30:53.071    159590 ksh:0.00
2025-11-18 09:31:03.381    159590 ksh:0.00
2025-11-18 09:31:13.489    159590 ksh:0.00
2025-11-18 09:31:23.188    159590 ksh:0.00

回复

使用道具 举报

2

主题

5787

帖子

5787

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
发表于 2025-11-18 10:39 | 显示全部楼层
tNUMPROFIT(1)  这种函数 你用 sumbars  sum等历史序列函数  去处理是不行的。它其实是没有历史值的,指定的参数N都只有最近一次的值。获取历史值通过指定参数来获取 比如tNUMPROFIT(2) 就是上上次的。

这种统计不是很好做。因为你如果有多种平仓来源,那其实 tNUMPROFIT是区分不了的。除非说你就是根据平仓盈亏结果简单判定?例如把所有亏损平仓的数值累计下? 这种可以考虑用循环做,但是效率的情况不是很确定。



回复

使用道具 举报

4

主题

32

帖子

32

积分

Rank: 4

等级: 专业版

注册:
2025-7-4
曾用名:
 楼主| 发表于 2025-11-18 11:08 | 显示全部楼层
资深技术05 发表于 2025-11-18 10:39
tNUMPROFIT(1)  这种函数 你用 sumbars  sum等历史序列函数  去处理是不行的。它其实是没有历史值的,指定 ...

对,我就是想把止损后的亏损累加,用于下一次的止盈判断,下一次如果盈利平仓则归0;
也即是说tNUMPROFIT(1)在后台里返回的是一个常数?
回复

使用道具 举报

2

主题

5787

帖子

5787

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
发表于 2025-11-18 11:10 | 显示全部楼层
是的。它返回是常数而非序列值。如果统计的话,你这个是不是也要考虑约束下 当日还是说历史所有平仓盈亏都统计在内?还有一点你平仓都是全平 还是有部分平仓呢?这个涉及到一些函数的使用。
回复

使用道具 举报

4

主题

32

帖子

32

积分

Rank: 4

等级: 专业版

注册:
2025-7-4
曾用名:
 楼主| 发表于 2025-11-18 11:27 | 显示全部楼层
资深技术05 发表于 2025-11-18 11:10
是的。它返回是常数而非序列值。如果统计的话,你这个是不是也要考虑约束下 当日还是说历史所有平仓盈亏都 ...

连续止损的亏损都要统计在内,一旦下次平仓盈利则亏损统计清0,等下次亏损时再统计,平仓时是全平
回复

使用道具 举报

2

主题

5787

帖子

5787

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
发表于 2025-11-18 14:09 | 显示全部楼层
[PEL] 复制代码
i:=1;

累计止损:0;
while i>0 do 
begin


if tnumprofit(i)<0 then 
begin
累计止损:=累计止损+tnumprofit(i); 
i:=i+1;
CONTINUE;
end 	

break;
	
end



效果:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号? 微信登录

x
回复

使用道具 举报

4

主题

32

帖子

32

积分

Rank: 4

等级: 专业版

注册:
2025-7-4
曾用名:
 楼主| 发表于 2025-11-18 14:24 | 显示全部楼层
资深技术05 发表于 2025-11-18 14:09
[mw_shl_code=pel,true]i:=1;

累计止损:0;

好的,我试一下,谢谢
回复

使用道具 举报

4

主题

32

帖子

32

积分

Rank: 4

等级: 专业版

注册:
2025-7-4
曾用名:
 楼主| 发表于 2025-11-20 10:42 | 显示全部楼层
因为要取得连续止损时第一笔止损时的开仓价,及累计止损和,当盈利后将这些值置0,我这样写看有没有问题?
// 交易信号判断(仅做多)
pdd := TEXITBARS(0)=0 AND TTYPE(1)=2;  // 2=平多信号--平多点
//开多发生 := TENTERBARS(0)=0 AND TTYPE(1)=1;  // 1=开多信号
// 当平多发生时处理盈亏逻辑
IF pdd THEN BEGIN
    // 获取本次交易盈亏
    current_profit := TNUMPROFIT(1);
    // 判断是否盈利
    IF current_profit > 0 THEN BEGIN
        // 盈利时重置该品种记录
        EXTGBDATASET('loss_price_'+STKLABEL,0);
        EXTGBDATASET('acc_loss_'+STKLABEL,0);
        EXTGBDATASET('loss_cnt_'+STKLABEL,0);
     end;
    IF current_profit<0 THEN BEGIN
        IF EXTGBDATA('loss_cnt_'+STKLABEL) = 0 THEN  EXTGBDATASET('loss_price_'+STKLABEL,TORDERPRICE(1,1)); // 第一次亏损,记录开仓价// 最近一次开多价
       // 更新累计亏损和次数
        new_acc_loss := EXTGBDATA('acc_loss_'+STKLABEL) + ABS(current_profit);
        new_loss_cnt := EXTGBDATA('loss_cnt_'+STKLABEL) + 1;
        //
        EXTGBDATASET('acc_loss_'+STKLABEL,new_acc_loss);
        EXTGBDATASET('loss_cnt_'+STKLABEL,new_loss_cnt);
     END;
END;
//
scj:=EXTGBDATA('loss_price_'+STKLABEL);//取连续止损时第一笔止损的首仓价
ksh:=EXTGBDATA('acc_loss_'+STKLABEL);//连续止损的累计止损金额
回复

使用道具 举报

2

主题

5787

帖子

5787

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
发表于 2025-11-20 10:54 | 显示全部楼层
TEXITBARS(0)=0  你判断这个是假设了一定能在本根K时间内成交。假如恰好这根K就是没成交。这次平仓后续即便成交了 也不会被记录了不是吗。 这个地方不稳妥。  

还有假设平仓是亏损的:

       // 更新累计亏损和次数

        new_loss_cnt := EXTGBDATA('loss_cnt_'+STKLABEL) + 1;

这部分代码是会重复执行的。他执行的条件仅仅是最近一次平仓是亏损的。如果你是轮询模式,你会执行很多次的。最终结果就是累计的次数是不对的。



回复

使用道具 举报

2

主题

5787

帖子

5787

积分

Rank: 8Rank: 8

等级: 超级版主

注册:
2021-5-24
曾用名:
发表于 2025-11-20 10:58 | 显示全部楼层
你就基于前面那个循环的范例做处理就行了。你在循环中用函数TORDERPRICE 读取第I次的价格 也就行了。最后一次读取和记录的值 其实就是连亏第一笔的价格。因为这个循环是从当前向历史查询的。

回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-11-27 12:45 , Processed in 0.121358 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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