Traducir de mq4 a PRT:"PAMA GannGrid"

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #101251 quote
    Fr7
    Participant
    Master

    Hola Nicolás ,le traigo un nuevo indicador.:”PAMA GannGrid”…….A ver si es tan amable de traducirlo a Prorealtime.Gracias

    //+------------------------------------------------------------------+
    //|                                        PAMA GannGrid_indv4.3.mq4 |
    //|                                                                  |
    //+------------------------------------------------------------------+
    #property copyright "Copyright © 2010.01.24, SwingMan"
    #property link      ""
    /*+------------------------------------------------------------------+
       v 4.1  draw trading lines
       v 4.3  text shift for values  
    //+-----------------------------------------------------------------*/
    string sIndicatorName = "PAMA GannGrid_indv4.3";
    
    //---- window
    bool Draw_InMainWindow = true; //set this parameter!
    //#property indicator_separate_window
    #property indicator_chart_window
    
    #property indicator_buffers 8
    
    #property indicator_color1 DodgerBlue //price line
    #property indicator_color2 DodgerBlue //price dots
    #property indicator_color3 Silver     //max,min; identical with MainGrid_Color
    #property indicator_color4 Silver
    #property indicator_color5 Green  //up arrow
    #property indicator_color6 Green  //up line
    #property indicator_color7 Red   //dn arrow
    #property indicator_color8 Red   //dn line
    
    #property indicator_width1 1 //price line
    #property indicator_width2 1 //price dots
    #property indicator_width3 1 //max,min; identical with MainGrid_Color
    #property indicator_width4 1 //
    #property indicator_width5 2 //up arrow
    #property indicator_width6 2 //up line
    #property indicator_width7 2 //dn arrow
    #property indicator_width8 2 //dn line
    
    #property indicator_style3 STYLE_SOLID
    #property indicator_style4 STYLE_SOLID
    
    //---- extern inputs
    //+------------------------------------------------------------------+
    extern string ____GridBegin____ = "";
    extern bool UseBeginDate = false;
    //extern string BeginDate = "2010.01.21";
    //extern string BeginDate = "2009.11.01";
    extern string BeginDate = "2010.01.01 00:00";
    extern int nBarsBack = 120;//250;
    extern string prices = "0=close, 4=median, 5=typical";
    extern int Price_Mode = 5;
    //-- oscillator (Draw_InMainWindow = false)
    //extern bool Show_GridMatrix = true;
    //extern bool Show_GannGrid = true;
    //-- indicator (Draw_InMainWindow = true)
    extern bool Show_GridMatrix = false;
    extern bool Show_GannGrid = false;
    extern bool Show_HiloArrows = true;
    extern bool Show_PriceArrows = false;
    extern bool Show_Comments = false;
    extern string ____MainGrid____ = "";
    extern color MainGrid_Color = Silver;//Green;//Sienna;
    extern int MainGrid_Style = STYLE_DOT;
    extern int MinMaxGrid_Style = STYLE_SOLID;
    extern int MainGrid_Width = 1;
    extern int fontSize = 8;
    extern bool Draw_AllGrids = false;
    extern bool Draw_AdditionalGrids = false;
    extern string ____GannGrid____ = "";
    extern color GannGrid_Color = Silver;//Gray;
    //---- if (Draw_InMainWindow == true) 
    extern int GannGrid_Style = STYLE_DOT;
    //---- if (Draw_InMainWindow == false) 
    //extern int GannGrid_Style = STYLE_SOLID;
    extern int GannGrid_Width = 1;
    extern string ____Default_GridParameters____ = "Recomanded GridInterval 35 or 36";
    extern int MainGrid_Intervals = 36;   //default=35(!)
    extern double GannGrid_Interval = 8.0;//with default 8.5 is the time interval not OK; and 9 is too large
    extern int Text_Shift = 50;
    //+------------------------------------------------------------------+
    
    //---- default input parameters
    //string ____DefaultGridInterval____ = "";
    //int MainGrid_Intervals = 36;   //default=35(!)
    //double GannGrid_Interval = 8.0;//with default 8.5 is the time interval not OK; and 9 is too large
    
    //---- buffers
    double price[], dotPrice[];
    double MaxPriceLine[], MinPriceLine[];
    double upArrow[], upLine[], dnArrow[], dnLine[];
    
    //---- variables
    int iWindow;
    string sWindowName;
    datetime firstTime, thisTime, oldTime;
    bool bGridOK = false;
    int nMainGrid_Intervals;
    int iGannGrid_Interval, iHalfInterval;
    datetime maxPriceTime, minPriceTime;
    double maxPrice, minPrice, gridStep;
    bool UseBeginDateOriginal;
    int nDigits;
    
    //####################################################################
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function                         |
    //+------------------------------------------------------------------+
    int init()
    {  
    //---- indicators
       SetIndexBuffer(0,price);    SetIndexStyle(0,DRAW_LINE); 
          SetIndexLabel(0,"PAMA Price");
       SetIndexBuffer(1,dotPrice); SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,159); 
          SetIndexLabel(1,NULL);
       SetIndexBuffer(2,MaxPriceLine);   SetIndexStyle(2,DRAW_LINE,MinMaxGrid_Style,MainGrid_Width,MainGrid_Color); 
          SetIndexLabel(2,"maxPrice");
       SetIndexBuffer(3,MinPriceLine);   SetIndexStyle(3,DRAW_LINE,MinMaxGrid_Style,MainGrid_Width,MainGrid_Color); 
          SetIndexLabel(3,"minPrice");      
       SetIndexBuffer(4,upArrow); SetIndexStyle(4,DRAW_ARROW); SetIndexArrow(4,241); 
          SetIndexLabel(4,NULL);      
       SetIndexBuffer(5,upLine);  SetIndexStyle(5,DRAW_LINE); 
          SetIndexLabel(5,"upLine");      
       SetIndexBuffer(6,dnArrow); SetIndexStyle(6,DRAW_ARROW); SetIndexArrow(6,242); 
          SetIndexLabel(6,NULL);
       SetIndexBuffer(7,dnLine);  SetIndexStyle(7,DRAW_LINE); 
          SetIndexLabel(7,"dnLine");
    //----
       SetIndexEmptyValue(7,EMPTY_VALUE);
    //----
       string sName = sIndicatorName + "  ";
       if (Price_Mode == 0) string sPrice = "(ClosePrices) "; else
       if (Price_Mode == 4) sPrice = "(MedianPrices) "; else
       if (Price_Mode == 5) sPrice = "(TypicalPrices) "; 
       sWindowName = sName+sPrice;
       IndicatorShortName(sWindowName);
       IndicatorDigits(Digits);
    //---- initialisations
       if (UseBeginDate == true)
       {
          firstTime = StrToTime(BeginDate + " 00:00");
          nBarsBack = 0;
       }
       else
          firstTime = 0;
       nMainGrid_Intervals = MainGrid_Intervals;
       iGannGrid_Interval  = GannGrid_Interval;
       iHalfInterval       = iGannGrid_Interval / 2;   
       UseBeginDateOriginal = UseBeginDate;
       bGridOK = false;
       nDigits = MarketInfo(Symbol(),MODE_DIGITS);
       if (nDigits == 5 || nDigits == 3) nDigits--;
       //---- window
       if (Draw_InMainWindow)   
            iWindow = 0;   
       else iWindow = WindowFind(sWindowName);
    //----
       return(0);
    }
    
    //+------------------------------------------------------------------+
    //| Custom indicator deinitialization function                       |
    //+------------------------------------------------------------------+
    int deinit()
    {  
       Delete_GannObjects();
       if (Show_Comments) Comment("");
       for (int i=0; i<nBarsBack+20; i++)
       {
          upArrow[i] = EMPTY_VALUE;
          dnArrow[i] = EMPTY_VALUE;
          upLine[i]  = EMPTY_VALUE;
          dnLine[i]  = EMPTY_VALUE;
          MaxPriceLine[i] = EMPTY_VALUE;
          MinPriceLine[i] = EMPTY_VALUE;
       }
    //----
       return(0);
    }
    
    
    //####################################################################
    //+------------------------------------------------------------------+
    //| Custom indicator iteration function                              |
    //+------------------------------------------------------------------+
    int start()
    {
    //datetime testTime1=TimeCurrent();
    
    double dPrice;
       if (Draw_InMainWindow==false)
          if (iWindow < 1) iWindow = WindowFind(sWindowName);
    
       int counted_bars=IndicatorCounted();
       if(counted_bars<0) return(-1);
       if(counted_bars>0) counted_bars--;   
       int limit = Bars-counted_bars;      
    
       //---- check newBar
       thisTime = Time[0]; 
       if (thisTime != oldTime) 
       {
          oldTime = thisTime;
          Delete_GannObjects();
          if ( (UseBeginDate == false && firstTime != 0) || //-- nBarsBack after first calculation
               (UseBeginDate == true  && limit < 4) )       //-- Date after first calculation
          {
             nBarsBack = 0;
             bGridOK = false;
             UseBeginDate = true; //firstTime is now allowable for nBarsBack
             int thisBarShift = iBarShift(Symbol(),Period(),firstTime,false);
             limit = thisBarShift;         
          }
       }
       
       //---- first min,max prices   
       if (bGridOK == false)
       {   
          dPrice = CurrentPrice(Price_Mode, 0);      
          maxPrice = dPrice; maxPriceTime = Time[0];
          minPrice = dPrice; minPriceTime = Time[0];
       }
    
       
       //---- draw prices, caculate min,max prices
       //================================================================
       for(int i=0; i<limit; i++)   
       {
          dPrice = CurrentPrice(Price_Mode, i);
          price[i] = dPrice;
          dotPrice[i]  = dPrice;
    
          if (bGridOK == false)
          {
             //---- use fix date as begin
             if (UseBeginDate == true)
             {
                if (Time[i] > firstTime)
                {
                   if (dPrice > maxPrice) {maxPrice = dPrice; maxPriceTime = Time[i];}
                   if (dPrice < minPrice) {minPrice = dPrice; minPriceTime = Time[i];}
                   nBarsBack++;
                }
             }
             else
             //---- use nBarsBack as begin
             if (UseBeginDate == false)
             {
                if (i < nBarsBack)
                {
                   if (dPrice > maxPrice) {maxPrice = dPrice; maxPriceTime = Time[i];}
                   if (dPrice < minPrice) {minPrice = dPrice; minPriceTime = Time[i];}
                   firstTime = Time[i];
                }         
             }         
          }
       }
       
       //---- calculate data for MainGrid
       if (bGridOK == false)
       {
          double diffMinMax = maxPrice - minPrice;
          gridStep = NormalizeDouble(diffMinMax / nMainGrid_Intervals,Digits);
       }
       
       //---- dummy lines for uper and lower prices
       for(i=0; i<limit; i++)   
       {
          MaxPriceLine[i] = maxPrice;// + iHalfInterval *gridStep;
          MinPriceLine[i] = minPrice;// - iHalfInterval *gridStep;
          Write_PriceValue(maxPrice);
          Write_PriceValue(minPrice);
       }
    
       //-- adjust nBarsBack
       if (UseBeginDate == true)
          nBarsBack++;
          
    //---- draw matrix and GannGrid
    //===================================================================
       if (bGridOK == false)
       {
       
    //---- write matrix data
    string st;   
    st = st + "** " + sIndicatorName + " ** " + "\n";
    if (UseBeginDateOriginal) string sBegin = "  (Date)"; else sBegin = "  (nBars)";
    st = st + "GridBegin: " + TimeToStr(firstTime,TIME_DATE|TIME_MINUTES) + sBegin + "\n";
    st = st + "nBarsBack= " + nBarsBack + "\n";
    string sMaxPriceTime = "  (" + TimeToStr(maxPriceTime) + ")";
    string sMinPriceTime = "  (" + TimeToStr(minPriceTime) + ")";
    st = st + "maxPrice= " + DoubleToStr(maxPrice,Digits) + sMaxPriceTime + "\n";
    st = st + "minPrice= " + DoubleToStr(minPrice,Digits) + sMinPriceTime + "\n";
    double percent = 100.0 *( maxPrice - minPrice) / minPrice;
    double gridPerc= percent / nMainGrid_Intervals;
    string sGridPercent = " ( " + DoubleToStr(gridPerc,2) + " % )";
    st = st + "Percent= " + DoubleToStr(percent,2) + " %\n";
    st = st + "GridStep= " + DoubleToStr(gridStep,Digits) + sGridPercent + "\n";
    string sGridStep = " (" + iHalfInterval + " GridSteps)";
    st = st + "mainStep= " + DoubleToStr(gridStep*iHalfInterval,Digits) + sGridStep + "\n";
    if (Show_Comments)
       Comment(st);   
    
    //---- draw horizontal lines  (35+1=36 HLines) ----------------------
          if (MainGrid_Intervals == 36) 
               int nMainGrids = nMainGrid_Intervals;      
          else nMainGrids = nMainGrid_Intervals+1; //nMainGrid_Intervals+1 for 35
          
          if (Show_GridMatrix == true)
          for (i=1; i<nMainGrids; i++) 
          {  
             if (Draw_AllGrids == true)
                Draw_HorizontalLine(maxPrice - i*gridStep);
             else 
             {           
                if (MathMod(i,iHalfInterval) == 0)
                   Draw_HorizontalLine(maxPrice - i*gridStep);
             }
             //---- write price values
             if (MathMod(i,iHalfInterval) == 0)
                Write_PriceValue(maxPrice - i*gridStep);
          }
    
          //-- additional grids
          if (Show_GridMatrix == true)
          if (Draw_AdditionalGrids)
          {
             for (int k=1; k<=iHalfInterval; k++)
                Draw_HorizontalLine(maxPrice+k*gridStep);         
             for (k=1; k<=iHalfInterval; k++) //k=2 for 35
                Draw_HorizontalLine(minPrice-k*gridStep);      
          }
          
    //---- draw vertical lines ------------------------------------------
          if (Show_GridMatrix == true)
          for (i=0; i<nBarsBack; i++)
          {
             if (Draw_AllGrids == true)
                int j = i;
             else   
                j = (nBarsBack-1) - i * iHalfInterval;         
                   
             if (j>0)
                datetime dTime = Time[j];
             else
                dTime = Time[0];   
             Draw_VerticalLine(dTime,minPrice,maxPrice);//minPrice-gridStep for 35
          }
          
    //---- draw trading lines -------------------------------------------
          Draw_TradingLines();
                
    //==== draw GannGrid lines (angle 45°) ==============================
          if (Show_GannGrid)
          {
             datetime time1 = Time[nBarsBack-1];
             datetime time2 = Time[nBarsBack-iHalfInterval-1];
             double price1 = maxPrice;      
             double price2 = maxPrice - iHalfInterval*gridStep;
             Draw_GannGrid(time1,time2, price1,price2);
          }
       }   
    //----
       bGridOK = true;
    //datetime testTime2=TimeCurrent();
    //if (Symbol() == "EURUSD" && Period() == PERIOD_M5)
    //   Print("### ",TimeToStr(testTime2 - testTime1,TIME_MINUTES|TIME_SECONDS));   
       return(0);
    }
    //+------------------------------------------------------------------+
    
    //___________________________________________________________________
    void Draw_TradingLines()
    {
    //int xStep=0;
    //      xStep++;
    int iTrend;
    double lineValue;
    
       int iFirstBar = nBarsBack-1;
       double firstPriceValue = price[iFirstBar];
       double diffBegin = price[iFirstBar] - price[iFirstBar+1];
       
       //---- first value -----------------------------------------------
       //---- high at begin
       if (diffBegin >= 0)
       {
          iTrend =  1;
          lineValue = firstPriceValue - iGannGrid_Interval*gridStep;
          Set_UpLineValue(iFirstBar, lineValue);
       }  
       else 
       //---- low at begin
       {
          iTrend = -1;
          lineValue = firstPriceValue + iGannGrid_Interval*gridStep;
          Set_DnLineValue(iFirstBar, lineValue);
       }
       
       //---- main loop
       //================================================================
       for (int i=nBarsBack-2; i>=0; i--)
       {
          //---- up trend (blue line) -----------------------------------
          if (iTrend == 1)
          {
             //---- translate up linie
             if (price[i] - iGannGrid_Interval*gridStep > lineValue + gridStep)
                  lineValue = price[i] - iGannGrid_Interval*gridStep;
             else lineValue = lineValue + gridStep;
             Set_UpLineValue(i, lineValue);
             //---- reverse from up-trend / down-trend
             if (price[i] < lineValue)
             {
                iTrend = -1;
                lineValue = price[i] + iGannGrid_Interval*gridStep;
                Set_DnLineValue(i, lineValue);
                if (Show_PriceArrows)
                   dnArrow[i] = price[i];            
                if (Show_HiloArrows)
                   Show_SignalArrows(i, iTrend);
             }
          }
          else
          
          //---- down trend (red line) ----------------------------------
          if (iTrend == -1)
          {
             //---- translate down linie
             if (price[i] + iGannGrid_Interval*gridStep < lineValue - gridStep)
                  lineValue = price[i] + iGannGrid_Interval*gridStep;
             else lineValue = lineValue - gridStep;
             Set_DnLineValue(i, lineValue);
             //---- reverse from down-trend / up-trend
             if (price[i] > lineValue)
             {
                iTrend = 1;
                lineValue = price[i] - iGannGrid_Interval*gridStep;
                Set_UpLineValue(i, lineValue);            
                if (Show_PriceArrows)
                   upArrow[i] = price[i];
                if (Show_HiloArrows)            
                   Show_SignalArrows(i, iTrend);
             }
          }
       }
       return;
    }
    
    //___________________________________________________________________
    void Set_UpLineValue(int iBar, double dValue)
    {
       if (dValue >= MinPriceLine[iBar]-gridStep && 
           dValue <= MaxPriceLine[iBar]+gridStep) 
       {    
          upLine[iBar] = dValue;
       }
       else 
          upLine[iBar] = EMPTY_VALUE;
       return;
    }
    
    //___________________________________________________________________
    void Set_DnLineValue(int iBar, double dValue)
    {
       if (dValue >= MinPriceLine[iBar]-gridStep && 
           dValue <= MaxPriceLine[iBar]+gridStep) 
       {    
          dnLine[iBar] = dValue;
       }     
       else 
          dnLine[iBar] = EMPTY_VALUE;
       return;
    }
    
    //___________________________________________________________________
    void Show_SignalArrows(int i, int iTrend)
    {
    int iArrow;
    color dColor;
    double dATR, dHighOffset, dLowOffset, dPrice;
    double dFactorOffset  = 0.40;
    int iHeight = 2;
    
       string sName = "Signal_" + TimeToStr(Time[i]);
       
       dATR = iATR(Symbol(),Period(),34,i);
       double dHiloOffset = dATR * dFactorOffset;
       
    //I use a value based on the current height of the window...?
       double dHeightWindow = WindowPriceMax(0) - WindowPriceMin(0);
       dLowOffset  = dHeightWindow / 100;
       dHighOffset = dLowOffset + 2*dHiloOffset;   
    
       //---- long signal
       if (iTrend == 1)
       {
          iArrow = 233;   
          dColor = Blue;
          dPrice = Low[i] - dLowOffset;
       }
       else
       //---- short signal
       if (iTrend == -1)
       {
          iArrow = 234;
          dColor = Red;
          dPrice = High[i] + dHighOffset;
       }
       dPrice = NormalizeDouble(dPrice,Digits);
    
       ObjectCreate(sName,OBJ_ARROW,0,Time[i],dPrice);
          ObjectSet(sName,OBJPROP_COLOR,dColor);
          ObjectSet(sName,OBJPROP_ARROWCODE,iArrow);
       return;
    }
    
    //___________________________________________________________________
    double CurrentPrice(int priceCode, int i)
    {
    double dPrice;
    
       switch (priceCode)
       {
          case PRICE_CLOSE: 
          {
             dPrice = Close[i];
             break;
          }
          case PRICE_OPEN: 
          {
             dPrice = Open[i];
             break;
          }
          case PRICE_MEDIAN: 
          {
             dPrice = (High[i] + Low[i]) / 2.0;
             dPrice = NormalizeDouble(dPrice,Digits);
             break;
          }
          case PRICE_TYPICAL: 
          {
             dPrice = (High[i] + Low[i] + Close[i]) / 3.0;
             dPrice = NormalizeDouble(dPrice,Digits);
             break;
          }
       }
       return(dPrice);
    }
    
    //___________________________________________________________________
    void Draw_HorizontalLine(double dValue)
    {
       dValue = NormalizeDouble(dValue,Digits);
       string sName = "HLine_" + DoubleToStr(dValue,Digits);
       ObjectCreate(sName,OBJ_TREND,iWindow, firstTime,dValue, Time[0],dValue);
          ObjectSet(sName,OBJPROP_COLOR,MainGrid_Color);
          ObjectSet(sName,OBJPROP_STYLE,MainGrid_Style);
          ObjectSet(sName,OBJPROP_WIDTH,MainGrid_Width);
          ObjectSet(sName,OBJPROP_RAY,false);
          ObjectSet(sName,OBJPROP_BACK,false); //drawn in foreground
       return;   
    }
    
    //___________________________________________________________________
    void Draw_VerticalLine(datetime dTime, double minVal, double maxVal)
    {
       string sName = "VLine_" + TimeToStr(dTime);
       ObjectCreate(sName,OBJ_TREND,iWindow, dTime,minVal, dTime,maxVal);
          ObjectSet(sName,OBJPROP_COLOR,MainGrid_Color);
          ObjectSet(sName,OBJPROP_STYLE,MainGrid_Style);
          ObjectSet(sName,OBJPROP_WIDTH,MainGrid_Width);
          ObjectSet(sName,OBJPROP_RAY,false);
          ObjectSet(sName,OBJPROP_BACK,false); //drawn in foreground
       return;   
    }
    
    //___________________________________________________________________
    void Draw_GannGrid(datetime time1, datetime time2, double dValue1, double dValue2)
    {
       string sName = "Gann_" + dValue1;
       double dScale = -gridStep * MathPow(10,Digits);
       ObjectCreate(sName,OBJ_GANNGRID,iWindow, time1,dValue1, time2,dValue2);
          ObjectSet(sName,OBJPROP_COLOR,GannGrid_Color);
          ObjectSet(sName,OBJPROP_STYLE,GannGrid_Style);
          ObjectSet(sName,OBJPROP_WIDTH,GannGrid_Width);
          ObjectSet(sName,OBJPROP_RAY,true);
          ObjectSet(sName,OBJPROP_SCALE,dScale);
          ObjectSet(sName,OBJPROP_BACK,true); //drawn in background
       return;
    }
    
    //___________________________________________________________________
    void Write_PriceValue(double dValue)
    {
       string sTextShift;
       for (int i=1; i<= Text_Shift; i++)
          sTextShift = sTextShift + " ";
       string sValue = DoubleToStr(dValue,Digits);
       string sName = "Price_" + sValue;
       sValue = sTextShift + sValue;
       ObjectCreate(sName,OBJ_TEXT,iWindow, Time[0],dValue);
          ObjectSetText(sName,sValue,fontSize);
       return;
    }
    
    //####################################################################
    //____________________________________________________________________
    void Delete_GannObjects()
    {
       Delete_ObjectNames("Gann_");
       Delete_ObjectNames("HLine_");
       Delete_ObjectNames("VLine_");
       Delete_ObjectNames("Price_");
       Delete_ObjectNames("Signal_");
    }
    //____________________________________________________________________
    void Delete_ObjectNames(string sName)
    {
       int nObjects = ObjectsTotal();
       for (int i=nObjects; i>=0; i--)
       {
          string sObjectName = ObjectName(i);
          if (StringFind(sObjectName, sName, 0) != -1)
          {
             ObjectDelete(sObjectName);
          }   
       }
    }
    
    
    #101280 quote
    Nicolas
    Keymaster
    Master

    Aparte de las dificultades para codificar el indicador :), creo que se vuelve a pintar porque la cuadrícula se calcula con el máximo y mínimo de todos los tiempos y se adapta en tiempo real, para que siempre obtenga una precisión perfecta del pasado. ¿Ya lo has usado con éxito? (y en tiempo real?).

    #101345 quote
    Fr7
    Participant
    Master

    La verdad que no lo he probado ni testeado este indicador…..pero si finalmente repinta no es interesante la traducción.Gracias y disculpe las molestias.

Viewing 3 posts - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.

Traducir de mq4 a PRT:"PAMA GannGrid"


Soporte ProBuilder

New Reply
Author
author-avatar
Fr7 @fr7 Participant
Summary

This topic contains 2 replies,
has 2 voices, and was last updated by Fr7
6 years, 7 months ago.

Topic Details
Forum: Soporte ProBuilder
Language: Spanish
Started: 06/23/2019
Status: Active
Attachments: 2 files
Logo Logo
Loading...