Cette stratégie utilise un système de moyenne mobile pour déterminer la direction de la tendance actuelle et fait des positions longues ou courtes en fonction de la tendance. Lorsque la moyenne mobile monte, la confiance en long est plus élevée, alors allez long. Lorsque la moyenne mobile descend, la confiance en court est plus élevée, alors allez court. Cette stratégie utilise principalement le système de moyenne mobile pour déterminer la direction de la tendance du marché, appartenant à la stratégie de tendance suivante.
Calculer la moyenne mobile pondérée vwma comme indicateur de la moyenne mobile pour une certaine période (défaut 400 périodes).
Déterminez si la moyenne mobile vwma est en hausse, si elle est en hausse définissez la tendance haussière du signal long; si elle est en baisse définissez la tendance baissière du signal court.
Lorsque la tendance haussière est vraie, allez long; lorsque la tendance baissière est vraie, fermez long et allez court.
Calculer la stratégie de retour bar_pnl et acheter et conserver retour bar_bh pour chaque barre.
Selon les horodatages trimestriels et annuels, calculer le rendement trimestriel de la stratégie quarter_pnl, le rendement annuel year_pnl et les rendements correspondants buy & hold quarter_bh, year_bh.
Afficher le rendement trimestriel de la stratégie par rapport au rendement de l'achat et de la détention dans un tableau.
Les principaux avantages de cette stratégie sont les suivants:
Simple à utiliser, facile à comprendre, détermine la tendance du marché par moyenne mobile.
Suivre la tendance réduit les pertes sur les marchés qui ne suivent pas la tendance.
Peu de paramètres réglables, principalement la période de moyenne mobile, facile à tester et à optimiser.
Tableau de retour intuitif pour montrer clairement les résultats.
Ajouter le rendement d'achat et de détention dans le tableau pour la comparaison, montre le rendement excédentaire.
Position de table flexible, facile à intégrer à d'autres stratégies.
Il y a aussi des risques:
La sous-performance sur le marché haussier à long terme par rapport à l'achat et à la détention peut optimiser la période moyenne mobile.
Un risque élevé sur le marché de l'intervalle peut ajouter des conditions de filtrage comme briser le précédent sommet pour réduire les transactions.
Les moyennes mobiles ont une mauvaise capacité d'ajustement à la courbe, peuvent manquer les points tournants de la tendance.
Il n'y a pas de mécanisme de stop-loss, il y a un risque de retrait énorme.
Pour le tableau, vous pouvez ajouter des indicateurs de risque comme le ratio de netteté, le tirage maximal.
La stratégie peut être optimisée dans les aspects suivants:
Optimiser les paramètres de la moyenne mobile, ajuster la période en fonction des régimes du marché.
Ajouter des filtres comme briser le précédent haut pour réduire les coups de fouet.
Essayez différents types de moyennes mobiles, comme WMA, DEMA etc.
Ajoutez des mécanismes de stop loss, comme les stops dynamiques ou le dimensionnement des positions.
Enrichir le contenu de la table, ajouter des métriques comme le ratio de netteté, le tirage maximal.
Combinez avec d'autres indicateurs comme MACD, Bollinger Bands pour déterminer les tendances.
Optimiser la taille des positions, ajuster les positions dynamiquement en fonction des conditions du marché.
Testez sur différents produits, trouvez la meilleure application.
La stratégie de trading de moyenne mobile est relativement simple et directe. Elle suit la tendance en déterminant la tendance en utilisant la moyenne mobile, avec un bon contrôle de la baisse, adapté aux traders qui suivent la tendance. Il y a encore beaucoup de place pour l'optimisation, comme le système de moyenne mobile, le mécanisme de stop loss, le dimensionnement des positions, etc., pour la rendre adaptable à des environnements de marché complexes.
/*backtest start: 2022-10-23 00:00:00 end: 2023-10-29 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © Dannnnnnny //@version=4 strategy(title="Quarterly Returns in Strategies vs Buy & Hold", initial_capital= 1000, overlay=true,default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.1) maLength= input(400) wma= vwma(hl2,maLength) uptrend= rising(wma, 5) downtrend= falling(wma,5) plot(wma) if uptrend strategy.entry("Buy", strategy.long) else strategy.close("Buy")// /////////////////// // QUARTERLY TABLE // enableQuarterlyTable = input(title="Enable Quarterly Return table", type=input.bool, defval=false) enableCompareWithMarket = input(title="Compare with Market Benchmark", type=input.bool, defval=false) table_position = input(title="Table Position", type=input.string, defval='bottom_right', options=['bottom_right','bottom_left','top_right', 'top_left']) precision = 2 new_quarter = ceil(month(time)/3) != ceil(month(time[1])/3) new_year = year(time) != year(time[1]) eq = strategy.equity bar_pnl = eq / eq[1] - 1 bar_bh = (close-close[1])/close[1] cur_quarter_pnl = 0.0 cur_year_pnl = 0.0 cur_quarter_bh = 0.0 cur_year_bh = 0.0 // Current Quarterly P&L cur_quarter_pnl := new_quarter ? 0.0 : (1 + cur_quarter_pnl[1]) * (1 + bar_pnl) - 1 cur_quarter_bh := new_quarter ? 0.0 : (1 + cur_quarter_bh[1]) * (1 + bar_bh) - 1 // Current Yearly P&L cur_year_pnl := new_year ? 0.0 : (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1 cur_year_bh := new_year ? 0.0 : (1 + cur_year_bh[1]) * (1 + bar_bh) - 1 // Arrays to store Yearly and Quarterly P&Ls var quarter_pnl = array.new_float(0) var quarter_time = array.new_int(0) var quarter_bh = array.new_float(0) var year_pnl = array.new_float(0) var year_time = array.new_int(0) var year_bh = array.new_float(0) end_time = false end_time:= time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory if (not na(cur_quarter_pnl[1]) and (new_quarter or end_time)) if (end_time[1]) array.pop(quarter_pnl) array.pop(quarter_time) array.push(quarter_pnl , cur_quarter_pnl[1]) array.push(quarter_time, time[1]) array.push(quarter_bh , cur_quarter_bh[1]) if (not na(cur_year_pnl[1]) and (new_year or end_time)) if (end_time[1]) array.pop(year_pnl) array.pop(year_time) array.push(year_pnl , cur_year_pnl[1]) array.push(year_time, time[1]) array.push(year_bh , cur_year_bh[1]) // Quarterly P&L Table var quarterly_table = table(na) getCellColor(pnl, bh) => if pnl > 0 if bh < 0 or pnl > 2 * bh color.new(color.green, transp = 20) else if pnl > bh color.new(color.green, transp = 50) else color.new(color.green, transp = 80) else if bh > 0 or pnl < 2 * bh color.new(color.red, transp = 20) else if pnl < bh color.new(color.red, transp = 50) else color.new(color.red, transp = 80) if (end_time and enableQuarterlyTable) quarterly_table := table.new(table_position, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1) table.cell(quarterly_table, 0, 0, "", bgcolor = #cccccc) table.cell(quarterly_table, 1, 0, "Q1", bgcolor = #cccccc) table.cell(quarterly_table, 2, 0, "Q2", bgcolor = #cccccc) table.cell(quarterly_table, 3, 0, "Q3", bgcolor = #cccccc) table.cell(quarterly_table, 4, 0, "Q4", bgcolor = #cccccc) table.cell(quarterly_table, 5, 0, "Year", bgcolor = #999999) for yi = 0 to array.size(year_pnl) - 1 table.cell(quarterly_table, 0, yi + 1, tostring(year(array.get(year_time, yi))), bgcolor = #cccccc) y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi)) table.cell(quarterly_table, 5, yi + 1, enableCompareWithMarket ? tostring(round(array.get(year_pnl, yi) * 100, precision)) + " (" + tostring(round(array.get(year_bh, yi) * 100, precision)) + ")" : tostring(round(array.get(year_pnl, yi) * 100, precision)), bgcolor = y_color, text_color=#bfbfbf) for mi = 0 to array.size(quarter_time) - 1 m_row = year(array.get(quarter_time, mi)) - year(array.get(year_time, 0)) + 1 m_col = ceil(month(array.get(quarter_time, mi)) / 3) m_color = getCellColor(array.get(quarter_pnl, mi), array.get(quarter_bh, mi)) table.cell(quarterly_table, m_col, m_row, enableCompareWithMarket ? tostring(round(array.get(quarter_pnl, mi) * 100, precision)) + " (" + tostring(round(array.get(quarter_bh, mi) * 100,precision)) +")" : tostring(round(array.get(quarter_pnl, mi) * 100, precision)), bgcolor = m_color, text_color=#bfbfbf)