تقشير البيانات من موقع تداول بستخدام R


مهارة إستحواذ البيانات


مقدمة

احد أهم الخطوات في تحليل البيانات هي الحصول على البيانات نفسها. صعوبة هذه الخطوة يعتمد على مدى توفر البيانات المراد تحليلها.لذلك اليوم راح اشرح لك طريقة “تقشير الويب” وهي احد طرق جمع البيانات. وبالتحديد راح احاول اجمع بيانات موقع تداول عن طريق استخدام لغة R وهي اللغة المفضلة عندي لمثل هذه المهمات.

هل تقشير الويب هي الطريقة الوحيدة؟

اكيد لا , في الاسواق العالمية والأمريكية بالخصوص يمكن تحميل بيانات اداء الأسهم أو المؤشر بدون اللجوء للبرمجة. موقع جوجل على سبيل المثال عنده صفحة خاصة لعرض بيانات الاسهم الامريكية ويمكن تحميلها كملف csv او ملف اكسل. كذلك موقع ياهو يوفر نفس الخدمة. للأسف, موقع تداول لا يوفر مثل هذه الخدمة ويمكن الحصول على بيانات الأسهم او المؤشر السعودي إما بتصفح الموقع أو بشراء ترخيص للنشر. لذلك قررت ان اكتب كود يستخرج البيانات من موقع تداول لتحليلها لاحقا.

بعض الأساسيات عن الويب

لكن قبل ما نبدأ مشوارنا مع تقشير الويب, لازم نعرف بعض الاشياء المهمة عن كيفية حصول المواقع نفسها على البيانات وكيف تعرضها على صفحاتها. في معظم الاحيان كل ما يتطلب منا هو ان نكتب موقع تداول في برنامج المتصفح عندنا والموقع يحمل الصفحة مع بيانات اليوم للمؤشر او السهم. ولكن ما يحصل بالضبط هو ان المتصفح يستخدم الرابط الذي كتبناه ويحوله مع التقيد ببروتوكول نقل النص الفائق (أو ما يعرف بـ إتش تي تي بي) إلى “طلب نقل نص فائق” ويرسله إلى خادم معين يستقبل مثل هذه الطلبات. الخادم يستجيب بدوره للطلب ويرسل المعلومات المناسبة.

خلينا ناخذ مثال

إذا شعرت ان الموضوع بدأ يتعقد انا راح اعطيك مثال مع ياهو

#https://uk.finance.yahoo.com/quote/AAPL/history?period1=1511211600&period2=1513803600&interval=1d&filter=history&frequency=1d

هذا الرابط لموقع ياهو يعرض لنا أخر ٣٠ يوم من تداولات شركة آبل. لو امعنت النظر, راح تشوف ان هذا الرابط يحتوي على خمس متغيرات بالإضافة إلى رمز شركة آبل APPL الظاهر في الرابط. الأول هو period1 وقيمته 1511211600. المتغير الثاني هو period2 وقيمته 1513803600. هذان المتغيران هما من يحدد النافذة الزمنية للبيانات التي نريد جمعها. كما تلاحظ، هذه الارقام لا تشبه اي تاريخ فما الحكاية هنا. الجدير بالذكر هو ان موقع ياهو يستخدم نظام توقيت يونكس وهو ببساطة نظام يمثل الوقت والتاريخ بعدد الثواني المنقضية منذ الواحد من يناير سنة ١٩٧٠. هذه الطريقة تسهل على الكمبيوترات التعامل الوقت وإجراء العمليات الحسابية عليه. المتغير الثالث هو interval وقيمته 1d اي اعطيني البيانات بالأيام وليس بالأسابيع على سبيل المثال. المتغيران الآخيران هم filter و frequency سوف نغض النظر عنهم لأنهم غير مهمين بالنسبة لنا الآن.

الأن بإمكاننا ان نغير قيم هذه المتغيرات ونحصل على اي نوع من البيانات الي نبغاها بدون ما نتصفح موقع ياهو يدويا. خلينا نجرب نطلب بيانات تداولات سهم شركة مايكروسوفت للشهرين المنصرمين. متغيراتنا راح تكون كالتالي

  • الأول : 1508533200

  • الثاني : 1513803600

  • الثالث : لا تغيير

  • الرابع : لا تغيير

  • الخامس : لا تغيير

الرابط راح يكون بشكل كالتالي

#https://uk.finance.yahoo.com/quote/MSFT/history?period1=1508533200&period2=1513803600&interval=1d&filter=history&frequency=1d

طبعا لاحظ أننا قمنا بتغيير رمز الشركة إلى MSFT في الرابط

طلبات خلف الكواليس

ماتعلمنا إلى الآن كافي لإستخراج بيانات موقع تداول القديم. لكن تداول حدثت موقعها في ١٥ مايو ٢٠١٦ . الموقع الجديد يستخدم تقنية الأجاكس AJAX . لعلك لاحظت عند تصفحك بعض المواقع ان بعضها يعيد تحميل الصفحة بكاملها وبعضها الآخر يحدث جزء من الصفحة فقط. المواقع الي تحدث جزء من الصفحة تستخدم تقنية الأجاكس. الأجاكس بختصار هي تقنية تستخدمها بعض المواقع لتتمكن من تكوين طلبات http خلف الكواليس بدون التأثير على المحتويات الاخرى في الصفحة. في موقع تداول وصفحة اداء المؤشر على سبيل المثال, راح تلاحظ ان الصفحة تعرض اولا ثم جدول البيانات. وإذا غيرت تواريخ الأداء , يتم تحديث الجدول فقط وليس كل الصفحة. هذا ايضا يعني ان الرابط لا يتم تحديثه وبالتالي لا يمكننا الاعتماد عليه. للحصول على روابط الطلبات “الخفية” انصحك ان تستخدم فايرفوكس وتثبيت إضافة اسمها httpFox فعّل الإضافة واذهب إلى التالي

أدوات -> مطوريّ الويب -> httpfox ثم open in own window

يفترض ان تفتح لك هذه النافذة

الآن افتح موقع تداول وروح إلى صفحة المؤشر راح تشوف ان البرنامج بدأ برصد جميع الطلبات الي صارت خلف الكواليس كما هو في الصورة ادناه.

هذه الطلبات هي الي بنستخدمها لكتابة الكود. رابط تداول لبيانات شركة معينة يحتوي على ٧٠ متغير. لحسن الحظ, كل ما يمهنا هو اربع متغيرات فقط وهم رمز الشركة والفترة (من تاريخ إلى تاريخ معين) و رقم الصفحة. موقع تداول يعرض فقط ثلاثين سجل لكل طلب. لذلك نحتاج رقم الصفحة لتصفح وجمع كل البيانات الي طلبناها. لو ننسخ الطلب بدون اي تعديل راح نحصل على البيانات وحدها لكن بتنسيق غريب. هذا التنسيق هو ما يعرف بالجيسون JSON. هذا التنسيق في انتشار كبير حاليا وتستخدمه مواقع كبيرة مثل الفيسبوك والتويتر. لحسن الحظ هناك حزمة في لغة الـ R راح تساعدنا كثير في قراءة البيانات من الملفات بتنسيق الجيسون. الرابط سيكون بالشكل التالي

#https://www.tadawul.com.sa/wps/portal/tadawul/markets/equities/indices/today/!ut/p/z1/rZFNTwIxEIZ_C4cepbOwgnprTFhrViIRcO1lU7pVavqxaQuL_97CzUSXGJ3bZJ4nM28GM1xhZvlevfGonOU69S9sUo9Gt1fZdQ4llNMMyKQAunjIx8UM8HMfAEWG2a_8gs6nQBbkbj1bL5M__psP-Xmf9SLzrB84RfwKfJOhFzgeeQLghyKA78_lSI_axtjeIEDQdd1QbcxQOIPgYLQNCFrvGgQNjzx-tBKBcDZKGxF4GdzOC3khnNZSHP8eMIt8Q20jD7h6lP7VecOtkP-9RGy5j3XkQdVi530i65CGzuNqSZ4obs1qVYGi75d6X5LB4BP_kbdL/p0/IZ7_NHLCH082KGN530A68FC4AN2OM2=CZ6_22C81940L0L710A6G0IQM43GF0=N/?draw=4&columns;%5B0%5D%5Bdata%5D=date&columns;%5B0%5D%5Bname%

الرابط اطول من كذا لكن اختصرته لأعطيك فكرة فقط.

كتابة الكود

حان الوقت اننا نضع كل شي تعلمناه في كتابة الكود. أول شي راح نعمله هو كتابة دالة تأخذ المتغيرات الي ذكرناها بالإضافة إلى متغير نوع الرابط ومخرجاتها رابط يمكننا استخدامه لإستخراج بيانات المؤشر أو شركة بعينها.

parseURL <- function(p,fromDate, toDate, comSymbol = NULL , type, adjustment ="no") {
  if (type == "company") {
    firstJunk <-"https://www.tadawul.com.sa/wps/portal/tadawul/market-participants/issuers/issuers-directory/company-details/!ut/p/z1/pdDJDoIwFAXQr2HdSwFFdwgKlSHBAbUbUzUqCdMCNfr1FnVj4hDj2zU5973cEk7mhBfimO5EnZaFyOR7wVvLyAtsDyb13f5Eg9VyQnsUMQqAzG6AUttUOzoCBG1VAhcsDnUNsUb4T3mXRW1YseUlg0RSk_6Xh_4tPyR8l5Wre9V9XVddBQpqsRGnQ6aA8HWZV6I4j8_5qpRIhdoc5c974VFH7u37vmMbFD3jAT79yzN4UfwjaJrdAN6MBVLl0-n8EmzHLGVXY0T5Tw!!/p0/IZ7_NHLCH082KGET30A6DMCRNI2086=CZ6_NHLCH082KGET30A6DMCRNI2000=NJhistoricalPerformance=/?draw=2&columns%5B0%5D%5Bdata%5D=transactionDate&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=todaysOpen&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=highPrice&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=lowPrice&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=previousClosePrice&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=true&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=change&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=true&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=changePercent&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=true&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=volumeTraded&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=true&columns%5B7%5D%5Borderable%5D=true&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B8%5D%5Bdata%5D=turnOver&columns%5B8%5D%5Bname%5D=&columns%5B8%5D%5Bsearchable%5D=true&columns%5B8%5D%5Borderable%5D=true&columns%5B8%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B8%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B9%5D%5Bdata%5D=noOfTrades&columns%5B9%5D%5Bname%5D=&columns%5B9%5D%5Bsearchable%5D=true&columns%5B9%5D%5Borderable%5D=true&columns%5B9%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B9%5D%5Bsearch%5D%5Bregex%5D=false&start="
    return (
      paste(
        firstJunk,p,"&length=30&search%5Bvalue%5D=&search%5Bregex%5D=false&isNonAdjusted=0&startDate=", fromDate, "&toDate=" ,toDate,"&symbol=",comSymbol,"&_=1463986258725",sep = ""
      )
    )
  }
  if (type == "index") {
    firstJunk <- "https://www.tadawul.com.sa/wps/portal/tadawul/markets/equities/indices/today/!ut/p/z1/rZFNTwIxEIZ_C4cepbOwgnprTFhrViIRcO1lU7pVavqxaQuL_97CzUSXGJ3bZJ4nM28GM1xhZvlevfGonOU69S9sUo9Gt1fZdQ4llNMMyKQAunjIx8UM8HMfAEWG2a_8gs6nQBbkbj1bL5M__psP-Xmf9SLzrB84RfwKfJOhFzgeeQLghyKA78_lSI_axtjeIEDQdd1QbcxQOIPgYLQNCFrvGgQNjzx-tBKBcDZKGxF4GdzOC3khnNZSHP8eMIt8Q20jD7h6lP7VecOtkP-9RGy5j3XkQdVi530i65CGzuNqSZ4obs1qVYGi75d6X5LB4BP_kbdL/p0/IZ7_NHLCH082KGN530A68FC4AN2OM2=CZ6_22C81940L0L710A6G0IQM43GF0=N/?draw=25&columns%5B0%5D%5Bdata%5D=date&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=open&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=high&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=low&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=close&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=true&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=totalVolume&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=true&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=totalTurnover&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=true&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=noOfTrades&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=true&columns%5B7%5D%5Borderable%5D=true&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=desc&start="
    fromDate <- strptime(fromDate, format = "%Y-%m-%d") ; toDate <- strptime(toDate, format = "%Y-%m-%d")

    fromY <- format.Date(fromDate, "%Y") ; toY <- format.Date(toDate, "%Y")
    fromM <- format.Date(fromDate, "%m") ; toM <- format.Date(toDate, "%m")
    fromD <- format.Date(fromDate, "%d") ; toD <- format.Date(toDate, "%d")

    return (
      paste(
        firstJunk,p,"&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&sourceCallerId=datePicker&dateParameter=", fromY,"%2F",fromM,"%2F",fromD,"+-+",toY,"%2F",toM,"%2F",toD,"&typeOfCall=", ifelse(adjustment =="no",  "adjustedType","nonAdjustedType&old_tasi_current_sector=TASI"),sep = ""
      )
    )
  }

}

ممتاز!! الآن نحتاج دالة خاصة بإستخراج بيانات المؤشر وتنسيقها في إيطار بيانات. لكن قبل ما نبدأ بكتابة هذه الدالة, لازم نحّمل ونرفق حزمة الـ rjson هذه الحزمة مهم لإنها توفر دالة خاصة لقراءة تنسيق الجيسون. ضع في عين الاعتبار انك تحتاج تحمل الحزمة مرة واحدة فقط ولكنك تحتاج ترفقها لكل جلسة جديد في لغة الـ R هذه الدالة سوف تأخذ متغيرين فقط وهما بدء وانتهاء الفترة التاريخية للمؤشر. الجدير بالذكر, ان المؤشر تم إعادة هيكلته في عام ٢٠٠٨ شهر ابريل. البيانات القديمة له رابط مختلف قليلا عن البيانات الجديدة. لذلك قمت بكتابة دالة اضافية لتعديل ودمج البيانات عند الضرورة.

#install.packages("rjson")  # only if not installed already
library("rjson")
#Private FUNCTION: to get the index
privateGetIndex <-function(startDate, endDate, adjustPeriod){
  nRecords <-  fromJSON(file= parseURL(0, startDate, endDate, type = "index", adjustment = adjustPeriod))$recordsFiltered
  ifelse(nRecords <= 10, nPages <- 1, nPages <- ceiling(nRecords/10))

  fullData <- data.frame(stringsAsFactors = FALSE)
  for (i in 0:nPages ) {
    jsonData <- fromJSON(file = parseURL((i*10), startDate, endDate, type = "index", adjustment = adjustPeriod))
    p.table <- t(sapply(jsonData$data, function(x) unlist(x)))
    fullData <- rbind(fullData, as.data.frame(p.table, stringsAsFactors = FALSE))
  }
  #Formating the table
  fullData$date <- strptime(fullData$date, format = "%Y/%m/%d")
  fullData$high <- as.numeric(gsub(",","", fullData$high))
  fullData$open <- as.numeric(gsub(",","", fullData$open))
  fullData$low <- as.numeric(gsub(",","", fullData$low) )
  fullData$close <- as.numeric(gsub(",","", fullData$close))
  fullData$noOfTrades <- as.numeric(gsub(",","", fullData$noOfTrades))
  fullData$totalVolume <- as.numeric(gsub(",","", fullData$totalVolume))
  return (fullData[nRecords:1,])
}

رائع, الآن كل ما علينا هو ان نكتب دالة خاصة لإستخراج بيانات الشركات. هذه الدالة راح تأخذ متغير الفترة (البدء والإنتهاء) ورمز الشركة ومخرجاتها بيانات الشركة للفترة المحددة وتنسيقها في إيطار بيانات.

    #FUNCTION: get all records of a specified company for a specified period.
getCompanyRecords <- function (startDate, endDate, companySymbol){
      nRecords <-  fromJSON(file= parseURL(0, startDate, endDate, companySymbol, type = "company"))$recordsFiltered
      ifelse(nRecords <= 30, nPages <- 1, nPages <- ceiling(nRecords/30))

      fullData <- data.frame(stringsAsFactors = FALSE)
      for (i in 0:nPages ) {
        jsonData <- fromJSON(file = parseURL((i*30), startDate, endDate, companySymbol, type = "company"))
        p.table <- t(sapply(jsonData$data, function(x) unlist(x)))
        fullData <- rbind(fullData, as.data.frame(p.table, stringsAsFactors = FALSE))
      }

      #Formating the table
      fullData$transactionDate <- strptime(fullData$transactionDate, format = "%b %e, %Y")
      fullData$previousClosePrice <- as.numeric(fullData$previousClosePrice)
      fullData$todaysOpen <- as.numeric(fullData$todaysOpen)
      fullData$highPrice <- as.numeric(fullData$highPrice)
      fullData$lowPrice <- as.numeric(fullData$lowPrice)
      fullData$volumeTraded <- as.numeric(fullData$volumeTraded)
      fullData$turnOver <- as.numeric(fullData$turnOver)
      fullData$noOfTrades <- as.numeric(fullData$noOfTrades)
      fullData$lastTradePrice <- as.numeric(fullData$lastTradePrice)
      fullData$change <- as.numeric(fullData$change)
      fullData$changePercent <- as.numeric(fullData$changePercent)

      return (fullData[nRecords:1,])
    }

ممتاز، بما أننا كتبنا دالة لإستخراج بيانات الشركات ، الا يجدر بنا ايضا كتابة دالة متخصص لإستخراج بيانات المؤشر السعودي. الكود سيكون كالتالي

#FUNCTION: get all records of TASI for a specified period.
getIndexRecords <- function(fromDate, toDate){

  cutoffDate <- strptime("2008-04-02"  , format = "%Y-%m-%d")
  stY<-strptime(fromDate, format = "%Y-%m-%d")
  endY<-strptime(toDate, format = "%Y-%m-%d")

  if(stY<=cutoffDate & endY <= cutoffDate) {
    period <- "AllBeforeRestructure"
    return(privateGetIndex(startDate = fromDate, endDate = toDate, adjustPeriod = "yes"))
  }
  if((stY<=cutoffDate & endY >cutoffDate)){
    period <- "Combination"
    oldPart<- privateGetIndex(startDate = fromDate, endDate = "2008-04-02", adjustPeriod = "yes")
    newPart<- privateGetIndex(startDate = "2008-04-05", endDate = toDate, adjustPeriod = "no")
    oldPart$close * 0.9801111;
    return(rbind(oldPart,newPart)); }
  if((stY >cutoffDate)){
    period <- "NewIndex"
    return(privateGetIndex(startDate = fromDate, endDate = toDate, adjustPeriod = "no"))
  }
}

تجربة و أختبار الكود (مبايعة الأمير محمد بن سلمان وليا للعهد)

إلى هنا, عملنا انتهى مع كتابة الكود. الأن احنا جاهزين لإختبار الكود والإجابة عن بعض التساؤلات حول السوق. خلينا نحاول نستخرج البيانات الخاصة بالمؤشر خلال هذه السنة المليئة بالأحداث. الهدف من استخراج هذه البيانات هو عرض ما حدث في شهر يونيو ٢٠١٧ عندما تم مبايعة الأمير محمد بن سلمان وليا للعهد من خلال رسم بياني. لاحظ ان الكود قد يستغرق بعض الوقت. لذلك انصحك ترتاح و تحتسي لك كوب من الشاهي وتروّق. بعد ما يخلص الكود, راح يكون عندنا كل البيانات محفوظة في المتغير TASI . لتتأكد اننا حصلنا على البيانات المطلوبة خلينا نشغل هذا الكود

    TASI <- getIndexRecords("2017-01-01", "2017-12-01")
    head(TASI)
##           date    high    open     low   close totalVolume
## 229 2017-01-01 7250.19 7210.43 7207.65 7237.95   255953012
## 228 2017-01-02 7290.33 7237.95 7224.77 7247.34   312748197
## 227 2017-01-03 7260.37 7247.34 7209.51 7250.76   284702000
## 226 2017-01-04 7254.61 7250.76 7182.79 7198.11   253856191
## 225 2017-01-05 7224.50 7198.11 7176.32 7198.73   230974499
## 224 2017-01-08 7212.04 7198.73 7130.25 7138.86   197940300
##        totalTurnover noOfTrades
## 229 4,460,586,641.65     113416
## 228 5,841,410,563.75     147723
## 227 5,151,905,839.90     132104
## 226 5,031,016,273.05     138147
## 225 4,460,386,480.90     120440
## 224 3,900,807,491.20     106546

ممتاز, يبدو ان كل شي تمام. الآن راح نعمل رسم بياني ونأخذ فكرة عن ردة فعل السوق تجاه الخبر.

at.tick <- format(TASI$date, "%d") %in% c("15")
maxV<-dim(TASI)[1]
plot(x=as.Date(TASI$date), y=TASI$close, type = "l", xaxt="n", xlab = "Time", ylab = "Index")
axis(side = 1, at = as.Date(TASI$date[at.tick]), labels = format(TASI$date[at.tick], "%b-%y"))
text(x=as.Date("2017-08-25"), y =7480 , labels = "Market Jump", cex = 1)

الإرتفاع واضح تمام حيث ان الموشر وصل إلى ما فوق الـ ٧٤٠٠ نقطة بعد ما كان ما دون ٦٧٠٠ نقطة. وبذلك نختم موضوعنا اليوم واتمنى انك استمتعت بقراءته. ولكن الأهم هو انك تعلمت ولو القليل عن طريقة تقشير الويب. لا تتردد بنسخ الكود وتجريب أو حتى تطويره كما تشاء. إذا عندك اي ملاحظات او اقتراحات ارجو انك ترسلها عبر قسم التعليقات و شكراً


جرب بنفسك

كامل الكود تجده هنا

comments powered by Disqus