StringToInteger

本文介绍了一种将带有符号和空白字符的字符串转换为整数的方法。通过使用trim()去除空白,判断正负号,并逐位累加字符值来完成转换。同时考虑了溢出情况。

题意:将一个数字字符串转换为纯数字
思路:这道题就是需要做一些判断, 不规则输入,空格判断,溢出,正负号判断等。这里字符串处理有一个方法,trim()方法,它可以将字符串首尾的空格去掉。
代码:

package StringToInteger;

public class StringToInteger {
    public double Trverse(String s){
        if(s.length() == 0 ) return -1;
        //remove whitespace
        s = s.trim();
        int flag = 1;
        int i = 0;
        if(s.charAt(0) == '+') i++;
        if(s.charAt(0) == '-') {
            flag = -1;
            i++;
        }
        double sum = 0;
        while(i < s.length() && s.charAt(i) >= '0' && s.charAt(i) <= '9'){
            sum =  sum * 10+ (s.charAt(i)-'0');
            i++;
        }
        if(flag == -1)  sum = sum * -1;
        if(sum > Integer.MAX_VALUE) return -2;
        if(sum < Integer.MIN_VALUE) return -3;
        return sum;
    }

    public static void main(String[] args) {
        String string = " -324xz42";
        StringToInteger stn = new StringToInteger();
        double sum = stn.Trverse(string);
        System.out.println(sum);
    }
}
//±-----------------------------------------------------------------+ //| 马丁加仓EA.mq5 - 完整修复版 | //| Copyright 2023, MetaQuotes Software Corp. | //| https://www.mql5.com | //±-----------------------------------------------------------------+ #property copyright "Copyright 2023" #property version "1.03" // 修复版 #property script_show_inputs #property strict input double BaseVolume = 0.01; // 基础手数 input int GapPoints = 30; // 加仓点数间隔 input double MarginSafetyRatio = 1.5; // 保证金安全系数 input double MinFreeMargin = 100; // 最低保留保证金(USD) #include <Trade/Trade.mqh> #include <Trade/SymbolInfo.mqh> #include <Trade/PositionInfo.mqh> // 添加头文件 CTrade trade; CSymbolInfo symbolInfo; //— 全局变量 enum ENUM_MODE {MODE_NONE, MODE_BUY, MODE_SELL}; ENUM_MODE currentMode = MODE_NONE; // 当前模式:无/做多/做空 double lastBuyPrice = 0.0; // 上一次做多开仓价 double lastSellPrice = 0.0; // 上一次做空开仓价 int orderCount = 0; // 订单计数器 //±-----------------------------------------------------------------+ //| EA初始化函数 | //±-----------------------------------------------------------------+ int OnInit() { // 初始化品种信息 if(!symbolInfo.Name(_Symbol)) { Print("初始化品种信息失败!"); return(INIT_FAILED); } // 创建交易按钮 CreateButton("一键做多", 10, 50, 100, 30, clrGreen, "StartBuy"); CreateButton("一键做空", 120, 50, 100, 30, clrRed, "StartSell"); CreateButton("一键清仓", 230, 50, 100, 30, clrGray, "CloseAll"); CreateButton("一键锁仓", 340, 50, 100, 30, clrBlue, "LockPos"); CreateButton("平盈利单", 10, 90, 100, 30, clrGold, "CloseProfit"); CreateButton("平亏损单", 120, 90, 100, 30, clrOrange, "CloseLoss"); CreateButton("平多单盈利", 230, 90, 100, 30, clrGreen, "CloseBuyProfit"); CreateButton("平空单盈利", 340, 90, 100, 30, clrRed, "CloseSellProfit"); // 创建手数和间距输入框 CreateLabel("开仓手数:", 10, 130, 80, 20, clrWhite, "LabelVolume"); CreateEditBox("0.01", 90, 130, 80, 20, clrWhite, "InputVolume"); CreateLabel("加仓间距(点):", 180, 130, 100, 20, clrWhite, "LabelGap"); CreateEditBox("30", 280, 130, 80, 20, clrWhite, "InputGap"); // 添加保证金设置 CreateLabel("安全系数:", 10, 160, 80, 20, clrWhite, "LabelMarginRatio"); CreateEditBox("1.5", 90, 160, 80, 20, clrWhite, "InputMarginRatio"); CreateLabel("保留保证金:", 180, 160, 100, 20, clrWhite, "LabelMinMargin"); CreateEditBox("100", 280, 160, 80, 20, clrWhite, "InputMinMargin"); // 添加最大层数设置 CreateLabel("最大层数:", 10, 190, 80, 20, clrWhite, "LabelMaxLayers"); CreateEditBox("10", 90, 190, 80, 20, clrWhite, "InputMaxLayers"); // 设置初始值 ObjectSetString(0, "InputVolume", OBJPROP_TEXT, DoubleToString(BaseVolume, 2)); ObjectSetString(0, "InputGap", OBJPROP_TEXT, IntegerToString(GapPoints)); ObjectSetString(0, "InputMarginRatio", OBJPROP_TEXT, DoubleToString(MarginSafetyRatio, 2)); ObjectSetString(0, "InputMinMargin", OBJPROP_TEXT, DoubleToString(MinFreeMargin, 2)); // 设置异步交易模式 trade.SetAsyncMode(true); // 输出关键信息 Print("EA初始化完成 账户杠杆: 1:", AccountInfoInteger(ACCOUNT_LEVERAGE)); Print("当前品种: ", _Symbol, " 合约大小: ", symbolInfo.ContractSize()); return(INIT_SUCCEEDED); } //±-----------------------------------------------------------------+ //| 保证金检查函数 - 修复版 | //±-----------------------------------------------------------------+ bool CheckMarginSufficient(ENUM_ORDER_TYPE orderType, double volume) { // 计算所需保证金 double marginRequired = 0.0; double price = 0.0; if(orderType == ORDER_TYPE_BUY) price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); else price = SymbolInfoDouble(_Symbol, SYMBOL_BID); // 黄金的特殊保证金计算 if(_Symbol == "XAUUSD" || _Symbol == "GOLD") { // 黄金保证金 = (手数 * 合约大小 * 当前价格) / 账户杠杆 marginRequired = (volume * symbolInfo.ContractSize() * price) / AccountInfoInteger(ACCOUNT_LEVERAGE); } else { // 标准保证金计算 marginRequired = (volume * symbolInfo.ContractSize() * price) / AccountInfoInteger(ACCOUNT_LEVERAGE); } // 获取当前可用保证金 double freeMargin = AccountInfoDouble(ACCOUNT_MARGIN_FREE); double minMargin = GetMinFreeMargin(); double safetyRatio = GetMarginSafetyRatio(); // 添加安全系数检查 if(freeMargin > (marginRequired * safetyRatio) && (freeMargin - marginRequired) > minMargin) { Print("保证金充足: 需要=", marginRequired, " 可用=", freeMargin, " 安全系数=", safetyRatio, " 保留=", minMargin); return true; } Print("保证金不足! 需要: ", marginRequired, " 可用: ", freeMargin, " 安全系数: ", safetyRatio, " 需保留: ", minMargin); return false; } //±-----------------------------------------------------------------+ //| 获取保证金安全系数 | //±-----------------------------------------------------------------+ double GetMarginSafetyRatio() { string text = ObjectGetString(0, "InputMarginRatio", OBJPROP_TEXT); double ratio = StringToDouble(text); return(ratio > 1.0 ? ratio : MarginSafetyRatio); } //±-----------------------------------------------------------------+ //| 获取最低保留保证金 | //±-----------------------------------------------------------------+ double GetMinFreeMargin() { string text = ObjectGetString(0, "InputMinMargin", OBJPROP_TEXT); double margin = StringToDouble(text); return(margin > 0 ? margin : MinFreeMargin); } //±-----------------------------------------------------------------+ //| 获取当前基础手数 | //±-----------------------------------------------------------------+ double GetBaseVolume() { string text = ObjectGetString(0, "InputVolume", OBJPROP_TEXT); double volume = StringToDouble(text); return(volume > 0 ? volume : BaseVolume); } //±-----------------------------------------------------------------+ //| 获取当前加仓间距 | //±-----------------------------------------------------------------+ int GetGapPoints() { string text = ObjectGetString(0, "InputGap", OBJPROP_TEXT); int gap = (int)StringToInteger(text); return(gap > 0 ? gap : GapPoints); } //±-----------------------------------------------------------------+ //| 获取当前仓位数量 | //±-----------------------------------------------------------------+ int GetPositionCount() { int count = 0; for(int i = 0; i < PositionsTotal(); i++) { ulong ticket = PositionGetTicket(i); if(ticket > 0 && PositionGetString(POSITION_SYMBOL) == _Symbol) { count++; } } return count; } //±-----------------------------------------------------------------+ //| EA订单逻辑处理函数 - 添加保证金检查 | //±-----------------------------------------------------------------+ void OnTick() { // 马丁加仓逻辑 if(currentMode == MODE_BUY) { double currentBid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double pointValue = SymbolInfoDouble(_Symbol, SYMBOL_POINT); // 获取当前加仓间距 int currentGapPoints = GetGapPoints(); // 检查是否需要加仓(价格下跌指定点数) if(lastBuyPrice - currentBid >= currentGapPoints * pointValue) { double volume = GetBaseVolume(); // 添加保证金检查 if(CheckMarginSufficient(ORDER_TYPE_BUY, volume)) { double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if(trade.Buy(volume, _Symbol, ask, 0, 0)) { lastBuyPrice = ask; orderCount++; Print("加仓做多: ", volume, "手 @ ", ask, " 当前订单数: ", orderCount); } else { Print("加仓做多失败! 错误代码: ", GetLastError()); } } else { Print("保证金不足,无法加仓做多"); } } } else if(currentMode == MODE_SELL) { double currentAsk = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double pointValue = SymbolInfoDouble(_Symbol, SYMBOL_POINT); // 获取当前加仓间距 int currentGapPoints = GetGapPoints(); // 检查是否需要加仓(价格上涨指定点数) if(currentAsk - lastSellPrice >= currentGapPoints * pointValue) { double volume = GetBaseVolume(); // 添加保证金检查 if(CheckMarginSufficient(ORDER_TYPE_SELL, volume)) { double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); if(trade.Sell(volume, _Symbol, bid, 0, 0)) { lastSellPrice = bid; orderCount++; Print("加仓做空: ", volume, "手 @ ", bid, " 当前订单数: ", orderCount); } else { Print("加仓做空失败! 错误代码: ", GetLastError()); } } else { Print("保证金不足,无法加仓做空"); } } } } //±-----------------------------------------------------------------+ //| 创建按钮函数 | //±-----------------------------------------------------------------+ void CreateButton(string text, int x, int y, int width, int height, color bgColor, string name) { if(!ObjectCreate(0, name, OBJ_BUTTON, 0, 0, 0)) { Print("创建按钮失败: ", name); return; } ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, name, OBJPROP_XSIZE, width); ObjectSetInteger(0, name, OBJPROP_YSIZE, height); ObjectSetString(0, name, OBJPROP_TEXT, text); ObjectSetInteger(0, name, OBJPROP_BGCOLOR, bgColor); ObjectSetInteger(0, name, OBJPROP_COLOR, clrWhite); ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 9); } //±-----------------------------------------------------------------+ //| 创建标签函数 | //±-----------------------------------------------------------------+ void CreateLabel(string text, int x, int y, int width, int height, color textColor, string name) { if(!ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0)) { Print("创建标签失败: ", name); return; } ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, name, OBJPROP_XSIZE, width); ObjectSetInteger(0, name, OBJPROP_YSIZE, height); ObjectSetString(0, name, OBJPROP_TEXT, text); ObjectSetInteger(0, name, OBJPROP_COLOR, textColor); ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 9); } //±-----------------------------------------------------------------+ //| 创建编辑框函数 | //±-----------------------------------------------------------------+ void CreateEditBox(string text, int x, int y, int width, int height, color textColor, string name) { if(!ObjectCreate(0, name, OBJ_EDIT, 0, 0, 0)) { Print("创建编辑框失败: ", name); return; } ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x); ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y); ObjectSetInteger(0, name, OBJPROP_XSIZE, width); ObjectSetInteger(0, name, OBJPROP_YSIZE, height); ObjectSetString(0, name, OBJPROP_TEXT, text); ObjectSetInteger(0, name, OBJPROP_COLOR, textColor); ObjectSetInteger(0, name, OBJPROP_BGCOLOR, clrBlack); ObjectSetInteger(0, name, OBJPROP_BORDER_COLOR, clrSilver); ObjectSetInteger(0, name, OBJPROP_FONTSIZE, 9); ObjectSetInteger(0, name, OBJPROP_ALIGN, ALIGN_CENTER); } //±-----------------------------------------------------------------+ //| 图表事件处理函数 - 添加保证金检查 | //±-----------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { // 处理按钮点击事件 if(id == CHARTEVENT_OBJECT_CLICK) { //— 一键做多 if(sparam == "StartBuy") { double volume = GetBaseVolume(); if(CheckMarginSufficient(ORDER_TYPE_BUY, volume)) { currentMode = MODE_BUY; orderCount = 0; // 重置订单计数器 double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); if(trade.Buy(volume, _Symbol, ask, 0, 0)) { lastBuyPrice = ask; orderCount++; Print("开始做多: ", volume, "手 @ ", ask); } else { Print("开始做多失败! 错误代码: ", GetLastError()); } } else { Print("保证金不足,无法开始做多"); } } //— 一键做空 else if(sparam == "StartSell") { double volume = GetBaseVolume(); if(CheckMarginSufficient(ORDER_TYPE_SELL, volume)) { currentMode = MODE_SELL; orderCount = 0; // 重置订单计数器 double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); if(trade.Sell(volume, _Symbol, bid, 0, 0)) { lastSellPrice = bid; orderCount++; Print("开始做空: ", volume, "手 @ ", bid); } else { Print("开始做空失败! 错误代码: ", GetLastError()); } } else { Print("保证金不足,无法开始做空"); } } //— 一键清仓 else if(sparam == "CloseAll") { currentMode = MODE_NONE; CloseAllPositionsFast(); orderCount = 0; // 重置订单计数器 } //— 一键锁仓 else if(sparam == "LockPos") { LockPositions(); } //— 平止盈单 else if(sparam == "CloseProfit") { CloseProfitPositions(); } //— 平亏损单 else if(sparam == "CloseLoss") { CloseLossPositions(); } //— 平多单盈利单 else if(sparam == "CloseBuyProfit") { ClosePositionsByTypeAndProfit(POSITION_TYPE_BUY, true); } //— 平空单盈利单 else if(sparam == "CloseSellProfit") { ClosePositionsByTypeAndProfit(POSITION_TYPE_SELL, true); } } } //±-----------------------------------------------------------------+ //| 快速关闭所有持仓(批量平仓优化) | //±-----------------------------------------------------------------+ void CloseAllPositionsFast() { int total = PositionsTotal(); if(total <= 0) return; // 收集所有仓位的ticket for(int i = total-1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket > 0 && PositionGetString(POSITION_SYMBOL) == _Symbol) { trade.PositionClose(ticket); } } Print("已关闭所有持仓"); } //±-----------------------------------------------------------------+ //| 锁仓函数(批量优化) | //±-----------------------------------------------------------------+ void LockPositions() { double buyVolume = 0.0; double sellVolume = 0.0; // 计算多空总手数 for(int i = 0; i < PositionsTotal(); i++) { ulong ticket = PositionGetTicket(i); if(ticket > 0 && PositionGetString(POSITION_SYMBOL) == _Symbol) { if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) buyVolume += PositionGetDouble(POSITION_VOLUME); else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) sellVolume += PositionGetDouble(POSITION_VOLUME); } } // 批量开对冲单 if(buyVolume > sellVolume) { double volume = buyVolume - sellVolume; if(trade.Sell(volume, _Symbol, SymbolInfoDouble(_Symbol, SYMBOL_BID))) Print("已锁仓: 卖出 ", volume, "手"); } else if(sellVolume > buyVolume) { double volume = sellVolume - buyVolume; if(trade.Buy(volume, _Symbol, SymbolInfoDouble(_Symbol, SYMBOL_ASK))) Print("已锁仓: 买入 ", volume, "手"); } else { Print("多空仓位已平衡,无需锁仓"); } } //±-----------------------------------------------------------------+ //| 平盈利单(批量优化) | //±-----------------------------------------------------------------+ void CloseProfitPositions() { int count = 0; for(int i = PositionsTotal()-1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket > 0 && PositionGetString(POSITION_SYMBOL) == _Symbol) { double profit = PositionGetDouble(POSITION_PROFIT); if(profit > 0) { trade.PositionClose(ticket); count++; } } } Print("已平仓 ", count, " 个盈利单"); } //±-----------------------------------------------------------------+ //| 平亏损单(批量优化) | //±-----------------------------------------------------------------+ void CloseLossPositions() { int count = 0; for(int i = PositionsTotal()-1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket > 0 && PositionGetString(POSITION_SYMBOL) == _Symbol) { double profit = PositionGetDouble(POSITION_PROFIT); if(profit < 0) { trade.PositionClose(ticket); count++; } } } Print("已平仓 ", count, " 个亏损单"); } //±-----------------------------------------------------------------+ //| 按类型和平仓条件关闭订单(批量优化) | //±-----------------------------------------------------------------+ void ClosePositionsByTypeAndProfit(ENUM_POSITION_TYPE type, bool closeProfit) { int count = 0; for(int i = PositionsTotal()-1; i >= 0; i--) { ulong ticket = PositionGetTicket(i); if(ticket > 0 && PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_TYPE) == type) { double profit = PositionGetDouble(POSITION_PROFIT); if((closeProfit && profit > 0) || (!closeProfit && profit < 0)) { trade.PositionClose(ticket); count++; } } } Print("已平仓 ", count, " 个指定类型订单"); } //±-----------------------------------------------------------------+ //| EA终止函数 | //±-----------------------------------------------------------------+ void OnDeinit(const int reason) { // 删除所有图形对象 ObjectsDeleteAll(0, -1, OBJ_BUTTON); ObjectsDeleteAll(0, -1, OBJ_LABEL); ObjectsDeleteAll(0, -1, OBJ_EDIT); Print("EA已卸载"); } 以上代码中,加仓的时候以前面开单的价格为标准,不以实时价格为标准,如果价格低于或者高于前面的价格达到30点的加仓间距再加仓,不要重复加仓
11-24
U1 u1_g_getSingleIntegerInput(const char* u1_t_prompt, S4* value) { U1 u1_t_buffer[INP]; U1 valid = TRUE; U1 u1_t_idx = (U1)DATAZERO; U1 u1_t_sign = (U1)DATAZERO; U1 u1_t_input_res = (U1)DATAZERO; U1 overflow = TRUE; while (TRUE) { /* Display prompt and read input */ printf("%s", u1_t_prompt); if (fgets(u1_t_buffer, INP, stdin) == NULL) { u1_t_input_res = FALSE; /* Read error */ break; } /* Remove newline and check overflow */ for (u1_t_idx = (U1)DATAZERO; u1_t_idx < (U1)INP && u1_t_buffer[u1_t_idx] != '\0'; u1_t_idx++) { if (u1_t_buffer[u1_t_idx] == '\n') { u1_t_buffer[u1_t_idx] = '\0'; overflow = FALSE; break; } } if (overflow) { printf("Input too long! Using first %d characters.\n", INP - 1); vd_g_clearInputBuffer(); } /* Check exit command */ if (('q' == u1_t_buffer[DATAZERO]) || ('Q' == u1_t_buffer[DATAZERO])) { printf("Program terminated.\n"); exit(EXIT_SUCCESS); } /* Skip leading spaces */ u1_t_idx = (U1)DATAZERO; while (u1_t_buffer[u1_t_idx] == ' ') u1_t_idx++; /* Handle sign */ if (u1_t_buffer[u1_t_idx] == '-') { u1_t_sign = 1; u1_t_idx++; } /* Validate numeric characters */ U1 digit_count = 0; for (; u1_t_buffer[u1_t_idx] != '\0'; u1_t_idx++) { if (u1_t_buffer[u1_t_idx] == ' ') { /* Skip trailing spaces */ while (u1_t_buffer[u1_t_idx] == ' ') u1_t_idx++; if (u1_t_buffer[u1_t_idx] != '\0') { valid = FALSE; /* Non-space after space */ break; } } else if (!u1_g_isDigit(u1_t_buffer[u1_t_idx])) { valid = FALSE; /* Non-digit character */ break; } else { digit_count++; } } /* Process valid input */ if (valid && digit_count > 0) { *value = s2_g_stringToInteger(u1_t_buffer); return TRUE; } printf("Invalid input! Please enter a single integer.\n"); valid = TRUE; /* Reset for next iteration */ } } 能不能把这个函数缩短到50行以内,摒弃重复逻辑,不改变逻辑和现有的命名
最新发布
11-26
我觉得可以复用函数U1 u1_g_getSingleIntegerInput(U1 *u1p_a_prompt, S4 *s4p_a_value) { U1 u1_t_input[10]; U1 u1_t_ret; U1 u1_t_idx; S2 s2_t_count; U1 u1_t_inputlength; U1 u1_t_valid = TRUE; u1_t_ret = (U1)FALSE; u1_t_inputlength = (U1)TRUE; u1_t_valid = (U1)TRUE; s2_t_count = (U1)INIT_ZERO; while (TRUE) { printf("%s", u1p_a_prompt); if (fgets(u1_t_input, INP, stdin) == NULL) { u1_t_ret = (U1)FALSE; /* Read error */ } else { /* do thong */ } /* Check for input overflow */ for (u1_t_idx = (U1)INIT_ZERO; (u1_t_idx < INP - INIT_ONE) && (u1_t_input[u1_t_idx] != '\0'); u1_t_idx++) { if (u1_t_input[u1_t_idx] == '\n') { /* Replace newline with null terminator */ u1_t_input[u1_t_idx] = '\0'; u1_t_inputlength = (U1)FALSE; break; } else { /* do thong */ } } if (u1_t_inputlength) { /* Handle buffer overflow */ printf("Input too long! Using first %d characters.\n", INP - INIT_ONE); vd_g_clearInputBuffer(); } else { /* do thong */ } /* Check for exit commands */ if (('q'== u1_t_input[0])||('Q' == u1_t_input[0])) { printf("Program terminated.\n"); exit((U1)INIT_ZERO); } else { /* do thong */ } u1_t_idx = (U1)INIT_ZERO; /* Skip leading spaces */ while (u1_t_input[u1_t_idx] == ' ') u1_t_idx++; /* Handle negative sign */ if (u1_t_input[u1_t_idx] == '-') { u1_t_idx++; } else { /* do thong */ } /* Check remaining characters */ for (; u1_t_input[u1_t_idx] != '\0'; u1_t_idx++) { if (u1_t_input[u1_t_idx] == ' ') { /* Skip trailing spaces */ while (u1_t_input[u1_t_idx] == ' ') u1_t_idx++; /* Invalid if non-space follows */ if (u1_t_input[u1_t_idx] != '\0') { u1_t_valid = (U1)FALSE; break; } else { /* do thong */ } } else if (u1_g_isDigit(u1_t_input[u1_t_idx]) == (U1)INIT_ZERO) { /* Non-digit character */ u1_t_valid = FALSE; break; } else { s2_t_count++; } } if (u1_t_valid && s2_t_count > (U1)INIT_ZERO) { /* Valid input, convert to integer */ *s4p_a_value = s2_g_stringToInteger(u1_t_input); u1_t_ret = (U1)TRUE; break; } else { printf("Invalid input! Please enter a single integer.\n"); } } return u1_t_ret; }而不用static S4 getValidatedMenuChoice(void) {函数,但是u1_g_getSingleIntegerInput这个函数同样需要简化
11-26
//+------------------------------------------------------------------+ //| MultiTimeZone.mq4 | //| Copyright 2023, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023" #property link "https://www.mql5.com" #property version "1.00" #property strict #property indicator_chart_window //--- 用户输入参数 input string TimeZoneNames = "Server,Local,New York,London,Tokyo,Sydney"; // 时区名称(逗号分隔) input string TimeOffsets = "0,0,-5,0,9,10"; // 时区偏移(小时) input bool AutoPosition = true; // 自动调整位置 input int X_Distance = 20; // X轴距离(像素) input int Y_Distance = 20; // Y轴距离(像素) input color TextColor = clrGold; // 文本颜色 input int FontSize = 10; // 字体大小 input string FontFace = "Arial"; // 字体类型 input bool DST_Adjust = true; // 夏令时调整 //--- 全局变量 string labels[]; int totalZones; //+------------------------------------------------------------------+ //| 自定义指标初始化函数 | //+------------------------------------------------------------------+ int OnInit() { // 分割时区配置 string zoneNames[]; string offsetValues[]; totalZones = StringSplit(TimeZoneNames, ',', zoneNames); StringSplit(TimeOffsets, ',', offsetValues); if(totalZones != ArraySize(offsetValues)) { Alert("错误:时区名称和偏移量数量不匹配"); return(INIT_FAILED); } // 创建文本标签 ArrayResize(labels, totalZones); for(int i = 0; i < totalZones; i++) { string labelName = "TZLabel_" + IntegerToString(i); labels[i] = labelName; if(ObjectFind(0, labelName) < 0) { ObjectCreate(0, labelName, OBJ_LABEL, 0, 0, 0); } ObjectSetInteger(0, labelName, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(0, labelName, OBJPROP_COLOR, TextColor); ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, FontSize); ObjectSetString(0, labelName, OBJPROP_FONT, FontFace); ObjectSetInteger(0, labelName, OBJPROP_ANCHOR, ANCHOR_LEFT_UPPER); ObjectSetInteger(0, labelName, OBJPROP_SELECTABLE, false); ObjectSetInteger(0, labelName, OBJPROP_HIDDEN, true); // 设置位置 if(AutoPosition) { ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, X_Distance); ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, Y_Distance + i * (FontSize + 5)); } else { ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, X_Distance); ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, Y_Distance); } } // 设置定时器每秒更新 EventSetTimer(1); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 定时器事件 | //+------------------------------------------------------------------+ void OnTimer() { UpdateTimeDisplay(); } //+------------------------------------------------------------------+ //| 更新时间显示 | //+------------------------------------------------------------------+ void UpdateTimeDisplay() { datetime baseTime = TimeCurrent(); // 经纪商服务器时间 datetime localTime = TimeLocal(); // 本地计算机时间 string zoneNames[]; string offsetValues[]; StringSplit(TimeZoneNames, ',', zoneNames); StringSplit(TimeOffsets, ',', offsetValues); for(int i = 0; i < totalZones; i++) { int offset = (int)StringToInteger(offsetValues[i]); datetime displayTime; // 特殊处理服务器和本地时间 if(zoneNames[i] == "Server") { displayTime = baseTime; } else if(zoneNames[i] == "Local") { displayTime = localTime; } else { // 夏令时调整 int dstOffset = 0; if(DST_Adjust && IsSummerTime(offset)) { dstOffset = 3600; // 增加1小时 } displayTime = baseTime + (offset * 3600) + dstOffset; } // 更新时间显示 string timeStr = TimeToString(displayTime, TIME_MINUTES|TIME_SECONDS); string dayStr = TimeDayOfWeek(displayTime) == 1 ? "Mon" : TimeDayOfWeek(displayTime) == 2 ? "Tue" : TimeDayOfWeek(displayTime) == 3 ? "Wed" : TimeDayOfWeek(displayTime) == 4 ? "Thu" : TimeDayOfWeek(displayTime) == 5 ? "Fri" : TimeDayOfWeek(displayTime) == 6 ? "Sat" : "Sun"; ObjectSetString(0, labels[i], OBJPROP_TEXT, zoneNames[i] + ": " + dayStr + " " + timeStr); } } //+------------------------------------------------------------------+ //| 夏令时检查函数 | //+------------------------------------------------------------------+ bool IsSummerTime(int offset) { MqlDateTime current; TimeCurrent(current); // 北半球夏令时(3月最后一个周日 - 10月最后一个周日) if(offset < 0) // 西半球时区 { if(current.mon > 3 && current.mon < 11) return true; if(current.mon == 3 && current.day - current.day_of_week >= 25) return true; if(current.mon == 11 && current.day - current.day_of_week < 25) return true; } // 南半球夏令时(10月首个周日 - 3月首个周日) else if(offset > 0) // 东半球时区 { if(current.mon > 10 || current.mon < 3) return true; if(current.mon == 10 && current.day - current.day_of_week >= 1) return true; if(current.mon == 3 && current.day - current.day_of_week < 7) return true; } return false; } //+------------------------------------------------------------------+ //| 指标卸载函数 | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // 删除所有标签对象 for(int i = 0; i < totalZones; i++) { ObjectDelete(0, labels[i]); } // 移除定时器 EventKillTimer(); } 改一下完整的给我
11-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值