上一节我们自己动手创建了一个不区分大小写的文本包含函数StrContains()
。但有时模糊包含还不够,我们需要更精确的“前缀匹配”,并且同样希望忽略大小写的干扰。
比如我想筛选出所有比特币相关的品种,BTCUSD
和btceur
都应该被选中。这时候,我们就需要自己动手,打造str.startswith()
的升级版。
自定义不区分大小写的StrStartsWith()
函数
实现思路和我们上一节课完全一样:在比较之前,先把两个字符串都用str.lower()
函数一视同仁地转换成小写,抹平大小写的差异,然后再进行比较。
基于这个思路,我们可以封装出下面这个专门用于前缀匹配的自定义函数:
// 判断源字符串是否以子字符串开头,不区分大小写
StrStartsWith(string source, string substring) =>
// 先转成小写,然后调用str.startswith()进行前缀匹配
str.startswith(str.lower(source), str.lower(substring))
这个函数的使用示例及其结果如下:
使用注意事项 (处理空值)
我们这个自定义函数在处理空字符串或na
值时,行为和内置的str.startswith()
一样。简单总结就是:
- 任何字符串都‘以空字符串开头’,所以
StrStartsWith("EURUSD", "")
会返回true
。 - 一个空字符串里不可能‘以任何非空内容开头’,所以
StrStartsWith("", "USD")
会返回false
。
实战案例:识别不同市场的iShares ETF
下面的指标旨在识别在美洲和欧洲交易所交易的iShares ETF。这个例子完美地展示了如何组合运用多个判断条件,以及我们自定义的StrStartsWith()
函数。
//@version=6
indicator(title="不区分大小写的前缀匹配", overlay=true)
StrStartsWith(string source, string substring) =>
str.startswith(str.lower(source), str.lower(substring))
// 步骤一:判断是否为iShares ETF
// 条件1: 品种必须以"iShares"开头(不区分大小写)
// 条件2: 品种类型必须是"fund",以排除同名的股票、CFD等
isIsharesETF = StrStartsWith(syminfo.description, "iShares") and
syminfo.type == "fund"
// 步骤二:对已筛选出的ETF进行二次筛选和打标
if barstate.islast and isIsharesETF
// 二次筛选条件1:时区是否以"america"开头
if StrStartsWith(syminfo.timezone, "america")
label.new(bar_index, high, "这是一个美洲市场的iShares ETF",
color=color.lime)
// 二次筛选条件2:时区是否以"europe"开头
else if StrStartsWith(syminfo.timezone, "europe")
label.new(bar_index, high, "这是一个欧洲市场的iShares ETF",
color=color.orange)
这个脚本的逻辑是一个“两步筛选”过程:
- 初步筛选:我们先用
StrStartsWith()
判断品种描述是否以"iShares"
开头,并且用and
连接第二个条件,确保品种类型是基金("fund"
)。只有同时满足这两个条件的,才会被认为是iShares ETF。 - 二次筛选:对于通过了初步筛选的ETF,我们再用
StrStartsWith()
去检查它的时区(syminfo.timezone
),从而判断它究竟是属于美洲市场还是欧洲市场,并打上不同的标签。
当我们在图表中显示一个ETF时,脚本会准确地将其识别为欧洲ETF或美洲ETF:
总结
总结一下,通过str.lower()
和str.startswith()
的巧妙组合,我们成功打造了第二个自定义工具StrStartsWith()
。它专门解决需要忽略大小写的“前缀匹配”问题,比StrContains()
更精确。当你需要根据品种代码前缀、交易所名称等信息来让脚本做出不同行为时,这个函数将是你的得力助手。
评论前必须登录!
立即登录 注册