Changeset 3205179
- Timestamp:
- 12/10/2024 12:45:48 AM (15 months ago)
- Location:
- tradejournal/trunk
- Files:
-
- 2 added
- 5 edited
-
includes/csv-import.php (modified) (1 diff)
-
includes/logs (added)
-
includes/logs/plugin-log.log (added)
-
includes/meta-box.php (modified) (2 diffs)
-
includes/options.php (modified) (4 diffs)
-
readme.txt (modified) (3 diffs)
-
tradejournal.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
tradejournal/trunk/includes/csv-import.php
r3185259 r3205179 80 80 $side = isset($trade['market pos.']) ? strtolower($trade['market pos.']) : ''; 81 81 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 ]; 88 91 } 89 92 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 91 106 $pnl = 0; 92 107 if ($entry_price && $exit_price) { 93 if ($side == 'long') {108 if ($side === 'long') { 94 109 $pnl = ($exit_price - $entry_price) * $qty * $multiplier; 95 } elseif ($side == 'short') {110 } elseif ($side === 'short') { 96 111 $pnl = ($entry_price - $exit_price) * $qty * $multiplier; 97 112 } 113 // Subtract commission 114 $pnl -= $commission; 98 115 $pnl = number_format($pnl, 2); 99 116 } -
tradejournal/trunk/includes/meta-box.php
r3185259 r3205179 45 45 $account = isset($trade['Account']) ? esc_attr($trade['Account']) : ''; 46 46 $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']) : ''; 47 49 $qty = isset($trade['Qty']) ? esc_attr($trade['Qty']) : ''; 48 50 $pnl = isset($trade['P&L']) ? esc_attr($trade['P&L']) : ''; … … 65 67 <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> 66 68 <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> 67 71 <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> 68 72 <label><?php esc_html_e('Side:', 'tradejournal'); ?> -
tradejournal/trunk/includes/options.php
r3185259 r3205179 20 20 21 21 // Render the options page HTML 22 // Render the options page HTML 22 23 function tjwp_tradejournal_options_page_html() 23 24 { … … 29 30 if (isset($_POST['tradejournal_options_submit'])) { 30 31 if (isset($_POST['tradejournal_options_nonce'])) { 31 // Unslash and sanitize the nonce32 32 $nonce = sanitize_text_field(wp_unslash($_POST['tradejournal_options_nonce'])); 33 34 // Verify the nonce35 33 if (wp_verify_nonce($nonce, 'tradejournal_options_action')) { 36 37 // Update options based on form submission 34 // Save options 38 35 update_option('tradejournal_merge_accounts', isset($_POST['tradejournal_merge_accounts']) ? 1 : 0); 39 40 // Sanitize and save the setups textarea field41 36 if (isset($_POST['tradejournal_setups'])) { 42 37 $setups = sanitize_textarea_field(wp_unslash($_POST['tradejournal_setups'])); 43 38 update_option('tradejournal_setups', $setups); 44 39 } 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 } 47 74 echo '<div class="updated"><p>Settings saved.</p></div>'; 48 75 } else { 49 // Nonce verification failed50 76 wp_die('Security check failed'); 51 77 } 52 78 } else { 53 // Nonce field is missing54 79 wp_die('Nonce field is missing'); 55 80 } 56 81 } 57 82 58 // Retrieve the current option values83 // Retrieve current options 59 84 $merge_accounts = get_option('tradejournal_merge_accounts', 0); 60 85 $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 } 61 92 ?> 62 93 … … 70 101 <td> 71 102 <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" /> 73 109 <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> 75 116 </label> 76 117 </td> … … 85 126 </table> 86 127 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 87 194 <?php submit_button('Save Options', 'primary', 'tradejournal_options_submit'); ?> 88 195 </form> -
tradejournal/trunk/readme.txt
r3196002 r3205179 4 4 Requires at least: 5.0 5 5 Tested up to: 6.7 6 Stable tag: 1.0. 66 Stable tag: 1.0.7 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 76 76 == Changelog == 77 77 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 78 87 = 1.0.6 = 79 88 * Enhancement: Added detailed plugin description and improved documentation. … … 129 138 == Upgrade Notice == 130 139 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 131 146 = 1.0.6 = 132 147 * Enhancement: Added detailed plugin description and improved documentation. -
tradejournal/trunk/tradejournal.php
r3196002 r3205179 3 3 Plugin Name: TradeJournal WP 4 4 Description: 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. 65 Version: 1.0.7 6 6 Author: Laith Sinawi 7 7 Author URI: https://sinawiwebdesign.com … … 71 71 } 72 72 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 77 82 $sanitized_trades = []; 78 83 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); 101 103 } 102 104 add_action('save_post', 'tjwp_tradejournal_save_trades');
Note: See TracChangeset
for help on using the changeset viewer.