首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用PHP实现扇形系数的简单计算

用PHP实现扇形系数的简单计算
EN

Code Review用户
提问于 2019-05-02 18:59:57
回答 1查看 187关注 0票数 1

函数

该类扩展了名为EQ的键类,并根据详细数据进行基本计算。然后利用市场搬运者的数据(如AAPLGOOGAMZNNVDAFB)计算股票交易所市场各部门的权重系数(例如)。

它很有效,我不太确定它的OOP。

你能好心点,好好复习一下吗?

SectorCalculations

代码语言:javascript
复制
class SectorCalculations extends EQ implements ConfigConstants
{

    /**
     *
     * @var an array of sector movers
     */
    static $sector_movers;

    /**
     *
     * @var a string of current time
     */
    static $current_time;

    /**
     *
     * @var a string of current time
     */
    static $database_file_permission = 0755;

    public static function calculateSectorCoeffs()
    {
        $base_url_api = self::BASE_URL_API . self::TARGET_QUERY_API;

        $index_data = array("Overall" => array("sector_weight" => 1, "sector_coefficient" => 1, "sector_value" => 0));
        foreach (self::getSectorMovers() as $sector_mover) {
            $sector_url_api = $base_url_api . implode("%2C", array_keys($sector_mover["selected_tickers"])) . "&types=quote&range=1m";
            $raw_sector_json = file_get_contents($sector_url_api);

            if (ConfigConstants::WRITING_INDICES_SECTOR_DATA_ON_DATABASE == true) {
                self::writeIndicesOnDatabase($sector_mover["directory"], $raw_sector_json);
            }

            $raw_sector_array = json_decode($raw_sector_json, true);

            // Calculate the real-time index
            $index_value = 0;
            foreach ($raw_sector_array as $ticker => $ticker_stats) {
                if (isset($sector_mover["selected_tickers"][$ticker], $ticker_stats["quote"], $ticker_stats["quote"]["extendedChangePercent"], $ticker_stats["quote"]["changePercent"], $ticker_stats["quote"]["ytdChange"])) {

                    $change_amount = ($ticker_stats["quote"]["extendedChangePercent"] + $ticker_stats["quote"]["changePercent"] + $ticker_stats["quote"]["ytdChange"]) / 200;
                    $index_value += $sector_mover["sector_weight"] * $sector_mover["selected_tickers"][$ticker] * $change_amount;
                }
            }

            $index_data[$sector_mover["sector"]] = array("sector_weight" => $sector_mover["sector_weight"], "sector_coefficient" => $sector_mover["sector_coefficient"], "sector_value" => $index_value);
            $index_data["Overall"]["sector_value"] += $index_data[$sector_mover["sector"]]["sector_value"];
        }

        // Calculate the index factor for better visibility between -1 and +1
        $front_index_data = array();
        foreach ($index_data as $sector_name => $sector_index_data) {

            $index_sign = abs($sector_index_data["sector_value"]);
            $index_factor = 1;
            for ($i = 0; $i <= 10; $i++) {
                $index_factor = pow(10, $i);
                if (($index_factor * $index_sign) > 1) {
                    $index_factor = pow(10, $i - 1);
                    break;
                }
            }

            $front_index_data[$sector_name] = $sector_index_data["sector_weight"] * $sector_index_data["sector_coefficient"] * $sector_index_data["sector_value"] * $index_factor;
        }

        $index_sector_file = self::writeFinalJSONforSectorCoeffsOnDatabase();

        self::copyFinalSectorCoeffsToFrontDirectory();

        if (EQ::isLocalServer()) {echo "YAAAY! " . __METHOD__ . " updated sector coefficients successfully !\n";}

        return $front_index_data;
    }

    public static function copyFinalSectorCoeffsToFrontDirectory()
    {
        $sector_dir = __DIR__ . self::LIVE_DATA_DIR_APP;
        if (!is_dir($sector_dir)) {mkdir($sector_dir, self::getDatabaseFilePermission(), true);} // if data directory did not exist

        // if s-1 file did not exist
        if (!file_exists($sector_dir . self::DIR_FRONT_SECTOR_COEF_FILENAME)) {
            $handle = fopen($sector_dir . self::DIR_FRONT_SECTOR_COEF_FILENAME, "wb");
            fwrite($handle, "d");
            fclose($handle);
        }

        $sector_coef_file = $sector_dir . self::DIR_FRONT_SECTOR_COEF_FILENAME;
        copy($index_sector_file, $sector_coef_file);
    }

    public static function writeFinalJSONforSectorCoeffsOnDatabase()
    {
        // Write the index file
        $index_sector_dir = __DIR__ . self::INDEX_SECTOR_DIR_PREFIX_APP;

        if (!is_dir($index_sector_dir)) {mkdir($index_sector_dir, self::getDatabaseFilePermission(), true);}

        $index_sector_file = $index_sector_dir . self::getCurrentTime() . ConfigConstants::EXTENSION_JSON;

        $index_sector_json = json_encode($front_index_data, JSON_FORCE_OBJECT);
        $file_handle = fopen($index_sector_file, "a+");
        fwrite($file_handle, $index_sector_json);
        fclose($file_handle);

        return $index_sector_file;
    }

    public static function writeIndicesOnDatabase($sector_mover_database, $raw_sector_json)
    {

        // Write the raw file in the back directories

        $rawSectorDir = __DIR__ . self::EACH_SECTOR_DIR_PREFIX_APP . $sector_mover_database;

        // if back directory not exist
        if (!is_dir($rawSectorDir)) {mkdir($rawSectorDir, self::getDatabaseFilePermission(), true);}

        // create and open/write/close sector data to back directories
        $rawSectorFile = $rawSectorDir . ConfigConstants::SLASH . self::getCurrentTime() . ConfigConstants::EXTENSION_JSON;
        $file_handle = fopen($rawSectorFile, "a+");
        fwrite($file_handle, $raw_sector_json);
        fclose($file_handle);

    }

    /**
     * @return a part of class object
     */
    public static function getSectorMovers()
    {
        return ConfigConstants::SECTOR_MOVERS_COEFFS;
    }

    /**
     * @return a part of class object
     */
    public static function getCurrentTime()
    {
        return date("Y-m-d-H-i-s");
    }

    /**
     * @return a part of class object
     */
    public static function getDatabaseFilePermission()
    {
        return ConfigConstants::DATABASE_FILE_PERMISSION;
    }

}

json_encode($index_data)

{“总体”:{“sector_weight”:1,"sector_coefficient":1,"sector_value":0.0009989048910975919},"IT":{"sector_weight":0.18,"sector_coefficient":4,"sector_value":0.0002908602069845678},“电信”:{“sector_weight”:0.12,"sector_coefficient":4,“sector_value”:8.0557827057372e-5},“金融”:{“sector_weight”:0.1,"sector_coefficient":6,"sector_value":9.958073135395748e-5},“能源”:{“sector_weight”:0.1,"sector_coefficient":6,"sector_value":8.529905787700634e-5},“工业”:{“sector_weight”:0.08,"sector_coefficient":8,"sector_value":8.477913513820296e-5},“材料和化学品”:{“sector_weight”:0.08,"sector_coefficient":8,"sector_value":3.149808669009844e-5},“公用设施”:{“sector_weight”:0.08,"sector_coefficient":8,"sector_value":5.1996127293426994e-5},“消费酌处”:{“sector_weight”:0.08,"sector_coefficient":8,"sector_value":9.118133207158268e-5},“消费者标准”:{“sector_weight”:0.06,"sector_coefficient":8,“sector_value”:7.2644851913639e-5},“国防”:{sector_weight:0.04,"sector_coefficient":10,"sector_value":4.648512175199498e-5},“健康”:{“sector_weight”:0.04,"sector_coefficient":10,"sector_value":1.474285957230441e-5},“房地产”:{sector_weight:0.04,"sector_coefficient":10,“sector_value”:4.927955774543618e-5}

最终扇区系数

扇区系数可介于(0,1)之间:

{“总体”:0.9989048910975918,“信息技术”:0.2094193490288888,“电信”:0.38667754898753853,“金融”:0.5974843881237449,“能源”:0.5117943472620381,“工业”:0.542586464884499,“材料和化学品”:0.20158775481663005,“公用事业”:0.33277521467793275,“消费者酌处”:0.5835605252581292,“消费者酌处”:0.3486952891837267,“国防”:0.185940487007994,“健康”:0.058971438289217644,“房地产”:0.19711823098174472}

$ticker_stats样本

可以在此链接中查看引号数组:

代码语言:javascript
复制
{
  "symbol": "AAPL",
  "companyName": "Apple Inc.",
  "primaryExchange": "Nasdaq Global Select",
  "sector": "Technology",
  "calculationPrice": "tops",
  "open": 154,
  "openTime": 1506605400394,
  "close": 153.28,
  "closeTime": 1506605400394,
  "high": 154.80,
  "low": 153.25,
  "latestPrice": 158.73,
  "latestSource": "Previous close",
  "latestTime": "September 19, 2017",
  "latestUpdate": 1505779200000,
  "latestVolume": 20567140,
  "iexRealtimePrice": 158.71,
  "iexRealtimeSize": 100,
  "iexLastUpdated": 1505851198059,
  "delayedPrice": 158.71,
  "delayedPriceTime": 1505854782437,
  "extendedPrice": 159.21,
  "extendedChange": -1.68,
  "extendedChangePercent": -0.0125,
  "extendedPriceTime": 1527082200361,
  "previousClose": 158.73,
  "change": -1.67,
  "changePercent": -0.01158,
  "iexMarketPercent": 0.00948,
  "iexVolume": 82451,
  "avgTotalVolume": 29623234,
  "iexBidPrice": 153.01,
  "iexBidSize": 100,
  "iexAskPrice": 158.66,
  "iexAskSize": 100,
  "marketCap": 751627174400,
  "peRatio": 16.86,
  "week52High": 159.65,
  "week52Low": 93.63,
  "ytdChange": 0.3665,
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2019-05-02 22:38:47

我看不出有什么值得改进的小片段--很好的作品。

  • $ticker_stats["quote"],可以安全地从isset()调用中省略,因为对其子数组的后续检查将完成必要的工作。为单个isset()调用提供多个参数的良好工作。
  • 我可能能够完善以下部分,但需要实际的样本输入才能确定。($raw_sector_array as $ticker => $ticker_stats) { if (isset( $sector_mover,$ticker_stats,$ticker_stats)) { $change_amount = ($ticker_stats + $ticker_stats + $ticker_stats) / 200;$index_value += $sector_mover *$sector_mover* $change_amount;} $index_data[$sector_mover] =数组(“sector_weight”=> $sector_mover,"sector_coefficient“=> $sector_mover,"sector_value”=> $index_value);$index_data += $index_data;
  • 与其执行迭代的“猜测&检查”算术操作来确定$index_factor,我认为非迭代字符串检查应该更直接/更有效。您可以编写Barmar解决方案的实现:PHP --在十进制数中查找零数或基于regex的方法:(尽管我承认,乍一看解释起来有点困难) $float = abs($float);$factor = pow(10,preg_match_all(‘?:^0?\g(!^)0’,$float)) https://regex101.com/r/SmlRp5/3,如果上面的条件不适用于您的所有情况(如$float = 0),您可以编写一个较早的条件来快捷精确的0以不接收一个因子--但我认为这不是一个预期的情况。嗯,再想一想,使用纯算术有更大的稳定性。基于字符串的过程很容易受到涉及科学表示法的挑战。我已经将一个新的答案添加到前面提到的Barmar回答的StackOverflow页面中。
  • 为了保持一致性,可以在多行上编写所有if块。线条的减少不值得减少可读性。

一些迟来的建议..。

代码语言:javascript
复制
$index_data["Overall"]["sector_value"] += $index_data[$sector_mover["sector"]]["sector_value"];

更容易理解为:

代码语言:javascript
复制
$index_data["Overall"]["sector_value"] += $index_value;
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/219601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档