资源加载中... loading...

基于移动平均线交叉策略

Author: ChaoZhang, Date: 2023-10-24 16:39:40
Tags:

基于移动平均线交叉策略

概述

本策略基于移动平均线交叉原理,当短期均线从下方上穿长期均线时做多,当短期均线从上方向下穿长期均线时做空,属于典型的趋势跟踪策略。

策略原理

该策略主要通过计算短期与长期两条简单移动平均线,并根据它们的交叉情况判断趋势方向。

具体来说,策略首先计算短期均线xMA和长期均线,短期均线长度为Len,长期均线长度为2*Len。

然后策略判断短期均线是否上穿长期均线,如果发生上穿则产生做多信号;判断短期均线是否下穿长期均线,如果发生下穿则产生做空信号。

收到做多信号后,若当前没有持仓,则按市价开仓做多;收到做空信号后,若当前没有持仓,则按市价开仓做空。

此外,策略还设置了止损止盈点。做多后设置止损价为入场价-止损百分比*入场价,止盈价为入场价+止盈百分比*入场价;做空后设置止损价为入场价+止损百分比*入场价,止盈价为入场价-止盈百分比*入场价。

最后,策略还输出均线的可视化曲线,以辅助判断趋势。

策略优势

  • 思路简单清晰,容易理解实现,适合新手学习;

  • 基于移动平均线判断趋势方向,可以有效跟踪市场趋势;

  • 设置止损止盈点,可以控制风险;

  • 可视化展示均线曲线,直观反映趋势变化。

策略风险

  • 均线具有滞后性,可能引发错过最佳入场时点的风险;

  • 止损点设置不合理可能导致止损过于宽松或过于严格;

  • 股价剧烈波动时,均线产生假信号的可能;

  • 仅基于均线周期参数进行参数优化,可能导致过拟合。

可以通过适当宽松止损,优化均线周期参数组合,增加其他指标过滤来减少这些风险。

策略优化方向

  • 增加其他指标进行过滤,例如MACD,KDJ等,避免均线错位产生错误信号;

  • 对短期均线和长期均线长度进行多组合优化,找到最佳参数组合;

  • 测试不同的止损止盈策略,如之字止损,移动止损等方式;

  • 添加仓位管理模块,优化资金利用效率。

总结

本策略整体思路清晰简洁,基于均线交叉判断趋势方向,可有效跟踪趋势,且风险可控,适合新手学习参考。但仅依赖均线可能出现错误信号,优化空间还很大,可以从多方面进行优化改进,使策略更稳健可靠。


/*backtest
start: 2023-09-23 00:00:00
end: 2023-10-23 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
//@strategy_alert_message {{strategy.order.alert_message}} 
////////////////////////////////////////////////////////////
//  Copyright by HPotter v2.0 19/09/2023
// MA Crossover Bot for OKX Exchange
////////////////////////////////////////////////////////////
var ALERTGRP_CRED = "entry"
signalToken = input("", "Signal Token", inline = "11", group = ALERTGRP_CRED)
OrderType = input.string("market", "Order Type", options = ["market", "limit"], inline = "21", group = ALERTGRP_CRED)
OrderPriceOffset = input.float(0, "Order Price Offset", minval = 0, maxval = 100, step = 0.01, inline = "21", group = ALERTGRP_CRED)
InvestmentType = input.string("percentage_balance", "Investment Type", options = ["margin", "contract", "percentage_balance", "percentage_investment"], inline = "31", group = ALERTGRP_CRED)
Amount = input.float(100, "Amount", minval = 0.01, inline = "31", group = ALERTGRP_CRED)

getAlertMsg(action, instrument, signalToken, orderType, orderPriceOffset, investmentType, amount) =>
    str = '{'
    str := str + '"action": "' + action + '", '
    str := str + '"instrument": "' + instrument + '", '
    str := str + '"signalToken": "' + signalToken + '", '
    //str := str + '"timestamp": "' + str.format_time(timenow, "yyyy-MM-dd'T'HH:mm:ssZ", "UTC+0") + '", '
    str := str + '"timestamp": "' + '{{timenow}}' + '", '
    str := str + '"orderType": "' + orderType + '", '
    str := str + '"orderPriceOffset": "' + str.tostring(orderPriceOffset) + '", '
    str := str + '"investmentType": "' + investmentType + '", '
    str := str + '"amount": "' + str.tostring(amount) + '"'
    str := str + '}'
    str

getOrderAlertMsgExit(action, instrument, signalToken) =>
    str = '{'
    str := str + '"action": "' + action + '", '
    str := str + '"instrument": "' + instrument + '", '
    str := str + '"signalToken": "' + signalToken + '", '
    str := str + '"timestamp": "' + '{{timenow}}' + '", '
    str := str + '}'
    str

strategy(title='OKX: MA Crossover', overlay=true)
Len = input(13)
Profit = input.float(7, title='Take Profit %', minval=0.01) / 100
Stop =  input.float(7, title='Stop Loss %', minval=0.01) / 100
xMA = ta.sma(close, Len)
//Robot State
isLong = strategy.position_size > 0 
isShort = strategy.position_size < 0 
isFlat = strategy.position_size == 0 
//Current Signal
doLong = low < xMA[1] ? true : false
doShort =   high > xMA[1] ? true:  false
//Backtest Start Date
tm =  timestamp(2022, 01, 01, 09, 30)
//Entry and exit orders
if  doLong[2] == false and isLong == false and doLong and time > tm
    strategy.cancel_all()
    buyAlertMsgExit = getOrderAlertMsgExit(action = 'EXIT_LONG', instrument = syminfo.ticker, signalToken = signalToken)
    buyAlertMsg = getAlertMsg(action = 'ENTER_LONG', instrument = syminfo.ticker, signalToken = signalToken, orderType =  OrderType, orderPriceOffset =  OrderPriceOffset, investmentType =  InvestmentType, amount = Amount)
    strategy.entry('Long', strategy.long, limit = close, comment='Long', alert_message =buyAlertMsg)
    strategy.exit("ExitLong", 'Long', stop=close - close * Stop  , limit = close + close * Profit , qty_percent = 100, alert_message = buyAlertMsgExit)  
if doShort[2] == false and isShort == false and doShort and time > tm
    strategy.cancel_all()
    sellAlertMsgExit = getOrderAlertMsgExit(action = 'EXIT_SHORT', instrument = syminfo.ticker, signalToken = signalToken)
    sellAlertMsg = getAlertMsg(action = 'ENTER_SHORT', instrument = syminfo.ticker, signalToken = signalToken, orderType =  OrderType, orderPriceOffset =  OrderPriceOffset, investmentType =  InvestmentType, amount = Amount)
    strategy.entry('Short', strategy.short, limit=close, comment='Short', alert_message = sellAlertMsg)
    strategy.exit("ExitShort", 'Short', stop=close + close * Stop  , limit = close - close * Profit  , qty_percent = 100, alert_message = sellAlertMsgExit)  
//Visual
barcolor(isShort  ? color.red : isLong ? color.green : color.blue)
plot(xMA, color=color.new(color.red, 0), title='MA')

更多内容