Plugin Directory

Changeset 3205179


Ignore:
Timestamp:
12/10/2024 12:45:48 AM (15 months ago)
Author:
laith3
Message:

Cleaned up and updated trunk for version 1.0.7.

Location:
tradejournal/trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • tradejournal/trunk/includes/csv-import.php

    r3185259 r3205179  
    8080            $side = isset($trade['market pos.']) ? strtolower($trade['market pos.']) : '';
    8181
    82             // Set instrument multiplier based on the instrument
    83             $multiplier = 1;
    84             if (strpos($instrument, 'MES') === 0) {
    85                 $multiplier = 5; // Micro E-mini S&P 500
    86             } elseif (strpos($instrument, 'ES') === 0) {
    87                 $multiplier = 50; // E-mini S&P 500
     82            // Retrieve instrument settings from plugin options
     83            $multipliers_and_commissions = get_option('tradejournal_instrument_multipliers', []);
     84
     85            // Default to empty array if settings are not found
     86            if (empty($multipliers_and_commissions)) {
     87                $multipliers_and_commissions = [
     88                    'ES' => ['multiplier' => 50, 'commission' => 5],
     89                    'MES' => ['multiplier' => 5, 'commission' => 0.5],
     90                ];
    8891            }
    8992
    90             // Calculate P&L based on side and multiplier
     93            // Set instrument multiplier and commission dynamically
     94            $multiplier = 1; // Default multiplier
     95            $commission = 0; // Default commission
     96
     97            foreach ($multipliers_and_commissions as $key => $values) {
     98                if (strpos($instrument, $key) === 0) {
     99                    $multiplier = $values['multiplier'];
     100                    $commission = $values['commission'];
     101                    break;
     102                }
     103            }
     104
     105            // Calculate P&L based on side, multiplier, and subtract commission
    91106            $pnl = 0;
    92107            if ($entry_price && $exit_price) {
    93                 if ($side == 'long') {
     108                if ($side === 'long') {
    94109                    $pnl = ($exit_price - $entry_price) * $qty * $multiplier;
    95                 } elseif ($side == 'short') {
     110                } elseif ($side === 'short') {
    96111                    $pnl = ($entry_price - $exit_price) * $qty * $multiplier;
    97112                }
     113                // Subtract commission
     114                $pnl -= $commission;
    98115                $pnl = number_format($pnl, 2);
    99116            }
  • tradejournal/trunk/includes/meta-box.php

    r3185259 r3205179  
    4545    $account = isset($trade['Account']) ? esc_attr($trade['Account']) : '';
    4646    $entry_time = isset($trade['Entry Time']) ? esc_attr($trade['Entry Time']) : '';
     47    $entry_price = isset($trade['Entry Price']) ? esc_attr($trade['Entry Price']) : '';
     48    $exit_price = isset($trade['Exit Price']) ? esc_attr($trade['Exit Price']) : '';
    4749    $qty = isset($trade['Qty']) ? esc_attr($trade['Qty']) : '';
    4850    $pnl = isset($trade['P&L']) ? esc_attr($trade['P&L']) : '';
     
    6567                <label><?php esc_html_e('Entry Time:', 'tradejournal'); ?> <input type="text" name="trades[<?php echo esc_attr($index); ?>][Entry Time]" value="<?php echo esc_attr($entry_time); ?>" /></label>
    6668                <label><?php esc_html_e('Qty:', 'tradejournal'); ?> <input type="number" name="trades[<?php echo esc_attr($index); ?>][Qty]" value="<?php echo esc_attr($qty); ?>" /></label>
     69                <label><?php esc_html_e('Entry Price:', 'tradejournal'); ?> <input type="number" step="0.01" name="trades[<?php echo esc_attr($index); ?>][Entry Price]" value="<?php echo esc_attr($entry_price); ?>" /></label>
     70                <label><?php esc_html_e('Exit Price:', 'tradejournal'); ?> <input type="number" step="0.01" name="trades[<?php echo esc_attr($index); ?>][Exit Price]" value="<?php echo esc_attr($exit_price); ?>" /></label>
    6771                <label><?php esc_html_e('P&L:', 'tradejournal'); ?> <input type="text" name="trades[<?php echo esc_attr($index); ?>][P&L]" value="<?php echo esc_attr($pnl); ?>" /></label>
    6872                <label><?php esc_html_e('Side:', 'tradejournal'); ?>
  • tradejournal/trunk/includes/options.php

    r3185259 r3205179  
    2020
    2121// Render the options page HTML
     22// Render the options page HTML
    2223function tjwp_tradejournal_options_page_html()
    2324{
     
    2930    if (isset($_POST['tradejournal_options_submit'])) {
    3031        if (isset($_POST['tradejournal_options_nonce'])) {
    31             // Unslash and sanitize the nonce
    3232            $nonce = sanitize_text_field(wp_unslash($_POST['tradejournal_options_nonce']));
    33 
    34             // Verify the nonce
    3533            if (wp_verify_nonce($nonce, 'tradejournal_options_action')) {
    36 
    37                 // Update options based on form submission
     34                // Save options
    3835                update_option('tradejournal_merge_accounts', isset($_POST['tradejournal_merge_accounts']) ? 1 : 0);
    39 
    40                 // Sanitize and save the setups textarea field
    4136                if (isset($_POST['tradejournal_setups'])) {
    4237                    $setups = sanitize_textarea_field(wp_unslash($_POST['tradejournal_setups']));
    4338                    update_option('tradejournal_setups', $setups);
    4439                }
    45 
    46                 // Optional: Display success message
     40                if (isset($_POST['tradejournal_instrument_multipliers']) && is_array($_POST['tradejournal_instrument_multipliers'])) {
     41                    $multipliers = [];
     42
     43                    // Check if the subarrays 'name', 'multiplier', and 'commission' exist and are arrays
     44                    $names = $_POST['tradejournal_instrument_multipliers']['name'] ?? [];
     45                    $multipliers_data = $_POST['tradejournal_instrument_multipliers']['multiplier'] ?? [];
     46                    $commissions = $_POST['tradejournal_instrument_multipliers']['commission'] ?? [];
     47
     48                    if (isset($_POST['tradejournal_instrument_multipliers']) && is_array($_POST['tradejournal_instrument_multipliers'])) {
     49                        $multipliers = [];
     50
     51                        // Unslash and extract subarrays
     52                        $unslashed_multipliers = wp_unslash($_POST['tradejournal_instrument_multipliers']);
     53                        $names = isset($unslashed_multipliers['name']) && is_array($unslashed_multipliers['name']) ? $unslashed_multipliers['name'] : [];
     54                        $multipliers_data = isset($unslashed_multipliers['multiplier']) && is_array($unslashed_multipliers['multiplier']) ? $unslashed_multipliers['multiplier'] : [];
     55                        $commissions = isset($unslashed_multipliers['commission']) && is_array($unslashed_multipliers['commission']) ? $unslashed_multipliers['commission'] : [];
     56
     57                        foreach ($names as $index => $name) {
     58                            $name = sanitize_text_field($name);
     59                            $multiplier = isset($multipliers_data[$index]) ? floatval($multipliers_data[$index]) : 1; // Default multiplier
     60                            $commission = isset($commissions[$index]) ? floatval($commissions[$index]) : 0; // Default commission
     61
     62                            if (!empty($name)) {
     63                                $multipliers[$name] = [
     64                                    'multiplier' => $multiplier,
     65                                    'commission' => $commission
     66                                ];
     67                            }
     68                        }
     69
     70                        // Save the multipliers option
     71                        update_option('tradejournal_instrument_multipliers', $multipliers);
     72                    }
     73                }
    4774                echo '<div class="updated"><p>Settings saved.</p></div>';
    4875            } else {
    49                 // Nonce verification failed
    5076                wp_die('Security check failed');
    5177            }
    5278        } else {
    53             // Nonce field is missing
    5479            wp_die('Nonce field is missing');
    5580        }
    5681    }
    5782
    58     // Retrieve the current option values
     83    // Retrieve current options
    5984    $merge_accounts = get_option('tradejournal_merge_accounts', 0);
    6085    $setups = get_option('tradejournal_setups', '');
     86    $multipliers = get_option('tradejournal_instrument_multipliers', []);
     87    if (empty($multipliers)) {
     88        $multipliers = [
     89            'ES' => ['multiplier' => 50, 'commission' => 5]
     90        ];
     91    }
    6192?>
    6293
     
    70101                    <td>
    71102                        <label for="wp_tradersync_merge_accounts">
    72                             <input type="checkbox" id="wp_tradersync_merge_accounts" name="wp_tradersync_merge_accounts" disabled />
     103                            <input
     104                                type="checkbox"
     105                                id="wp_tradersync_merge_accounts"
     106                                name="wp_tradersync_merge_accounts"
     107                                disabled
     108                                aria-disabled="true" />
    73109                            <em><strong>Available in Pro version</strong></em><br>
    74                             Merge trades from multiple accounts with the same entry<br> time and instrument. Ideal for users with trade copiers to<br> consolidate trades across accounts into a single entry
     110                            Merge trades from multiple accounts with the same entry<br>
     111                            time and instrument. Ideal for users with trade copiers to<br>
     112                            consolidate trades across accounts into a single entry.<br>
     113                            <a href="https://tradejournalwp.com/" target="_blank">
     114                                Upgrade to Pro
     115                            </a>
    75116                        </label>
    76117                    </td>
     
    85126            </table>
    86127
     128            <h2><?php esc_html_e('Instrument Multipliers and Commissions', 'tradejournal'); ?></h2>
     129            <p>
     130                <?php esc_html_e('Define the multipliers and round-trip commissions for each instrument. The multiplier represents how much the instrument is worth per point. The commission represents the total cost of the buy and sell for the instrument.', 'tradejournal'); ?>
     131            </p>
     132            <p>
     133                <strong><?php esc_html_e('How P&L is Calculated:', 'tradejournal'); ?></strong>
     134            <ul>
     135                <li><?php esc_html_e('For a Long trade: P&L = (Exit Price - Entry Price) × Quantity × Multiplier - Commission', 'tradejournal'); ?></li>
     136                <li><?php esc_html_e('For a Short trade: P&L = (Entry Price - Exit Price) × Quantity × Multiplier - Commission', 'tradejournal'); ?></li>
     137            </ul>
     138            </p>
     139            <p>
     140                <strong><?php esc_html_e('Example:', 'tradejournal'); ?></strong><br>
     141                <?php esc_html_e('Instrument: ES (Multiplier = 50, Commission = $5)', 'tradejournal'); ?><br>
     142                <?php esc_html_e('Entry Price: 4000, Exit Price: 4010, Quantity: 2', 'tradejournal'); ?><br>
     143                <?php esc_html_e('Long Trade: P&L = (4010 - 4000) × 2 × 50 - 5 = $995', 'tradejournal'); ?>
     144            </p>
     145
     146            <div id="tradejournal-repeater">
     147                <div class="tradejournal-repeater-headers">
     148                    <span><?php esc_html_e('Instrument', 'tradejournal'); ?></span>
     149                    <span><?php esc_html_e('Multiplier', 'tradejournal'); ?></span>
     150                    <span><?php esc_html_e('Commission (round-trip)', 'tradejournal'); ?></span>
     151                    <span><?php esc_html_e('Action', 'tradejournal'); ?></span>
     152                </div>
     153                <?php foreach ($multipliers as $instrument => $values) { ?>
     154                    <div class="tradejournal-repeater-row">
     155                        <input type="text" name="tradejournal_instrument_multipliers[name][]" value="<?php echo esc_attr($instrument); ?>" />
     156                        <input type="number" name="tradejournal_instrument_multipliers[multiplier][]" value="<?php echo esc_attr($values['multiplier']); ?>" step="1" />
     157                        <input type="number" name="tradejournal_instrument_multipliers[commission][]" value="<?php echo esc_attr($values['commission']); ?>" step="0.01" />
     158                        <button type="button" class="button tradejournal-remove-row" disabled><?php esc_html_e('Remove', 'tradejournal'); ?></button>
     159                    </div>
     160                <?php } ?>
     161            </div>
     162            <p>
     163                <button type="button" id="tradejournal-add-row" class="button" disabled><?php esc_html_e('Add Instrument', 'tradejournal'); ?></button>
     164                <span style="margin-left: 10px;">
     165                    <strong><?php esc_html_e('Upgrade to Pro to add more instruments.', 'tradejournal'); ?></strong>
     166                    <a href="https://tradejournalwp.com/" target="_blank"><?php esc_html_e('Upgrade to Pro', 'tradejournal'); ?></a>
     167                </span>
     168            </p>
     169            <style>
     170                .tradejournal-repeater-headers,
     171                .tradejournal-repeater-row {
     172                    display: grid;
     173                    grid-template-columns: 3fr 2fr 2fr 1fr;
     174                    gap: 10px;
     175                    align-items: center;
     176                    margin-bottom: 10px;
     177                }
     178
     179                .tradejournal-repeater-headers {
     180                    font-weight: bold;
     181                    border-bottom: 1px solid #ddd;
     182                    padding-bottom: 5px;
     183                }
     184
     185                .tradejournal-repeater-row input {
     186                    padding: 5px;
     187                }
     188
     189                .tradejournal-remove-row {
     190                    text-align: center;
     191                }
     192            </style>
     193
    87194            <?php submit_button('Save Options', 'primary', 'tradejournal_options_submit'); ?>
    88195        </form>
  • tradejournal/trunk/readme.txt

    r3196002 r3205179  
    44Requires at least: 5.0
    55Tested up to: 6.7
    6 Stable tag: 1.0.6
     6Stable tag: 1.0.7
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    7676== Changelog ==
    7777
     78= 1.0.7 =
     79* Enhancement: Automatically retrieve instrument multipliers and commissions from plugin settings for CSV imports.
     80* Enhancement: Commission deductions added to P&L calculations for more accurate trade analysis.
     81* Enhancement: Options page updated to allow easy management of multipliers and commissions.
     82* Improvement: A streamlined experience for managing instruments, with editable fields for the default instrument in the free version.
     83* Improvement: Clear upgrade prompts to explore additional features available in the Pro version.
     84* Security: Enhanced sanitization and validation for safer data handling.
     85* Fix: Addressed issues with input processing to ensure smoother operation.
     86
    7887= 1.0.6 =
    7988* Enhancement: Added detailed plugin description and improved documentation.
     
    129138== Upgrade Notice ==
    130139
     140= 1.0.7 =
     141* Easily customize multipliers and commissions directly from the settings page.
     142* Accurate P&L calculations with automatic commission adjustments.
     143* Simplified options management with enhanced controls and settings.
     144* Explore Pro features for advanced capabilities and flexibility.
     145
    131146= 1.0.6 =
    132147* Enhancement: Added detailed plugin description and improved documentation.
  • tradejournal/trunk/tradejournal.php

    r3196002 r3205179  
    33Plugin Name: TradeJournal WP
    44Description: TradeJournal WP imports trades from NinjaTrader CSV files, creating detailed journal entries for each trading day. Includes trade management, P&L calculation, responsive tables, lightbox for screenshots, and compatibility with custom post types and block-based themes. Track performance, analyze setups, and organize screenshots easily within WordPress.
    5 Version: 1.0.6
     5Version: 1.0.7
    66Author: Laith Sinawi
    77Author URI: https://sinawiwebdesign.com
     
    7171    }
    7272
    73     // Temporary capture of the POST data
    74     $post_data = $_POST;
    75 
    76     // Initialize an empty array to hold sanitized trades data
     73    // Check if trades data is set
     74    if (!isset($_POST['trades']) || !is_array($_POST['trades'])) {
     75        return;
     76    }
     77
     78    // Retrieve trades data
     79    $trades = wp_unslash($_POST['trades']); // Remove slashes added by WordPress
     80
     81    // Initialize sanitized trades array
    7782    $sanitized_trades = [];
    7883
    79     // Check if trades are set and perform an initial sanitization
    80     if (!empty($post_data['trades']) && is_array($post_data['trades'])) {
    81 
    82         // Temporarily store the unslashed data in a variable for processing
    83         $unslashed_trades = wp_unslash($post_data['trades']);
    84 
    85         // Sanitize all nested elements using array_walk_recursive
    86         array_walk_recursive($unslashed_trades, function (&$value) {
    87             if (!is_array($value)) {
    88                 $value = sanitize_text_field($value);
    89             }
    90         });
    91 
    92         // Assign sanitized trades data to the final variable
    93         $sanitized_trades = $unslashed_trades;
    94 
    95         // Debug: Log the final sanitized trades data
    96         // error_log('Sanitized Trades Data: ' . print_r($sanitized_trades, true));
    97 
    98         // Now proceed with saving the sanitized trades
    99         update_post_meta($post_id, 'trade_repeater', $sanitized_trades);
    100     }
     84    // Sanitize each trade
     85    foreach ($trades as $trade) {
     86        $sanitized_trades[] = [
     87            'Instrument'    => sanitize_text_field($trade['Instrument'] ?? ''),
     88            'Account'       => sanitize_text_field($trade['Account'] ?? ''),
     89            'Entry Time'    => sanitize_text_field($trade['Entry Time'] ?? ''),
     90            'Entry Price'   => floatval($trade['Entry Price'] ?? 0),
     91            'Exit Price'    => floatval($trade['Exit Price'] ?? 0),
     92            'Qty'           => intval($trade['Qty'] ?? 0),
     93            'P&L'           => sanitize_text_field($trade['P&L'] ?? ''),
     94            'Side'          => sanitize_text_field($trade['Side'] ?? ''),
     95            'Comment'       => sanitize_text_field($trade['Comment'] ?? ''),
     96            'Screenshot'    => intval($trade['Screenshot'] ?? 0), // Expecting attachment ID
     97            'Setup'         => isset($trade['Setup']) ? array_map('sanitize_text_field', (array) $trade['Setup']) : [],
     98        ];
     99    }
     100
     101    // Save sanitized trades data as post meta
     102    update_post_meta($post_id, 'trade_repeater', $sanitized_trades);
    101103}
    102104add_action('save_post', 'tjwp_tradejournal_save_trades');
Note: See TracChangeset for help on using the changeset viewer.