כיצד אתם ממיינים את המניות בקובץ של דייויד פיש? - או - מדריך כיצד למיין את המניות בקובץ של דייויד פיש

מומו

Well-Known Member
הצטרף
12/2/19
טוב, אז מדיי פעם אנו מקבלים קובץ אלופות מג'סטין ומאז שהקובץ הופץ "עברו הרבה מים בירדן" (=עברו הרבה דיבידנדים בתיק ההשקעות) והנתונים קצת השתנו.
לאחרונה ברכישה של GWW בתיק דיבידעת שיחס הון\חוב לפי קובץ האלופות היה 0.00, אבל לפי אתרים ברשת זה הגיע מעל 100%

הוספתי כאן קוד לסקריפט שיוכל לעזור, המטרה היא לעדכן את הנתון מהאתר Finviz.com
הקוד מניח שקובץ האלופות מתחיל בשורה 6, במידה ולא ביצעתם שינוי בקובץ האלופות והוא נשאר כפי שהורדתם אותו - לא אמורה להיות בעיה

הקוד לשימושכם, אשמח להערות\הארות

עריכה: כדי שהסקריפט יעבוד ויעדכן נתונים מאתר FInviz.com יש להגדיר את התוסף לגוגל שיט בשם Cheerio, קישור והסבר נמצא בהודעה מספר 47


קוד:
function CCC_UpdateDebtToEquity()
{
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('All CCC'), true);

  // Values is 0 Based and the sheet rows is 1 based
  var values = spreadsheet.getDataRange().getValues();
  for (var iRow = 6; iRow < values.length; iRow++)
  {
    const url = 'https://finviz.com/quote.ashx?t=' + values[iRow][1];
    const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true }).getContentText();
    const $ = Cheerio.load(res);
    var data = $('table').find('td').toArray().map(x => $(x).text());  

    if (data.indexOf("Debt/Eq") > -1 )
    {
      spreadsheet.getRange('AP' + parseInt(iRow+1)).setValue(data[ data.indexOf("Debt/Eq")+1]);  
    }

    //console.log('Row ' + parseInt(iRow+1) + ' ' + values[iRow][1] + ' = ' + data[ data.indexOf("Debt/Eq")+1] + ' Price: ' + data[ data.indexOf("Price")+1]);
  }
}
 
נערך לאחרונה ב:

SIN

Well-Known Member
הצטרף
12/12/16
מדהים מומו, תודה רבה.
בדרך להיות קובץ "נושם".

מצרף פה את הקוד שכתבת מאוחד עם מה שכתבת בתגובה #39 + הנתונים של FINVIZ (מקווה שאיחדתי נכון, אם לא מוזמן לתקן כמובן).
הוספתי סינונים נוספים ליחס החוב, יחס החלוקה, גדילה 5 שנים אחרונות + צפי גדילה 5 שנים קדימה .
ובמחילה, שיניתי את ממוצע ההגדלות 10/3/5/1 ל-5 במקום 4.

כרגע אני מקבל הודעת שגיאה בעת הרצת הפונקציה של עדכון הנתונים מ-FINVIZ -
ReferenceError: Cheerio is not defined


קוד:
/** @OnlyCurrentDoc */

function findRowByValue(sheet, value) {
  var dataRange = sheet.getDataRange();
  var values = dataRange.getValues();

  for (var i = 0; i < values.length; i++) {
    for (var j = 0; j < values[i].length; j++) {   
      if (values[i][j] == value) {
        //Logger.log(i);
        return i+1;
      }
    } 
   }
  return -1;
}

function CCC_PrepareFile() {
var spreadsheet = SpreadsheetApp.getActive();
// Duplication the All CCC
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('All CCC'), true);
spreadsheet.duplicateActiveSheet();
spreadsheet.getActiveSheet().setName('All CCC Org');
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('All CCC'), true);
// Remove bottuom lines
var iFirstRowDelete = findRowByValue(spreadsheet, "Averages for All");
var iLastRowDelete = spreadsheet.getLastRow(); 

for (var iRow = iLastRowDelete; iRow >= iFirstRowDelete; iRow--)
{
  spreadsheet.deleteRow( iRow );       
}
// Clear prices
spreadsheet.getRange('I7').activate();
var currentCell = spreadsheet.getCurrentCell();
spreadsheet.getSelection().getNextDataRange(SpreadsheetApp.Direction.DOWN).activate();
currentCell.activateAsCurrentCell();
spreadsheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
// Get prices from Google Finanace
spreadsheet.getRange('I7').activate();
spreadsheet.getCurrentCell().setFormula('=GOOGLEFINANCE(B7,"price")');
spreadsheet.getActiveRange().autoFillToNeighbor(SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);

// Add formula for 1,3,5,10 Years increment
spreadsheet.getRange('W:W').activate();
spreadsheet.getActiveSheet().insertColumnsBefore(spreadsheet.getActiveRange().getColumn(), 1);
spreadsheet.getActiveRange().offset(0, 0, spreadsheet.getActiveRange().getNumRows(), 1).activate();
spreadsheet.getRange('W6').activate();
spreadsheet.getCurrentCell().setValue('Score');
spreadsheet.getRange('W7').activate();
spreadsheet.getCurrentCell().setFormula('=J7*0.4+V7*0.3+U7*0.3+T7*0.3+S7*0.1');
spreadsheet.getActiveRange().autoFillToNeighbor(SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
}
function CCC_AddFilters()
{
var spreadsheet = SpreadsheetApp.getActive();

// Add filter with 22 Years
var iLastRow = spreadsheet.getLastRow();

var ui = SpreadsheetApp.getUi();

spreadsheet.getRange('6:' + iLastRow ).activate();
spreadsheet.getRange('6:' + iLastRow ).createFilter();


spreadsheet.getRange('E6').activate();
var criteria1 = SpreadsheetApp.newFilterCriteria()
.whenNumberGreaterThanOrEqualTo(22)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(5, criteria1);

// Add filter to MarketCap
spreadsheet.getRange('AM6').activate();
var criteria2 = SpreadsheetApp.newFilterCriteria()
.whenNumberGreaterThanOrEqualTo(1000)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(39, criteria2);
// Add filter for DGR 10 Years
spreadsheet.getRange('V6').activate();
var criteria3 = SpreadsheetApp.newFilterCriteria()
.whenNumberGreaterThanOrEqualTo(5)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(22, criteria3);
// Add filter for DGR 5 Years
spreadsheet.getRange('U6').activate();
var criteria4 = SpreadsheetApp.newFilterCriteria()
.whenNumberGreaterThanOrEqualTo(5)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(21, criteria4);

// Add filter for DGR 3 Years
spreadsheet.getRange('T6').activate();
var criteria5 = SpreadsheetApp.newFilterCriteria()
.whenNumberGreaterThanOrEqualTo(5)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(20, criteria5);


// Add filter for DGR 1 Years
spreadsheet.getRange('S6').activate();
var criteria6 = SpreadsheetApp.newFilterCriteria()
.whenNumberGreaterThanOrEqualTo(5)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(19, criteria6);

// Add filter for EPS
spreadsheet.getRange('AA6').activate();
var criteria7 = SpreadsheetApp.newFilterCriteria()
.whenNumberLessThanOrEqualTo(65)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(27, criteria7);

// Add filter for Past5yr
spreadsheet.getRange('Ak6').activate();
var criteria9 = SpreadsheetApp.newFilterCriteria()
.whenNumberGreaterThanOrEqualTo(0)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(37, criteria9);

// Add filter for Est5yr
spreadsheet.getRange('AL6').activate();
var criteria10 = SpreadsheetApp.newFilterCriteria()
.whenNumberGreaterThanOrEqualTo(0)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(38, criteria10);


function CCC_UpdateDebtToEquity()
{
  var spreadsheet = SpreadsheetApp.getActive();
  spreadsheet.setActiveSheet(spreadsheet.getSheetByName('All CCC'), true);

  // Values is 0 Based and the sheet rows is 1 based
  var values = spreadsheet.getDataRange().getValues();
  for (var iRow = 6; iRow < values.length; iRow++)
  {
    const url = 'https://finviz.com/quote.ashx?t=' + values[iRow][1];
    const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true }).getContentText();
    const $ = Cheerio.load(res);
    var data = $('table').find('td').toArray().map(x => $(x).text()); 

    if (data.indexOf("Debt/Eq") > -1 )
    {
      spreadsheet.getRange('AP' + parseInt(iRow+1)).setValue(data[ data.indexOf("Debt/Eq")+1]); 
    }

    //console.log('Row ' + parseInt(iRow+1) + ' ' + values[iRow][1] + ' = ' + data[ data.indexOf("Debt/Eq")+1] + ' Price: ' + data[ data.indexOf("Price")+1]);
  }
}

// Add filter for Debt/Eq
spreadsheet.getRange('A06').activate();
var criteria8 = SpreadsheetApp.newFilterCriteria()
.whenNumberLessThanOrEqualTo(0.7)
.build();
spreadsheet.getActiveSheet().getFilter().setColumnFilterCriteria(41, criteria8);

};
 
נערך לאחרונה ב:

daat99

מייסד
מנהל
הצטרף
22/11/15
כרגע אני מקבל הודעת שגיאה בעת הרצת הפונקציה של עדכון הנתונים מ-FINVIZ -
ReferenceError: Cheerio is not defined
תבדוק בדיוק איזה קישור אתה מנסה לדגום כשאתה מקבל את השגיאה ואז תבדוק אותו בדפדפן רגיל/אחר.

יכול להיות שאתה נתקל בחסימה נגד בוטים או שהקישור מפנה למקום לא תקין (כגון מניה שלא מתועדת בפינויז).
 

SIN

Well-Known Member
הצטרף
12/12/16
זה מתייחס לחלק הזה בקוד:

קוד:
 const url = 'https://finviz.com/quote.ashx?t=' + values[iRow][1];
    const res = UrlFetchApp.fetch(url, { muteHttpExceptions: true }).getContentText();
    const $ = Cheerio.load(res);
    var data = $('table').find('td').toArray().map(x => $(x).text());
אני רחוק מלהיות מבין גדול בזה, אבל אני חושב שנדרשת הגדרה איפשהו של ה-Cheerio.
זה לא למניה ספציפית, הוא נתקע בהרצה של הפונקציה, ומפנה לבעיה בקוד (ולא בתוצאה הסופית כדוגמת מניה שלא מקבלת פשוט נתון)
 

מומו

Well-Known Member
הצטרף
12/2/19
אולי זה יעזור:
בדיוק.
מתנצל שכחתי לציין שהתוסף Cheerio נדרש כדי לייבא את הנתונים. יש שם הסבר איך להוסיף אותו. במידה ומישהו צריך עזרה - אשמח לסייע...


יש מספר אפשרויות לבצע ייבוא נתונים לגוגלשיט (Scraping) חלקם בתשלום עם 7-30 ימי ניסיון, וחלקם בחינם כמו Cheerio
הבעיה שגם אלו שבתשלום לא עובדים ב100% וזה מאוד תלוי באתר שממנו שולפים את המידע. לצערנו באתר של Finviz יש הרבה עדכונים וכל פעם זה יכול "לשגע" את מנגנון שליפת המידע (זו הסיבה שהתייאשתי מה- ImportHtml/ImportXML מול Finviz. אין אפשרות לדעת באיזה טבלה הנתונים מופיעים)

כגון מניה שלא מתועדת בפינויז
בקוד שכתבתי יש התייחסות למקרים שאין נתון בFinviz אבל לא בטוח שזה הכי נכון לבצע. מה דעתכם האם במקרה כזה להשאיר ריק / להשאיר ללא שינוי מהמקורי / לצבוע בצבע שונה / לכתוב מלל "לא נמצא" / כל דבר אחר שתציעו?
 

daat99

מייסד
מנהל
הצטרף
22/11/15
בקוד שכתבתי יש התייחסות למקרים שאין נתון בFinviz אבל לא בטוח שזה הכי נכון לבצע. מה דעתכם האם במקרה כזה להשאיר ריק / להשאיר ללא שינוי מהמקורי / לצבוע בצבע שונה / לכתוב מלל "לא נמצא" / כל דבר אחר שתציעו?
כמו ברשימת האלופות: N/A (לא זמינים נתונים).
 

מומו

Well-Known Member
הצטרף
12/2/19
כמו ברשימת האלופות: N/A (לא זמינים נתונים).
הייתי בטוח שאתה הולך לעשות לי חיים יותר קשים ;)

במידה ולא מצאת בFinviz - חפש את הנתון בגורופוקוס
במידה ולא מצאת בגורופוקוס - אנא תואיל בטובך לחפש ביאהו פייננס
אם גם שם לא מצאת - קפוץ לסיקינג אלפא וחפש גם שם...
 

daat99

מייסד
מנהל
הצטרף
22/11/15
במידה ולא מצאת בFinviz - חפש את הנתון בגורופוקוס
במידה ולא מצאת בגורופוקוס - אנא תואיל בטובך לחפש ביאהו פייננס
אם גם שם לא מצאת - קפוץ לסיקינג אלפא וחפש גם שם...
אם תצליח תמיד להשיג את המידע הנכון מכל האתרים הללו אז יש לך מתכון לסטרטאפ מצנח.
מה תעשה כשתתקל במידע שונה באתרים הנ"ל?
לא בהכרח הרוב, ובהכרח לא אותו אחד כל הזמן!
 

lidans

New Member
הצטרף
5/1/23
שלום,

אני אציע כאן אפשרות נוספת של גוגל שיט.
עבורי יותר נוח לעבודה, גישה מכל מחשב וגם מהנייד בשילוב עם מעקב התיק שגם נמצא בגוגל שיט אז הכל מבחינתי מרוכז במקום אחד

מה שעשיתי - פתחתי גוגל שיט חדש, כתבתי בו קצת מאקרו שיקל על העבודה.
בתחילת כל חודש מבצע Import ואז Replace מקובץ האלופות לתוך הגוגל שיט. בצורה זו המאקרו נשמר.
אחרי הImport מפעיל את המאקרו שמבצע בצורה אוטומטית:
1. הוספת אפשרות סינון
2. סינון הפרמטרים הקבועים (למשל, חלוקת דיבידנד מעל 22 שנה, הגדלה ב1,3,5,10 שנים האחרונות מעל 5% וכו')
3. הוספת עמודת "ציון" לפי נוסחה שהגדרתי מראש


יש עוד אינספור אפשרויות שניתן להוסיף לדוגמה:

1. שליפת מחיר המניה המעודכן ע״י פונקציה GoogleFinance - בדרך זו כל הנתונים שתלויים במחיר משתנים בהתאם ומעודכנים. למשל המכפיל (P/E) אחוז דיבידנד וכו'
2. שליפת ממוצע אחוז דיבידנד של הS&P ואז ניתן יהיה להשתמש בו בסינון בצורה אוטומטית
3. כנ"ל גם לגבי המכפיל הממוצע של הS&P
4. הוספת עמודת צפי דיבידנד שנתי - שליפת הנתון מתיק המעקב שנמצא בגוגלשיט אחר וניתן לקשר בניהם. בדרך זו למשל ניתן לסנן את המניות עם החשיפה מעל הממוצע בתיק

בקיצור, אינסוף אפשרויות במאמץ יחסית קטן :)


אשמח לשמוע רעיונות נוספים...
אתה יכול לשתף את הגוגל שיטס?
 

מומו

Well-Known Member
הצטרף
12/2/19
גדול עלי, תודה
באיזה שלב נתקעת, אולי אוכל לעזור?
אפשר גם לשלוח בפרטי ואשמח לעזור.

תזכור שאם אתה בונה משהו בעצמך - הערך שלו יהיה הרבה יותר יקר מאשר שמישהו אחר יעשה זאת במקומך :)
 

daat99

מייסד
מנהל
הצטרף
22/11/15
גדול עלי, תודה
אם אתה מסתבך עם משהו אני ממליץ בחום לפתוח שרשור ולשאול.
הסבירות היא שמישהו יסכים לעזור לך צעד צעד בצורה שאתה תצליח להשיג את המטרה גם אם אתה חושב שלא.

אפשר גם לשלוח בפרטי ואשמח לעזור.
עדיף בשרשור ייעודי בפומבי בשביל שגם אחרים ילמדו.
 
הצטרף
14/1/23
מה אני עושה לא נכון ?
הורדתי את הקובץ מרדאר (לא מוצא את לאו המקורי...)
סיננתי את הצ'מפיונס לפי 2 פרמטרים, דיבידנד מעל 2.5% וצ'אודר מעל 12.
נשארתי עם 4 חברות בלבד כבר בשלב הזה...
 

daat99

מייסד
מנהל
הצטרף
22/11/15
אשמח ללינק ללאו המקורי האמיתי האורגינל :)
יש לינק בסרגל הימני של הבלוג.
לצערי הם מחביאים את הקישור לרישום אז תשלח מייל לכתובת שרשומה בדף ההתחברות ותשאל אותם איפה הקישור לרישום כי אתה לא מוצא אותו בדף ההתחברות.
 

moshe

Well-Known Member
הצטרף
5/1/23
יש לינק בסרגל הימני של הבלוג.
לצערי הם מחביאים את הקישור לרישום אז תשלח מייל לכתובת שרשומה בדף ההתחברות ותשאל אותם איפה הקישור לרישום כי אתה לא מוצא אותו בדף ההתחברות.
סליחה שאני מציק אבל אולי אתה תוכל לעדכן בבלוג זה הקישור להרשמה

 
למעלה תחתית