联系我们:微信:qhltcn | QQ:116589960
返回列表 发帖

John Ehlers’ article in 2017-07 issue, “The Deviation-Scaled Moving Average.”

John Ehlers’ article in 2017-07 issue, “The Deviation-Scaled Moving Average.”

TRADESTATION平台源码:
JULY 2018源码:
Function: EhlersDSMA
本帖隐藏的内容需要回复才可以浏览

Indicator: DSMA
本帖隐藏的内容需要回复才可以浏览


Strategy: DSMA
本帖隐藏的内容需要回复才可以浏览



效果图:
TT-Tradestation.gif
2018-6-20 16:27


FIGURE 1: TRADESTATION. This shows a daily chart of AAPL with the DSMA indicator and strategy.
期货论坛管理员,官方开户、量化、广告以及合作事宜,联系微信:qhltcn  QQ:116589960

MC源码与TS源码同乎一致,所以上面的指标可以直接移植到MC上面去。指标与交易策略效果如下图:

期货论坛管理员,官方开户、量化、广告以及合作事宜,联系微信:qhltcn  QQ:116589960

TOP

仔细学习,认真研究

TOP

原文如下:
The Deviation-Scaled Moving Average

Moving averages have two characteristics—they lag and they smooth data. But there are different ways to tweak them. Here’s one way to make them more adaptive to current prices and make the smoothing heavier.
Adaptive moving averages are not new to technical analysis. If you’re familiar with adaptive techniques, you’ll know that most start with an exponential moving average(EMA). The EMA is a smoothing filter that takes a fraction of the current price and adds the complement of that fraction times the value of the EMA one barago. The EMA equation is:


EMA = a*Close + (1 – a)*EMA[1];

W hat ’ s alpha ?


The alpha term is a number that can vary between zero and 1. When a is smaller, only a small fraction of the current price is used and a large fraction of the previous calculation is used. The result is an EMA that provides considerable smoothing. Conversely, when a is relatively large, a big fraction of the current price isused, which results in very little smoothing provided by the EMA. The idea of an adaptive moving aver-
age is to modify the alpha term according to another independently measured market condition.

Two of the more popular adaptive moving aver-ages are VIDYA and KAMA. VIDYA, developed by Tushar Chande, uses the equivalent of an RSI to adjust the alpha term. KAMA, developed by Perry Kaufman, uses an effectiveness ratio to adjust the alpha term. The effectiveness ratio is the total price change over a calculation period divided by the sum of the bar-to-bar price changes over the same period. Both of these adaptive moving averages require the alpha modifier’s calculation to be accomplished over a number of bars of data, with the result of induced computational lag.


a nother Way to modify alpha


The deviation-scaled moving average (DSMA) modi-fies the EMA’s alpha in terms of the amplitude of an oscillator scaled to the standard deviation from the mean. Since the oscillator almost directly follows the price, the computational lag of the DSMA is mini-mal. Therefore, the DSMA rapidly adapts to price variations. In addition, when the standard deviation from the mean is small, the effective alpha term of the EMA is made to be small. The result is there is considerable smoothing by the DSMA when price variations are small.

The DMSA is probably best described with reference to the code in the sidebar “EasyLanguage Code For Deviation-Scaled Moving Average.” The user input for the indicator is the critical period of a filter. The critical period of a smoothing filter is the cycle period at which the power of the signal allowed through the filter is reduced by half. Shorter cycle periods are re-duced even more, so the filter achieves its smoothing function by not allowing the short cycle components in the spectrum to pass through to its output. The alpha term of the EMA is often described with reference to the length of a simple moving average. I prefer to relate the EMA alpha term to the filter critical period.The approximate relationship is simple, and can be expressed as:
a = 5 / Period






In the DMSA, its alpha term is exactly equal to an EMA us-ing the same critical period if the scaled amplitude deviation of the oscillator is 1.

Z eros oscillator



After inputs and declaration of variables, the computation of the standard deviation starts with an oscillator called zeros that is a simple two-bar difference of prices. This oscillator is important because of two characteristics in its transfer response.



First, when the cycle periods are very long and, at the limit, there is no change in price, the transfer response is zero. It is this characteristic that provides the nominal zero mean in the oscillator output. Further, its filter rolloff from shorter cycle periods is -6 dB per octave. Market data are fractal, meaning the cycle amplitudes in its spectrum increase in direct proportion to their cycle periods. That means the data cycle amplitudes increase statistically at the rate of 6 dB per octave. Since the oscillator rolloff is -6 dB per octave and spectrum amplitudes are statistically increasing at the rate of +6 dB per octave, the result is that the zeros oscillator whitens the price spectrum. This is a good thing.



Second, when the cycle period is exactly at twice the sampling rate, the samples are exactly one cycle period apart. This is called the Nyquist frequency period, and is the shortest possible period in sampled data. In the zeros oscillator the transfer response is zero at the Nyquist period because the samples are exactly one period apart for that spectral component. Having a zero in the transfer response at the Nyquist period eliminates the 6 dB increase in noise produced by a simple one-bar difference. Having a zero in the transfer response at the Nyquist period also reduces the impact of aliased data in the oscillator output.



The zeros oscillator output is smoothed in my two-pole Super-Smoother filter. The critical period of the SuperSmoother filter is half the input period to retain the oscillator’s responsiveness,and the filter coefficients are calculated only on the first bar of data for computational efficiency.


Since the zeros oscillator has a nominally zero mean, the SuperSmoother filter output also has a nominally zero mean. Therefore, the standard deviation can be calculated as the square root of the average sum of the squares of the smoothed filter waveform over the input period. This is commonly called the root mean square (RMS).



When you divide the RMS into the smoothed filter waveform, it scales the waveform in terms of standard deviations. When you start with alpha computed in terms of the input period and then multiply it by the variable deviations, it scales alpha both in terms of the input and in terms of the current volatility. The scaling goes in the right direction at the right time. When the price deviation of the oscillator is large, the RMS is large, and consequently alpha is large. When alpha is large, there is very little EMA filtering and the filter quickly adapts to current prices. Conversely, when the price deviation of the oscillator is small, the RMS is small and alpha is small. When alpha is small, the EMA produces heavy smoothing.



The DSMA is an adaptive moving average that adapts rapidly to volatility in price movement.



The action of the DSMA speaks for itself in Figure 1. On the chart of the SPY in Figure 1, which uses data for the calendar year 2017, notice how the DSMA adapts to price action. You can change the responsiveness of the DSMA by simply changing the period input parameter.



A dApting to volAtility



In summary, the DSMA is an adap-tive moving average that features rapid adaptation to volatil-ity in price move-ment. It accomplishes this adaptation by modifying the alpha term of an EMA by the amplitude of an oscillator scaled in standard deviations from the mean. The DSMA’s responsiveness can be changed by using different values for the input parameter period.



S tockS & c ommoditieS Contributing Editor John Ehlers is a pioneer in theuse of cycles and DSP technical analy-sis. He is president of MESA Software and cofounder of StockSpotter.com and BeYourOwnHedgeFund.com, which is a new site that provides portfolios based on his algorithmic strategies.


The code given in this article is available in the Article Code section of our website,Traders.com.


See our Traders’ Tips section beginning on page 48 for commentary and implementa-tion of John Ehlers’ technique in various technical analysis programs. Accompanying program code can be found in the Traders’ Tips area at Traders.com.
期货论坛管理员,官方开户、量化、广告以及合作事宜,联系微信:qhltcn  QQ:116589960

TOP

MultiCharts 平台源码:
MC平台从某种意义上说就是TS平台的移植版,几乎TS平台上面所有的策略都可以经过稍微的改进而在MC平台上面跑,TS是EL语言,MC是PL语言,PL兼容EL语言。
与TS平台一致,MC平台上面也主要分:函数、指标与信号三大部分。函数是计算原始数据,指标是将原始数据按函数输出成想要的指标。信号就是在函数基础上增加了买卖策略,这三个部分是依次从原始到高级的过程。

函数部分源码:EhlersDSMA
  1. // Deviation Scaled Moving Average (DSMA)
  2. // (c) 2013 - 2018 John F. Ehlers
  3. // TASC JUL 2018
  4. // EhlersDSMA function

  5. inputs:
  6.     Period( numericsimple ) ;
  7.    
  8. variables:
  9.     a1( 0 ),
  10.     b1( 0 ),
  11.     c1( 0 ),
  12.     c2( 0 ),
  13.     c3( 0 ),
  14.     Zeros( 0 ),
  15.     Filt( 0 ),
  16.     ScaledFilt( 0 ),
  17.     RMS( 0 ),
  18.     count( 0 ),
  19.     alpha1( 0 ),
  20.     DSMA( 0 ) ;
  21.    
  22. once
  23. begin   

  24.     //Smooth with a Super Smoother
  25.     a1 = ExpValue( -1.414 * 3.14159 / ( .5 * Period ) ) ;
  26.     b1 = 2 * a1 * Cosine( 1.414 * 180 / ( .5 * Period ) ) ;
  27.     c2 = b1 ;
  28.     c3 = -a1 * a1 ;
  29.     c1 = 1 - c2 - c3 ;
  30. end ;

  31. //Produce Nominal zero mean with zeros in the transfer
  32. //response at DC and Nyquist with no spectral distortion
  33. //Nominally whitens the spectrum because of 6 dB
  34. //per octave rolloff
  35. Zeros = Close - Close[2] ;

  36. //SuperSmoother Filter
  37. Filt = c1 * ( Zeros + Zeros[1] ) / 2 + c2 * Filt[1] + c3 * Filt[2] ;

  38. //Compute Standard Deviation   
  39. RMS = 0;
  40. For count = 0 to Period - 1
  41. begin
  42.     RMS = RMS + Filt[count] * Filt[count] ;
  43. end ;
  44. RMS = SquareRoot( RMS / Period ) ;

  45. //Rescale Filt in terms of Standard Deviations
  46. If RMS <> 0 then
  47.         ScaledFilt = Filt / RMS ;

  48. alpha1 = AbsValue( ScaledFilt ) * 5 / Period ;
  49. DSMA = alpha1 * Close + ( 1 - alpha1 ) * DSMA[1] ;

  50. EhlersDSMA = DSMA ;
复制代码



指标部分:DSMA

  1. // TASC JUL 2018
  2. // Ehlers DSMA
  3. inputs:
  4.         FastPeriod( 40 ),
  5.         SlowPeriod( 100 ) ;
  6.         
  7. variables:
  8.         FastDSMAValue( 0 ),
  9.         SlowDSMAValue( 0 ) ;
  10.         
  11. FastDSMAValue = EhlersDSMA( FastPeriod ) ;
  12. SlowDSMAValue = EhlersDSMA( SlowPeriod ) ;

  13. Plot1( FastDSMAValue, "FastDSMAValue",green,default,0 ) ;
  14. Plot2( SlowDSMAValue, "SlowDSMAValue",red,default,0 ) ;               

  15. if AlertEnabled  then
  16. begin
  17.         if FastDSMAValue crosses over SlowDSMAValue then
  18.                 Alert( "Fast crossing over Slow" )
  19.         else if Close crosses under FastDSMAValue then
  20.                 Alert( "Slow crossing under Fast" ) ;
  21. end ;
复制代码



信号部分:DSMA

  1. // TASC JUL 2018
  2. // Ehlers DSMA
  3. inputs:
  4.         FastPeriod( 40 ),
  5.         SlowPeriod( 100 ) ;
  6.         
  7. variables:
  8.         FastDSMAValue( 0 ),
  9.         SlowDSMAValue( 0 ) ;
  10.         
  11. FastDSMAValue = EhlersDSMA( FastPeriod ) ;
  12. SlowDSMAValue = EhlersDSMA( SlowPeriod ) ;

  13. if FastDSMAValue crosses above SlowDSMAValue then
  14.         Buy next bar at Market
  15. else if FastDSMAValue crosses below SlowDSMAValue then
  16.         SellShort next bar at Market ;        
复制代码

期货论坛管理员,官方开户、量化、广告以及合作事宜,联系微信:qhltcn  QQ:116589960

TOP

METASTOCK平台: JULY 2018
John Ehlers’ article in this issue, “The Deviation-Scaled Moving Average,” introduces a moving average of the same name. The MetaStock formula for this moving average is provided here.

  1. tp:= Input("time periods",2, 200, 40);
  2. a1:= Exp(-1.414 * 3.14159 / (tp/2));
  3. b1:= 2*a1 * Cos(1.414*180 /(tp/2));
  4. c2:= b1;
  5. c3:= -a1 * a1;
  6. c1:= 1 - c2 - c3;
  7. zeros:= C-Ref(C,-2);
  8. filt:= c1 * (zeros + Ref(zeros, -1))/2 + c2*PREV + c3*Ref(PREV,-1);
  9. ScaledFilt:= filt/Std(filt,tp);
  10. a2:= Abs(ScaledFilt*5)/tp;
  11. If(Cum(1)<=tp+4, C, a2*C + ((1-a2)*PREV))
复制代码
期货论坛管理员,官方开户、量化、广告以及合作事宜,联系微信:qhltcn  QQ:116589960

TOP

eSIGNAL平台策略源码: JULY 2018

For this month’s Traders’ Tip, we’ve provided the study DSMA.efs, based on the article in this issue by John Ehlers, “The Deviation-Scaled Moving Average.” This study is an adaptive moving average.

The study contains formula parameters that may be configured through the edit chart window (right-click on the chart and select “edit chart”). A sample chart is shown in Figure 2.




FIGURE 2: eSIGNAL. Here is an example of the study plotted on a daily chart of SPY.

To discuss this study or download a complete copy of the formula code, please visit the EFS library discussion board forum under the forums link from the support menu at www.esignal.com or visit our EFS KnowledgeBase at www.esignal.com/support/kb/efs/. The eSignal formula script (EFS) is also shown below.

  1. /*********************************
  2. Provided By:  
  3. eSignal (Copyright c eSignal), a division of Interactive Data
  4. Corporation. 2016. All rights reserved. This sample eSignal
  5. Formula Script (EFS) is for educational purposes only and may be
  6. modified and saved under a new file name.  eSignal is not responsible
  7. for the functionality once modified.  eSignal reserves the right
  8. to modify and overwrite this EFS file with each new release.

  9. Description:        
  10.     The Deviation-Scaled Moving Average by John F. Ehlers

  11. Version:            1.00  5/14/2018

  12. Formula Parameters:                     Default:
  13. Period                                  40



  14. Notes:
  15. The related article is copyrighted material. If you are not a subscriber
  16. of Stocks & Commodities, please visit www.traders.com.

  17. **********************************/

  18. var fpArray = new Array();

  19. function preMain(){
  20.     setPriceStudy(true);
  21.     setStudyTitle("DSMA");
  22.    
  23.     var x = 0;
  24.     fpArray[x] = new FunctionParameter("Period", FunctionParameter.NUMBER);
  25.         with(fpArray[x++]){
  26.         setName("Period");
  27.         setLowerLimit(1);
  28.         setDefault(40);
  29.     }
  30. }

  31. var bInit = false;
  32. var bVersion = null;
  33. var xClose = null;
  34. var xRMS = null;
  35. var nDSMA_1 = 0;
  36. var nDSMA = 0;

  37. function main(Period){
  38.     if (bVersion == null) bVersion = verify();
  39.     if (bVersion == false) return;
  40.    
  41.     if (getCurrentBarCount() < Period) return;
  42.    
  43.     if (getBarState() == BARSTATE_ALLBARS){
  44.         bInit = false;
  45.     }
  46.    
  47.     if (getBarState() == BARSTATE_NEWBAR){
  48.         nDSMA_1 = nDSMA;
  49.     }

  50.    
  51.     if (!bInit){
  52.         var a1 = Math.exp(-Math.SQRT2 * Math.PI /(0.5 * Period));
  53.         var b1 = 2 * a1* Math.cos(Math.PI * Math.SQRT2 / (0.5 * Period));
  54.         var c2 = b1;
  55.         var c3 = - a1 * a1;
  56.         var c1 = 1 - c2 - c3;
  57.         nDSMA_1 = 0;
  58.         nDSMA = 0;
  59.         
  60.         xClose = close();
  61.         var xZeros = efsInternal("calc_Zeros", xClose);
  62.         var xSSFilter = efsInternal("calc_SSFilter", xZeros, c1, c2, c3);
  63.         xRMS = efsInternal("calc_RMS", Period, xSSFilter);
  64.                
  65.         bInit = true;
  66.     }

  67.     var alpha1 = Math.abs(xRMS.getValue(0)) * 5 / Period;

  68.     if (getCurrentBarCount() == Period){
  69.         nDSMA_1 = xClose.getValue(-1);
  70.     }

  71.     nDSMA = alpha1 * xClose.getValue(0) + (1 - alpha1) * nDSMA_1
  72.     return nDSMA;
  73. }



  74. function calc_Zeros (xClose){
  75.     if (xClose.getValue(-2) != null)
  76.         return xClose.getValue(0) - xClose.getValue(-2);
  77. }

  78. var nSSFilter = 0;
  79. var nSSFilter_1 = 0;
  80. var nSSFilter_2 = 0;

  81. function calc_SSFilter(xZeros, c1, c2, c3){
  82.     if (xZeros.getValue(-1) == null) return;
  83.    
  84.     if (getBarState() == BARSTATE_NEWBAR){
  85.         nSSFilter_2 = nSSFilter_1;
  86.         nSSFilter_1 = nSSFilter;
  87.     }

  88.     if (getBarState() == BARSTATE_ALLBARS){
  89.         nSSFilter = 0;
  90.         nSSFilter_1 = 0;
  91.         nSSFilter_2 = 0;
  92.     }
  93.         
  94.     nSSFilter = c1 * (xZeros.getValue(0) + xZeros.getValue(-1))
  95.                     / 2 + c2 * nSSFilter_1 + c3 * nSSFilter_2;
  96.    
  97.     return nSSFilter;
  98. }

  99. function calc_RMS(Period, xSSFilter){     
  100.     if (xSSFilter.getValue(-Period) == null) return;
  101.    
  102.     var nRMS = 0;
  103.    
  104.     for (var i = 0; i < Period; i++){
  105.         nRMS += Math.pow(xSSFilter.getValue(-i), 2);
  106.     }
  107.    
  108.     nRMS = Math.sqrt(nRMS / Period);

  109.     var nRMSScaled = xSSFilter.getValue(0) / nRMS;
  110.    
  111.     return nRMSScaled;
  112. }

  113. function verify(){
  114.     var b = false;
  115.     if (getBuildNumber() < 779){
  116.         
  117.         drawTextAbsolute(5, 35, "This study requires version 10.6 or later.",
  118.             Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
  119.             null, 13, "error");
  120.         drawTextAbsolute(5, 20, "Click HERE to upgrade.@URL=http://www.esignal.com/download/default.asp",
  121.             Color.white, Color.blue, Text.RELATIVETOBOTTOM|Text.RELATIVETOLEFT|Text.BOLD|Text.LEFT,
  122.             null, 13, "upgrade");
  123.         return b;
  124.     }
  125.     else
  126.         b = true;
  127.    
  128.     return b;
  129. }
复制代码
期货论坛管理员,官方开户、量化、广告以及合作事宜,联系微信:qhltcn  QQ:116589960

TOP

WEALTH-LAB 平台策略源码: JULY 2018

he DSMA described by John Ehlers in his article in this issue, “The Deviation-Scaled Moving Average,” is an adaptive moving average that rapidly adapts to volatility in price movement. We’re going to illustrate in few easy steps how to set up a DSMA-based trading system in Wealth-Lab without coding.

Before anything else, install (or update) the TASCIndicators library from our website, Wealth-Lab.com. Figure 3 demonstrates how to choose the indicator from the library.




FIGURE 3: WEALTH-LAB. This shows how to choose DSMA as the indicator.

Although the indicator is best suited for trend-following, for kicks, let’s make our entry and exit countertrend. The idea is to buy at next open when today’s closing price has crossed a percentage below the 40-period DSMA. The opposite applies to exits but the percentage can of course be asymmetric.

  • Step 1: As groundwork, open a new rule-based strategy and drag “buy at market” and “sell at market” from the entries and exits tab.
  • Step 2: From the conditions tab, expand the general indicators group. Drag “price crosses X% below indicator” and drop it on your entry rule created in step 1. Do the same for “price crosses X% above indicator” and the exit.
  • Step 3: Notice the parameters block below your added rules. You can change rule parameters from here. Click on indicator and choose “DSMA” for both the entry and exit rules.

You also have the option to click on the icon that appears next to the indicator to expose its parameter slider. This makes it possible to change, for example, DSMA’s responsiveness by varying its lookback period. As you keep dragging the slider at the bottom-left of the screen, the changes in the trading system are executed automatically.

Figure 4 is a chart implementing the indicator with example trades.




FIGURE 4: WEALTH-LAB. This chart shows some example trades on AAPL (Apple Inc.) using the DSMA.
期货论坛管理员,官方开户、量化、广告以及合作事宜,联系微信:qhltcn  QQ:116589960

TOP

AMIBROKER平台策略源码: JULY 2018
In “The Deviation-Scaled Moving Average” in this issue, author John Ehlers presents a variable-period (adaptive) exponential moving average. The code listing shown here contains a ready-to-use formula for the DSMA. To adjust parameters for the indicator, right-click on the chart and select parameters from the context menu. A sample chart is shown in Figure 7.

TT-Amibroker.gif
2018-6-30 09:59
FIGURE 7: AMIBROKER. Here is a daily chart of the SPY with the deviation-scaled moving average (blue line), replicating the chart from John Ehlers’ article in this issue.

  1. // Deviation Scaled Moving Average (DSMA)
  2. // TASC Traders Tips July 2018
  3. Period = Param( "Period", 40, 2, 100, 1 );

  4. PI = 3.1415926;

  5. a1 = exp( -1.414 * PI / ( 0.5 * Period ) );
  6. b1 = 2 * a1 * cos( 1.414 * PI / ( 0.5 * Period ) );
  7. c2 = b1;
  8. c3 = -a1 * a1;
  9. c1 = 1 - c2 - c3;

  10. Zeros = Close - Ref( Close, -2 );

  11. // SuperSmoother Filter
  12. Filt = IIR( Zeros, c1 * 0.5, c2, c1 * 0.5, c3 );

  13. // Compute Standard Deviation
  14. RMS = Sum( Filt * Filt, Period );
  15. RMS = sqrt( RMS / Period );

  16. // Rescale Filt in terms of Standard Deviations
  17. ScaledFilt = Filt / RMS;
  18. alpha1 = abs( ScaledFilt ) * 5 / Period;

  19. DSMA = AMA( Close, alpha1 );

  20. Plot( DSMA, "DSMA"+ Period, colorBlue, styleThick );

  21. Plot( C, "Price", colorDefault, styleCandle );
复制代码
期货论坛管理员,官方开户、量化、广告以及合作事宜,联系微信:qhltcn  QQ:116589960

TOP

最后附上文章中最原始的指标源码,MC平台上面指标:(即原文中图表的指标源码!)
  1. // Deviation Scaled Moving Average (DSMA)
  2. // (c) 2013 - 2018 John F. Ehlers
  3. Inputs:
  4. Period(40);
  5. Vars:
  6. a1(0),
  7. b1(0),
  8. c1(0),
  9. c2(0),
  10. c3(0),
  11. Zeros(0),
  12. Filt(0),
  13. ScaledFilt(0),
  14. RMS(0),
  15. count(0),
  16. alpha1(0),
  17. DSMA(0);
  18. If CurrentBar = 1 Then Begin
  19. //Smooth with a Super Smoother
  20. a1 = expvalue(-1.414*3.14159 / (.5*Period));
  21. b1 = 2*a1*Cosine(1.414*180 / (.5*Period));
  22. c2 = b1;
  23. c3 = -a1*a1;
  24. c1 = 1 - c2 - c3;
  25. End;

  26. //Produce Nominal zero mean with zeros in the transfer response
  27. //at DC and Nyquist with no spectral distortion
  28. //Nominally whitens the spectrum because of 6 dB peroctave
  29. //rolloff
  30. Zeros = Close - Close[2];
  31. //SuperSmoother Filter
  32. Filt = c1*(Zeros + Zeros[1]) / 2 + c2*Filt[1] + c3*Filt[2];
  33. //Compute Standard Deviation
  34. RMS = 0;
  35. For count = 0 to Period - 1 Begin
  36. RMS = RMS + Filt[count]*Filt[count];
  37. End;
  38. RMS = SquareRoot(RMS / Period);
  39. //Rescale Filt in terms of Standard Deviations
  40. ScaledFilt = Filt / RMS;
  41. alpha1 = AbsValue(ScaledFilt)*5 / Period;
  42. DSMA = alpha1*Close + (1 - alpha1)*DSMA[1];
  43. Plot1(DSMA);
复制代码
期货论坛管理员,官方开户、量化、广告以及合作事宜,联系微信:qhltcn  QQ:116589960

TOP

thank for share

TOP

thank for share

TOP

返回列表