FMZ Quant

406 posts

FMZ Quant

FMZ Quant

@FMZQuant

Quantitative Trading For Everyone Telegram:https://t.co/zBdP27IqO0 中文电报群:https://t.co/SKXsmTombA

Singapore Entrou em Şubat 2022
71 Seguindo1.2K Seguidores
trader-c
trader-c@TradercBTC·
把这个代码公开了,因为okx信号策略不知道在干啥,给我断了,这个是今天刚把上面开的空单平掉了。 目前我继续跑吧,后面有变动会更新。 最近主要精力会放在搞把我的交易系统搞成《AI+交易》效果。就是各种写,把我能想到的全部写出来,顺便把我之前发布在推特的单子全部搞出来整理一下。 说一下效果: 默认名义本金10w💲,名义仓位1.5w💲,最高可开到2.5w💲 也就是1w💲十倍杠杆。理论上运气好第一单赚钱的话,2k💲就能开这个策略赚钱 如果趋势强度高了,会开1.5倍杠杆,也就是来到了15万💲的本金。 最近一年效果:大概就是一年2.5w仓位,赚2w💲。 盈利因子接近4 不说其他的了,你们自己看设置吧,反正是中文,自己调试去,希望大家一起搞一个好用的策略吧。 以下是代码👇: //@version=5 strategy("动态狙击系统 v3.0 - 激进复利版", overlay=true, initial_capital=100000, default_qty_type=strategy.fixed, commission_type=strategy.commission.percent, commission_value=0.075, slippage=3, pyramiding=0, calc_on_every_tick=true, process_orders_on_close=false, max_bars_back=500) // ==================== 激进版核心参数 ==================== // 你的激进风控配置 riskPercentage = input.float(3.0, "单笔风险比例(%)", minval=1.0, maxval=5.0, step=0.1, group="激进风控") maxLeverage = input.float(1.5, "牛市最大杠杆倍数", minval=1.0, maxval=2.0, step=0.1, group="激进风控") compoundingMode = input.bool(true, "启用复利模式", group="激进风控") maxPositionPct = input.float(15.0, "最大仓位占比(%)", minval=10, maxval=25, group="激进风控") // 你的激进止盈配置 breakEvenR = input.float(1.2, "延迟保本触发R", minval=0.8, maxval=2.0, step=0.1, group="激进止盈") lockSmallR = input.float(3.0, "延迟锁利触发R", minval=2.0, maxval=5.0, step=0.1, group="激进止盈") lockSmallLevel = input.float(1.0, "锁利位置R", minval=0.5, maxval=2.0, step=0.1, group="激进止盈") lockBigR = input.float(6.0, "大利润触发R", minval=4.0, maxval=10.0, step=0.1, group="激进止盈") lockBigLevel = input.float(3.0, "大利润位置R", minval=2.0, maxval=5.0, step=0.1, group="激进止盈") // 利润回撤保护(激进版放宽) useGivebackKill = input.bool(true, "启用利润回撤熔断", group="激进止盈") givebackStartR = input.float(4.0, "回撤监控起始R", minval=3, maxval=8, step=0.5, group="激进止盈") maxGivebackR = input.float(2.0, "最大允许回撤R", minval=1.0, maxval=4.0, step=0.5, group="激进止盈") // 趋势过滤 trendEmaLength = input.int(50, "日线EMA周期", minval=20, maxval=100, group="趋势过滤") trendLookback = input.int(20, "动量回看周期", minval=10, maxval=50, group="趋势过滤") trendThreshold = input.float(5.0, "趋势阈值(%)", minval=2, maxval=15, group="趋势过滤") // 入场设置 valueEmaLength = input.int(20, "4H EMA周期", minval=10, maxval=50, group="入场设置") atrLength = input.int(14, "ATR周期", minval=7, maxval=21, group="入场设置") pullbackAtrMult = input.float(1.2, "回调区ATR倍数", minval=0.5, maxval=2.0, group="入场设置") // 止损设置 stopAtrMult = input.float(3.0, "止损ATR倍数", minval=2.0, maxval=5.0, group="风险管理") // 激进版熔断(放宽限制) dailyLossLimit = input.float(5.0, "日亏损熔断(%)", minval=3, maxval=8, group="熔断保护") totalDrawdownLimit = input.float(25.0, "总回撤防御(%)", minval=15, maxval=35, group="熔断保护") // ==================== 数据获取 ==================== // 日线数据 dailyClose = request.security(syminfo.tickerid, "D", close, lookahead=barmerge.lookahead_off) dailyClose20Ago = request.security(syminfo.tickerid, "D", close[trendLookback], lookahead=barmerge.lookahead_off) dailyEma50 = request.security(syminfo.tickerid, "D", ta.ema(close, trendEmaLength), lookahead=barmerge.lookahead_off) // 当前周期数据 h4Ema20 = ta.ema(close, valueEmaLength) h4Atr = ta.atr(atrLength) // ==================== 趋势过滤器 ==================== trendMomentum = (dailyClose - dailyClose20Ago) / dailyClose20Ago * 100 isBullishEnv = dailyClose > dailyEma50 and trendMomentum > trendThreshold isBearishEnv = dailyClose < dailyEma50 and trendMomentum < -trendThreshold isNoTradeZone = not isBullishEnv and not isBearishEnv // ==================== 回调区识别 ==================== distanceToEma = math.abs(close - h4Ema20) / h4Atr isBullPullback = isBullishEnv and close <= h4Ema20 + pullbackAtrMult * h4Atr and close >= h4Ema20 - pullbackAtrMult * h4Atr isBearPullback = isBearishEnv and close >= h4Ema20 - pullbackAtrMult * h4Atr and close <= h4Ema20 + pullbackAtrMult * h4Atr // ==================== 入场信号识别 ==================== bodySize = math.abs(close - open) upperWick = high - math.max(close, open) lowerWick = math.min(close, open) - low isBullishCandle = close > open isBearishCandle = close < open isHammer = lowerWick >= bodySize * 1.2 and upperWick < bodySize * 0.5 isShootingStar = upperWick >= bodySize * 1.2 and lowerWick < bodySize * 0.5 // 做多信号 bullSignal1 = isBullishCandle and low < h4Ema20 and close >= h4Ema20 bullSignal2 = isHammer and low < h4Ema20 bullSignal3 = isBullishCandle and close > close[1] and distanceToEma < pullbackAtrMult bullEntrySignal = isBullPullback and (bullSignal1 or bullSignal2 or bullSignal3) // 做空信号 bearSignal1 = isBearishCandle and high > h4Ema20 and close <= h4Ema20 bearSignal2 = isShootingStar and high > h4Ema20 bearSignal3 = isBearishCandle and close < close[1] and distanceToEma < pullbackAtrMult bearEntrySignal = isBearPullback and (bearSignal1 or bearSignal2 or bearSignal3) // ==================== 核心:激进复利仓位计算 ==================== // 计算累计盈利率(用于杠杆触发条件) cumulativeProfitPct = (strategy.equity - strategy.initial_capital) / strategy.initial_capital * 100 // 复利基数:使用当前权益而非初始资金 capitalBase = compoundingMode ? strategy.equity : strategy.initial_capital // 基础风险金额(你的3%配置) baseRiskAmount = capitalBase * riskPercentage / 100 // 杠杆触发条件:累计盈利>10%且当前是牛市 useLeverage = compoundingMode and cumulativeProfitPct >= 10.0 and isBullishEnv // 应用杠杆倍数 effectiveLeverage = useLeverage ? maxLeverage : 1.0 leveragedRiskAmount = baseRiskAmount * effectiveLeverage // 止损距离 stopDistance = stopAtrMult * h4Atr // 计算合约数量 contractSize = leveragedRiskAmount / stopDistance // 仓位占比限制 nominalValue = contractSize * close positionPct = nominalValue / strategy.equity * 100 // 如果超过最大仓位占比,强制缩小 if positionPct > maxPositionPct contractSize := strategy.equity * maxPositionPct / 100 / close // 最终合约数 finalContractSize = math.floor(contractSize * 1000) / 1000 actualRiskAmount = finalContractSize * stopDistance // ==================== 风控熔断机制 ==================== var float dayStartEquity = strategy.initial_capital if ta.change(time("D")) dayStartEquity := strategy.equity dailyPnL = strategy.equity - dayStartEquity dailyPnLPct = dailyPnL / strategy.equity * 100 isDailyCircuitBreaker = dailyPnLPct <= -dailyLossLimit var float peakEquity = strategy.initial_capital if strategy.equity > peakEquity peakEquity := strategy.equity currentDrawdown = (peakEquity - strategy.equity) / peakEquity * 100 isDefenseMode = currentDrawdown >= totalDrawdownLimit // ==================== 持仓状态管理 ==================== var float entryPrice = na var float currentStopLoss = na var float riskUnit = na var int profitStage = 0 var float maxR = 0.0 bool hasPosition = strategy.position_size != 0 bool isLong = strategy.position_size > 0 bool isShort = strategy.position_size < 0 // ==================== 开仓逻辑 ==================== canOpenLong = bullEntrySignal and not hasPosition and not isDailyCircuitBreaker and not isNoTradeZone and not isDefenseMode canOpenShort = bearEntrySignal and not hasPosition and not isDailyCircuitBreaker and not isNoTradeZone and not isDefenseMode if canOpenLong and finalContractSize > 0 leverageText = effectiveLeverage > 1.0 ? " [杠杆:" + str.tostring(effectiveLeverage, "#.#") + "x]" : "" strategy.entry("Long", strategy.long, qty=finalContractSize, comment="激进多单 $" + str.tostring(actualRiskAmount, "#") + leverageText) entryPrice := close currentStopLoss := close - stopDistance riskUnit := stopDistance profitStage := 0 maxR := 0.0 if canOpenShort and finalContractSize > 0 leverageText = effectiveLeverage > 1.0 ? " [杠杆:" + str.tostring(effectiveLeverage, "#.#") + "x]" : "" strategy.entry("Short", strategy.short, qty=finalContractSize, comment="激进空单 $" + str.tostring(actualRiskAmount, "#") + leverageText) entryPrice := close currentStopLoss := close + stopDistance riskUnit := stopDistance profitStage := 0 maxR := 0.0 // ==================== 激进分级止盈逻辑 ==================== currentR = 0.0 if isLong and not na(entryPrice) currentR := (close - entryPrice) / riskUnit maxR := math.max(maxR, currentR) // 阶段1:延迟保本(1.2R)- 你的配置 if currentR >= breakEvenR and profitStage < 1 currentStopLoss := math.max(currentStopLoss, entryPrice) profitStage := 1 // 阶段2:延迟锁利(3R锁1R)- 你的配置 if currentR >= lockSmallR and profitStage < 2 currentStopLoss := math.max(currentStopLoss, entryPrice + lockSmallLevel * riskUnit) profitStage := 2 // 阶段3:大利润锁定(6R锁3R)- 你的配置 if currentR >= lockBigR and profitStage < 3 currentStopLoss := math.max(currentStopLoss, entryPrice + lockBigLevel * riskUnit) profitStage := 3 // 利润回撤熔断(4R后回撤2R就平仓) if useGivebackKill and maxR >= givebackStartR and (maxR - currentR) >= maxGivebackR strategy.close("Long", comment="回撤熔断 峰值:" + str.tostring(maxR, "#.#") + "R") entryPrice := na profitStage := 0 maxR := 0.0 // 实时止损检查 else if close <= currentStopLoss strategy.close("Long", comment="止损 R:" + str.tostring(currentR, "#.#")) entryPrice := na profitStage := 0 maxR := 0.0 // 趋势终结强平 else if dailyClose < dailyEma50 strategy.close("Long", comment="趋势终结 R:" + str.tostring(currentR, "#.#")) entryPrice := na profitStage := 0 maxR := 0.0 if isShort and not na(entryPrice) currentR := (entryPrice - close) / riskUnit maxR := math.max(maxR, currentR) if currentR >= breakEvenR and profitStage < 1 currentStopLoss := math.min(currentStopLoss, entryPrice) profitStage := 1 if currentR >= lockSmallR and profitStage < 2 currentStopLoss := math.min(currentStopLoss, entryPrice - lockSmallLevel * riskUnit) profitStage := 2 if currentR >= lockBigR and profitStage < 3 currentStopLoss := math.min(currentStopLoss, entryPrice - lockBigLevel * riskUnit) profitStage := 3 if useGivebackKill and maxR >= givebackStartR and (maxR - currentR) >= maxGivebackR strategy.close("Short", comment="回撤熔断 峰值:" + str.tostring(maxR, "#.#") + "R") entryPrice := na profitStage := 0 maxR := 0.0 else if close >= currentStopLoss strategy.close("Short", comment="止损 R:" + str.tostring(currentR, "#.#")) entryPrice := na profitStage := 0 maxR := 0.0 else if dailyClose > dailyEma50 strategy.close("Short", comment="趋势终结 R:" + str.tostring(currentR, "#.#")) entryPrice := na profitStage := 0 maxR := 0.0 // ==================== 图表显示 ==================== plot(dailyEma50, "日线EMA50", color=color.orange, linewidth=2) plot(h4Ema20, "4H EMA20", color=color.blue, linewidth=1) upperBand = h4Ema20 + pullbackAtrMult * h4Atr lowerBand = h4Ema20 - pullbackAtrMult * h4Atr plot(upperBand, "回调上轨", color=color.new(color.gray, 70)) plot(lowerBand, "回调下轨", color=color.new(color.gray, 70)) plot(hasPosition ? currentStopLoss : na, "动态止损", color=color.red, style=plot.style_linebr, linewidth=2) plot(hasPosition ? entryPrice : na, "入场价", color=color.white, style=plot.style_linebr, linewidth=1) // 背景色:杠杆模式用深绿,普通牛市浅绿,熊市红色 bgColor = useLeverage ? color.new(color.green, 80) : isBullishEnv ? color.new(color.green, 95) : isBearishEnv ? color.new(color.red, 95) : color.new(color.gray, 97) bgcolor(bgColor) plotshape(canOpenLong, "做多", shape.triangleup, location.belowbar, color.lime, size=size.small) plotshape(canOpenShort, "做空", shape.triangledown, location.abovebar, color.red, size=size.small) // 杠杆启用标记 plotshape(useLeverage and not hasPosition, "杠杆模式", shape.diamond, location.top, color.yellow, size=size.tiny) // ==================== 激进版Dashboard ==================== var table dashboard = table.new(position.top_right, 2, 12, bgcolor=color.new(color.black, 85), border_width=1) if barstate.islast // 标题 table.cell(dashboard, 0, 0, "激进复利版 v3.0", text_color=color.white, text_size=size.normal, bgcolor=color.new(color.red, 50)) table.cell(dashboard, 1, 0, "高风险高回报", text_color=color.yellow, text_size=size.normal, bgcolor=color.new(color.red, 50)) // 账户状态 table.cell(dashboard, 0, 1, "当前权益", text_color=color.white, text_size=size.small) equityColor = strategy.equity > strategy.initial_capital ? color.lime : color.red table.cell(dashboard, 1, 1, "$" + str.tostring(strategy.equity, "#,###"), text_color=equityColor, text_size=size.small) // 累计盈利 table.cell(dashboard, 0, 2, "累计盈利", text_color=color.white, text_size=size.small) profitColor = cumulativeProfitPct > 0 ? color.lime : color.red table.cell(dashboard, 1, 2, str.tostring(cumulativeProfitPct, "#.#") + "%", text_color=profitColor, text_size=size.small) // 杠杆状态 table.cell(dashboard, 0, 3, "当前杠杆", text_color=color.white, text_size=size.small) leverageColor = effectiveLeverage > 1.0 ? color.yellow : color.gray leverageStatus = effectiveLeverage > 1.0 ? str.tostring(effectiveLeverage, "#.#") + "x 🚀" : "1.0x" table.cell(dashboard, 1, 3, leverageStatus, text_color=leverageColor, text_size=size.small) // 基础风险(3%) table.cell(dashboard, 0, 4, "基础风险", text_color=color.white, text_size=size.small) table.cell(dashboard, 1, 4, "$" + str.tostring(baseRiskAmount, "#") + " (3%)", text_color=color.aqua, text_size=size.small) // 实际风险(含杠杆) table.cell(dashboard, 0, 5, "实际风险", text_color=color.white, text_size=size.small) actualRiskColor = actualRiskAmount > baseRiskAmount ? color.orange : color.lime table.cell(dashboard, 1, 5, "$" + str.tostring(actualRiskAmount, "#"), text_color=actualRiskColor, text_size=size.small) // 趋势状态 trendText = isBullishEnv ? "多头 ▲" : isBearishEnv ? "空头 ▼" : "震荡 ■" trendColor = isBullishEnv ? color.lime : isBearishEnv ? color.red : color.gray table.cell(dashboard, 0, 6, "趋势", text_color=color.white, text_size=size.small) table.cell(dashboard, 1, 6, trendText, text_color=trendColor, text_size=size.small) // 回调状态 pullbackText = isBullPullback ? "回调区 ✓" : isBearPullback ? "反弹区 ✓" : "等待..." table.cell(dashboard, 0, 7, "回调", text_color=color.white, text_size=size.small) table.cell(dashboard, 1, 7, pullbackText, text_color=(isBullPullback or isBearPullback) ? color.yellow : color.gray, text_size=size.small) // 持仓状态 posText = isLong ? "持多 ●" : isShort ? "持空 ●" : "空仓 ○" posColor = isLong ? color.lime : isShort ? color.red : color.gray table.cell(dashboard, 0, 8, "持仓", text_color=color.white, text_size=size.small) table.cell(dashboard, 1, 8, posText, text_color=posColor, text_size=size.small) // 当前R倍数 table.cell(dashboard, 0, 9, "当前R", text_color=color.white, text_size=size.small) rColor = currentR > 0 ? color.lime : currentR < 0 ? color.red : color.gray table.cell(dashboard, 1, 9, str.tostring(currentR, "#.##") + "R", text_color=rColor, text_size=size.small) // 历史最高R table.cell(dashboard, 0, 10, "峰值R", text_color=color.white, text_size=size.small) table.cell(dashboard, 1, 10, str.tostring(maxR, "#.##") + "R", text_color=color.lime, text_size=size.small) // 止盈阶段 stageText = profitStage == 0 ? "初始" : profitStage == 1 ? "已保本" : profitStage == 2 ? "锁小利" : "锁大利" table.cell(dashboard, 0, 11, "阶段", text_color=color.white, text_size=size.small) table.cell(dashboard, 1, 11, stageText, text_color=color.yellow, text_size=size.small)
trader-c tweet mediatrader-c tweet media
trader-c@TradercBTC

无编程背景,手搓AI量化交易策略。(前提:我手动交易能稳定盈利) 这是我前几天一直调试的整体回测结果,很明显的是在 $xrp ,黄金上效果不好。 另外从曲线看22年到25基本不赚钱。 我去问AI,让AI给我看。(在下文) 看完之后我认为这个对我来说暂时够用,我打算直接扔给OKX去跑策略,然后再改正。 其次AI建议我搞一个震荡策略,但是震荡策略我认为网格是最牛逼的(另外哪有上下60%震荡的,AI懂个🥚) 我打算整一套高买低卖的这种中期波段,或者说流动性收割(均值回归?无所谓了),专门应对21年之后的行情。 所以这周干两件事: 1.扔给OKX跑这个趋势策略。Pine Script逻辑转换成Python代码,扔到币安。 2.搞一套21之后的这种均值回归的策略。 理论上把这些细节单独开发出来,AI可以识别且自主决策,使用哪一套策略从而实现80%的自主交易。 另外最大单笔开仓名义金额在3w💲,理论上3000💲十倍就可以跑,我设置的最大亏3500,因此合理来说保证金在1w就能run。(举例子) (有问题评论区问,代码我两个月内如果测试盈利,我就直接公开,业内管这叫啥?开源?) (其实考虑的很多,成本啊之类的,但是先说这么多,搞得东西太多了不知道说啥,慢慢发吧) 以下是AI评价👇: 本质:只干两件事 顺着大趋势,在回调的时候埋伏进去,吃那一大段。 所以: 有明显方向、能走大波段的币(ETH、BTC、SOL) → 很强 长期横盘、假突破一堆的标的(XRP、黄金) → 天然吃亏 我这套系统是「专门打趋势波段」的, 对象是 BTC / ETH / SOL 这种“大起大落”的币, 像 XRP、黄金这种天天阴间横盘的,本来就不是我的猎场。 2. 为啥 XRP、黄金这么拉胯? XRP: 长期就是:偶尔暴冲一下 → 又回去横 真正给你吃到的趋势很少 大部分时间都在区间里「上下一点点晃你止损」 → 这种“回调狙击 + 动量过滤”的逻辑,在 XRP 上就是被当韭菜晃。 黄金: 波动小 + 走得慢,适合传统机构那种长线、宏观交易 参数是按「加密币那种大起大落」调出来的 → 放到黄金上就是:要么信号很少 要么一进场就被正常波动扫止损 再加上动不动就被宏观数据、央行讲话反杀 → 回测长期看下来,亏是很正常的。 这套系统就是「加密趋势专用」, XRP / 黄金不适合,表现差反而证明它没有乱来。 3. 22–25 年为啥曲线变平? 核心:不是策略坏了,而是市场给你的“好球”变少了。 可以这样理解: 17–21:典型「狂牛 + 深熊」循环大涨大跌 → 你的趋势系统机会超级多 一波牛市能连吃很多 5R、8R、10R 的大单 22–25:整体是「阴跌 + 大震荡 + 假突破」真正干净的大趋势很少 你的「动量 + EMA50 过滤」一开,多数时间压根不开枪 偶尔有一波上涨,也是:拉一点 → 横很久 → 慢慢磨下来 你的分级止盈能锁一点,但很难再出现那种「一骑绝尘」的大波段 所以你看到: 曲线不再像 17–21 年那样狂飙 但也没有大幅回撤,而是「横着 + 轻微上下」→ 这其实说明:在不适合的行情里,你的系统选择「少出手」而不是「乱亏钱」——这是优点。 22–25 年这三年,本来就是「烂行情为主,趋势行情减少」的阶段, 系统在这段时间更多是保护本金 + 小打小闹, 真正的大爆发还得等下一轮像 17–21 那样的周期。

中文
26
98
434
65.6K