开发环境:
- Visual Studio V2012
- .NET Framework 4 Client Profile
- .NET Framework 4.5
功能说明:
- 精确计算沪深A股收益
- 具有简单记账功能
更新历史:
2013年09月20日
- 修正过户费计算错误
2013年07月31日
- 在配置文件中增加设置记账用的字符集编码选项
2013年07月30日
- 记账中股票价格精确到厘
2013年07月28日
- 修正了过户费的计算
- 修正了大额交易时数据溢出的问题
- 增加了多次买入同一股票时,直接通过买入成本来核算收益
2013年07月23日
- 完成股票收益计算器
软件下载:
源代码下载:
软件界面:
源代码:
MainWindow.xaml
<Window x:Class="Splash.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore" Title="股票收益计算器" Height="600" Width="500" Icon="balance.ico" ResizeMode="CanMinimize" SizeToContent="Height" WindowStartupLocation="CenterScreen" Closing="Window_Closing" Loaded="Window_Loaded" FontFamily="Microsoft YaHei" KeyDown="Window_KeyDown" MouseRightButtonDown="Window_MouseRightButtonDown"> <Grid Margin="8"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <GroupBox Grid.Row="0"> <GroupBox.Header> <Label Content="证券交易所" /> </GroupBox.Header> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <RadioButton Grid.Column="0" Name="radioButtonSHA" Content="沪市A股" VerticalAlignment="Center" Margin="8" IsChecked="True" Click="radioButtonSHA_Click" TabIndex="1" /> <RadioButton Grid.Column="1" Name="radioButtonSZA" Content="深市A股" VerticalAlignment="Center" Margin="8" Click="radioButtonSZA_Click" TabIndex="2" /> </Grid> </GroupBox> <GroupBox Grid.Row="1"> <GroupBox.Header> <Label Content="交易税率" /> </GroupBox.Header> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid Grid.Row="0"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="100" /> <ColumnDefinition Width="60" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="券商佣金比率" /> <Label Grid.Row="1" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="印花税税率" /> <TextBox Name="textBoxCommissionRate" Grid.Row="0" Grid.Column="1" Margin="0,4" Text="0.075" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" input:InputMethod.IsInputMethodEnabled="False" TabIndex="3" /> <TextBox Name="textBoxStampDutyRate" Grid.Row="1" Grid.Column="1" Margin="0,4" Text="0.1" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" input:InputMethod.IsInputMethodEnabled="False" TabIndex="4" /> <Label Grid.Row="0" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="%(不足5元按5元收取)" /> <Label Grid.Row="1" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="%(仅在卖出时征收)" /> </Grid> <Grid Grid.Row="1" Name="gridTransferFee"> <Grid.ColumnDefinitions> <ColumnDefinition Width="100" /> <ColumnDefinition Width="60" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="过户费费率" /> <TextBox Name="textBoxTransferFeeRate" Grid.Column="1" Margin="0,4" Text="0.6" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" input:InputMethod.IsInputMethodEnabled="False" TabIndex="5" /> <Label Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="元/千股(最低收取1元)" /> </Grid> </Grid> </GroupBox> <GroupBox Name="groupBoxStockTradeVolume" Grid.Row="2"> <GroupBox.Header> <Label Content="交易量" /> </GroupBox.Header> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="60" /> <ColumnDefinition Width="60" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="股票买入数量" /> <Label Grid.Row="1" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="股票买入价" /> <Label Grid.Row="2" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="股票卖出数量" /> <Label Grid.Row="3" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="股票卖出价" /> <TextBox Name="textBoxNumberOfSharesBought" Grid.Row="0" Grid.Column="1" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" input:InputMethod.IsInputMethodEnabled="False" TabIndex="7" LostFocus="textBoxNumberOfSharesBought_LostFocus" TextChanged="textBoxTradeVolumeState_TextChanged" /> <TextBox Name="textBoxStockPurchasePrice" Grid.Row="1" Grid.Column="1" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" input:InputMethod.IsInputMethodEnabled="False" TabIndex="8" TextChanged="textBoxTradeVolumeState_TextChanged" /> <TextBox Name="textBoxStockAskSize" Grid.Row="2" Grid.Column="1" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" input:InputMethod.IsInputMethodEnabled="False" IsReadOnly="True" TabIndex="9" TextChanged="textBoxTradeVolumeState_TextChanged" /> <TextBox Name="textBoxStockAskingPrice" Grid.Row="3" Grid.Column="1" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" input:InputMethod.IsInputMethodEnabled="False" TabIndex="10" TextChanged="textBoxTradeVolumeState_TextChanged" /> <Label Grid.Row="0" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="股" /> <Label Grid.Row="1" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="元/股" /> <Label Grid.Row="2" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="股" /> <Label Grid.Row="3" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="元/股" /> <Grid Grid.Row="0" Grid.RowSpan="2" Grid.Column="3"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="股票代号" Padding="0,5,5,5" /> <TextBox Name="textBoxStockCode" Grid.Row="0" Grid.Column="1" Margin="0,4" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" input:InputMethod.IsInputMethodEnabled="False" MaxLength="6" TabIndex="13" /> <Button Name="buttonAccounting" Grid.Row="0" Grid.Column="2" Margin="8,4" MinWidth="80" Content="记账" TabIndex="15" Click="buttonAccounting_Click" /> <Label Grid.Row="1" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="股票名称" Padding="0,5,5,5" /> <TextBox Name="textBoxStockName" Grid.Row="1" Grid.Column="1" Margin="0,4" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" TabIndex="14" /> <Button Name="buttonView" Grid.Row="1" Grid.Column="2" Margin="8,4" MinWidth="80" Content="查看" TabIndex="16" Click="buttonView_Click"/> </Grid> <CheckBox Name="checkBoxSame" Grid.Row="2" Grid.Column="3" Margin="0,4" VerticalContentAlignment="Center" IsChecked="True" Content="同买入数量" TabIndex="12" Click="checkBoxSame_Click" /> <Grid Grid.Row="3" Grid.Column="3" Margin="0,4"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Button Name="buttonCalculate" Grid.Column="0" Margin="8,0" MaxWidth="80" Content="计算" Click="buttonCalculate_Click" TabIndex="11" /> <Button Name="buttonReset" Grid.Column="1" Margin="8,0" MaxWidth="80" Content="重置" Click="buttonReset_Click" TabIndex="12" /> </Grid> </Grid> </GroupBox> <GroupBox Name="groupBoxOutput" Grid.Row="3"> <GroupBox.Header> <Label Content="计算结果" /> </GroupBox.Header> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="8" /> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <CheckBox Name="checkBoxStockPurchaseCost" Grid.Row="0" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="买入成本" Click="checkBoxStockPurchaseCost_Click" /> <Label Grid.Row="1" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="过户费" /> <Label Grid.Row="2" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="券商佣金" /> <Label Grid.Row="3" Grid.Column="0" Margin="0,4" VerticalContentAlignment="Center" Content="总体投资收益" /> <TextBox Name="textBoxStockPurchaseCost" Grid.Row="0" Grid.Column="1" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsReadOnly="True" ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}" TextChanged="textBoxStockPurchaseCost_TextChanged" /> <TextBox Name="textBoxStockTransferFee" Grid.Row="1" Grid.Column="1" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsReadOnly="True" /> <TextBox Name="textBoxStockBrokerageCommission" Grid.Row="2" Grid.Column="1" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsReadOnly="True" /> <TextBox Name="textBoxTotalInvestmentIncome" Grid.Row="3" Grid.Column="1" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsReadOnly="True" Foreground="Red" Background="LightGray" FontSize="24" FontWeight="Bold" ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}" /> <Label Grid.Row="0" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="元" /> <Label Grid.Row="1" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="元" /> <Label Grid.Row="2" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="元" /> <Label Grid.Row="3" Grid.Column="2" Margin="0,4" VerticalContentAlignment="Center" Content="元" /> <Label Grid.Row="0" Grid.Column="4" Margin="0,4" VerticalContentAlignment="Center" Content="卖出收入" /> <Label Grid.Row="1" Grid.Column="4" Margin="0,4" VerticalContentAlignment="Center" Content="印花税" /> <Label Grid.Row="2" Grid.Column="4" Margin="0,4" VerticalContentAlignment="Center" Content="税费合计" /> <Label Grid.Row="3" Grid.Column="4" Margin="0,4" VerticalContentAlignment="Center" Content="总体盈亏比例" /> <TextBox Name="textBoxStockSellRevenue" Grid.Row="0" Grid.Column="5" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsReadOnly="True" ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}" /> <TextBox Name="textBoxStockStampDuty" Grid.Row="1" Grid.Column="5" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsReadOnly="True" /> <TextBox Name="textBoxStockTotalTaxes" Grid.Row="2" Grid.Column="5" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsReadOnly="True" /> <TextBox Name="textBoxTotalProfitAndLossRatio" Grid.Row="3" Grid.Column="5" Margin="0,4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsReadOnly="True" Background="LightGray" FontSize="24" FontWeight="Bold" ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}" /> <Label Grid.Row="0" Grid.Column="6" Margin="0,4" VerticalContentAlignment="Center" Content="元" /> <Label Grid.Row="1" Grid.Column="6" Margin="0,4" VerticalContentAlignment="Center" Content="元" /> <Label Grid.Row="2" Grid.Column="6" Margin="0,4" VerticalContentAlignment="Center" Content="元" /> <Label Grid.Row="3" Grid.Column="6" Margin="0,4" VerticalContentAlignment="Center" Content="%" /> </Grid> </GroupBox> </Grid> </Window>
MainWindow.xaml.cs
/* ---------------------------------------------------------- * 文件名称:MainWindow.xaml.cs * * 作者:秦建辉 * * QQ:36748897 * * 博客:http://www.firstsolver.com/wordpress/ * * 开发环境: * Visual Studio V2012 * .NET Framework 4 Client Profile * * 版本历史: * V1.4 2013年09月20日 * 修正过户费计算错误 * * V1.3 2013年07月31日 * 在配置文件中增加设置记账用的字符集编码选项 * * V1.2 2013年07月30日 * 记账中股票价格精确到厘 * * V1.1 2013年07月28日 * 修正了过户费的计算 * 修正了大额交易时数据溢出的问题 * 增加了多次买入同一股票时,直接通过买入成本来核算收益 * * V1.0 2013年07月23日 * 完成股票收益计算器 * 注意事项: * Math.Round为4舍6入,如果为5,则看前一位,奇进偶不进,不符合现实情况中的4舍5入要求 ------------------------------------------------------------ */ using Splash.Linq; using Splash.Windows; using System; using System.IO; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace Splash { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { /// <summary> /// 配置文件信息 /// </summary> private StockReturnConfig Config = new StockReturnConfig(); /// <summary> /// 配置文件路径 /// </summary> private String iniFilePath = AppDomain.CurrentDomain.BaseDirectory + "\\" + "StockReturn.ini"; /// <summary> /// 记账文件存储目录 /// </summary> private static readonly String csvToFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\Splash\\StockReturn\\"; /// <summary> /// 记账文件存储路径 /// </summary> private static readonly String csvFilePath = csvToFolder + "StockReturn.csv"; /// <summary> /// 是否已有计算输出结果 /// </summary> private Boolean isHasOutput = false; public MainWindow() { InitializeComponent(); } private void radioButtonSHA_Click(object sender, RoutedEventArgs e) { // 沪市A股,显示过户费 if ((Boolean)radioButtonSHA.IsChecked) gridTransferFee.Visibility = System.Windows.Visibility.Visible; } private void radioButtonSZA_Click(object sender, RoutedEventArgs e) { // 深市A股,隐藏过户费 if ((Boolean)radioButtonSZA.IsChecked) gridTransferFee.Visibility = System.Windows.Visibility.Collapsed; } private void checkBoxSame_Click(object sender, RoutedEventArgs e) { textBoxStockAskSize.IsReadOnly = (Boolean)checkBoxSame.IsChecked; if ((Boolean)checkBoxSame.IsChecked) { // 卖出数量等同于买入数量 textBoxStockAskSize.Text = textBoxNumberOfSharesBought.Text; } else { textBoxStockAskSize.Clear(); textBoxStockAskSize.Focus(); } } private void textBoxNumberOfSharesBought_LostFocus(object sender, RoutedEventArgs e) { if ((Boolean)checkBoxSame.IsChecked) { textBoxStockAskSize.Text = textBoxNumberOfSharesBought.Text; } } // 计算 private void buttonCalculate_Click(object sender, RoutedEventArgs e) { // 券商佣金比率 Double CommissionRate; if (!Double.TryParse(textBoxCommissionRate.Text, out CommissionRate)) { MessageBoxPlus.Show(this, "不正确的券商佣金比率!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxCommissionRate.Focus(); return; } if (CommissionRate != Config.CommissionRate) { Config.CommissionRate = CommissionRate; Config.isUpdateNeeded = true; } // 印花税税率 Double StampDutyRate; if (!Double.TryParse(textBoxStampDutyRate.Text, out StampDutyRate)) { MessageBoxPlus.Show(this, "不正确的印花税税率!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxStampDutyRate.Focus(); return; } if (StampDutyRate != Config.StampDutyRate) { Config.StampDutyRate = StampDutyRate; Config.isUpdateNeeded = true; } // 过户费费率 Double TransferFeeRate; if (!Double.TryParse(textBoxTransferFeeRate.Text, out TransferFeeRate)) { MessageBoxPlus.Show(this, "不正确的过户费费率!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxTransferFeeRate.Focus(); return; } if (TransferFeeRate != Config.TransferFeeRate) { Config.TransferFeeRate = TransferFeeRate; Config.isUpdateNeeded = true; } Int32 NumberOfSharesBought = 0; // 股票买入数量 Double StockPurchasePrice = 0.0; // 股票买入价格 if (!(Boolean)checkBoxStockPurchaseCost.IsChecked) { if (!Int32.TryParse(textBoxNumberOfSharesBought.Text, out NumberOfSharesBought)) { MessageBoxPlus.Show(this, "不正确的股票买入数量!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxNumberOfSharesBought.Focus(); return; } if (!Double.TryParse(textBoxStockPurchasePrice.Text, out StockPurchasePrice)) { MessageBoxPlus.Show(this, "不正确的股票买入价格!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxStockPurchasePrice.Focus(); return; } } // 股票卖出数量 Int32 StockAskSize; if (!Int32.TryParse(textBoxStockAskSize.Text, out StockAskSize)) { MessageBoxPlus.Show(this, "不正确的股票卖出数量!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxStockAskSize.Focus(); return; } // 股票卖出价格 Double StockAskingPrice; if (!Double.TryParse(textBoxStockAskingPrice.Text, out StockAskingPrice)) { MessageBoxPlus.Show(this, "不正确的股票卖出价格!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxStockAskingPrice.Focus(); return; } // 计算过户费 Double BuyingTransferFee = 0.0; Double SellingTransferFee = 0.0; if ((Boolean)radioButtonSHA.IsChecked) { // 沪市A股 const Int32 Base = 1000; if (!(Boolean)checkBoxStockPurchaseCost.IsChecked) { BuyingTransferFee = NumberOfSharesBought * TransferFeeRate / Base; BuyingTransferFee = ((Int64)(BuyingTransferFee * 1000 + 5)) / 10 * 0.01; // 圆整到小数点后2位 if (BuyingTransferFee < 1.0) BuyingTransferFee = 1.0; // 不足1元时按1元收取 } SellingTransferFee = StockAskSize * TransferFeeRate / Base; SellingTransferFee = ((Int64)(SellingTransferFee * 1000 + 5)) / 10 * 0.01; if (SellingTransferFee < 1.0) SellingTransferFee = 1.0; // 不足1元时按1元收取 } Double TransferFee = BuyingTransferFee + SellingTransferFee; textBoxStockTransferFee.Text = TransferFee.ToString("F2"); // 计算印花税 Double StampDuty = StockAskSize * StockAskingPrice * StampDutyRate * 0.01; StampDuty = ((Int64)(StampDuty * 1000 + 5)) / 10 * 0.01; textBoxStockStampDuty.Text = StampDuty.ToString("F2"); // 计算券商佣金 Double BuyingCommission = 0.0; if (!(Boolean)checkBoxStockPurchaseCost.IsChecked) { BuyingCommission = NumberOfSharesBought * StockPurchasePrice * CommissionRate * 0.01; BuyingCommission = ((Int64)(BuyingCommission * 1000 + 5)) / 10 * 0.01; if (BuyingCommission < 5.0) BuyingCommission = 5.0; // 买入佣金 } Double SellingCommission = StockAskSize * StockAskingPrice * CommissionRate * 0.01; SellingCommission = ((Int64)(SellingCommission * 1000 + 5)) / 10 * 0.01; if (SellingCommission < 5.0) SellingCommission = 5.0; // 卖出佣金 Double BrokerCommission = BuyingCommission + SellingCommission; // 总的佣金 textBoxStockBrokerageCommission.Text = BrokerCommission.ToString("F2"); // 计算税费合计:过户费 + 印花税 + 券商佣金 Double StockTotalTaxes = TransferFee + StampDuty + BrokerCommission; textBoxStockTotalTaxes.Text = StockTotalTaxes.ToString("F2"); // 计算买入成本 Double StockPurchaseCost = 0.0; if (!(Boolean)checkBoxStockPurchaseCost.IsChecked) { StockPurchaseCost = BuyingTransferFee + BuyingCommission + NumberOfSharesBought * StockPurchasePrice; StockPurchaseCost = ((Int64)(StockPurchaseCost * 1000 + 5)) / 10 * 0.01; } else { if (!Double.TryParse(textBoxStockPurchaseCost.Text, out StockPurchaseCost)) { MessageBoxPlus.Show(this, "不正确的买入成本!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxStockPurchaseCost.Focus(); return; } } if (StockPurchaseCost < 1.0) // 1手100股 { MessageBoxPlus.Show(this, "不正确的买入成本!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxStockPurchaseCost.Focus(); return; } textBoxStockPurchaseCost.Text = StockPurchaseCost.ToString("F2"); // 计算卖出收入 Double StockSellRevenue = StockAskSize * StockAskingPrice - SellingTransferFee - StampDuty - SellingCommission; StockSellRevenue = ((Int64)(StockSellRevenue * 1000 + 5)) / 10 * 0.01; textBoxStockSellRevenue.Text = StockSellRevenue.ToString("F2"); // 计算总体投资收益 Double TotalInvestmentIncome = StockSellRevenue - StockPurchaseCost; textBoxTotalInvestmentIncome.Text = TotalInvestmentIncome.ToString("F2"); // 计算总体盈亏比例 Double TotalProfitAndLossRatio = TotalInvestmentIncome / StockPurchaseCost * 100; TotalProfitAndLossRatio = ((Int64)(TotalProfitAndLossRatio * 1000 + 5)) / 10 * 0.01; textBoxTotalProfitAndLossRatio.Text = TotalProfitAndLossRatio.ToString("F2"); // 设置颜色 switch (Math.Sign(TotalInvestmentIncome)) { case 1: textBoxTotalInvestmentIncome.Foreground = textBoxTotalProfitAndLossRatio.Foreground = new SolidColorBrush(Colors.Red); break; case 0: textBoxTotalInvestmentIncome.Foreground = textBoxTotalProfitAndLossRatio.Foreground = new SolidColorBrush(Colors.White); break; case -1: textBoxTotalInvestmentIncome.Foreground = textBoxTotalProfitAndLossRatio.Foreground = new SolidColorBrush(Colors.Green); break; } isHasOutput = true; // 已生成计算结果 } // 重置 private void buttonReset_Click(object sender, RoutedEventArgs e) { // 交易量组合框 ClearTextBoxInPanel(groupBoxStockTradeVolume.Content as Panel); // 计算结果组合框 ClearTextBoxInPanel(groupBoxOutput.Content as Panel); } // 记账 private void buttonAccounting_Click(object sender, RoutedEventArgs e) { if (String.IsNullOrEmpty(textBoxStockCode.Text)) { MessageBoxPlus.Show(this, "股票代码不能为空!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxStockCode.Focus(); return; } if (String.IsNullOrEmpty(textBoxStockName.Text)) { MessageBoxPlus.Show(this, "股票名称不能为空!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); textBoxStockName.Focus(); return; } if (!isHasOutput) { MessageBoxPlus.Show(this, "请先获取计算结果!", "警告", MessageBoxButton.OK, MessageBoxImage.Warning); return; } // 判断文件是否存在 if (!System.IO.File.Exists(csvFilePath)) { // 如果目标文件夹不存在则自动创建 if (!System.IO.Directory.Exists(csvToFolder)) { System.IO.Directory.CreateDirectory(csvToFolder); } using (StreamWriter sw = new StreamWriter(csvFilePath, true, System.Text.Encoding.GetEncoding(Config.CodePage))) { // 写入列标题 sw.WriteLine("\"股票代码\",\"股票名称\",\"买入数量\",\"卖出数量\",\"买入价格\",\"卖出价格\",\"买入成本\",\"卖出收入\",\"税费合计\",\"投资收益\",\"盈亏比例\""); } } try { using (StreamWriter sw = new StreamWriter(csvFilePath, true, System.Text.Encoding.GetEncoding(Config.CodePage))) { // 股票代码 sw.Write("\"" + textBoxStockCode.Text + "\","); // 股票名称 sw.Write("\"" + textBoxStockName.Text + "\","); // 股票买入数量 if (!(Boolean)checkBoxStockPurchaseCost.IsChecked) { sw.Write("\"" + textBoxNumberOfSharesBought.Text + "\","); } else { sw.Write("\"\","); } // 股票卖出数量 sw.Write("\"" + textBoxStockAskSize.Text + "\","); // 股票买入价格 if (!(Boolean)checkBoxStockPurchaseCost.IsChecked) { Double StockPurchasePrice = Double.Parse(textBoxStockPurchasePrice.Text); sw.Write("\"" + StockPurchasePrice.ToString("F3") + "\","); } else { sw.Write("\"\","); } // 股票卖出价格 Double StockAskingPrice = Double.Parse(textBoxStockAskingPrice.Text); sw.Write("\"" + StockAskingPrice.ToString("F3") + "\","); // 买入成本 sw.Write("\"" + textBoxStockPurchaseCost.Text + "\","); // 卖出收入 sw.Write("\"" + textBoxStockSellRevenue.Text + "\","); // 税费合计 if (!(Boolean)checkBoxStockPurchaseCost.IsChecked) { sw.Write("\"" + textBoxStockTotalTaxes.Text + "\","); } else { sw.Write("\"\","); } // 总体投资收益 sw.Write("\"" + textBoxTotalInvestmentIncome.Text + "\","); // 总体盈亏比例 sw.WriteLine("\"" + textBoxTotalProfitAndLossRatio.Text + "\""); // 显示成功信息 MessageBoxPlus.Show(this, "记账成功!", "祝贺", MessageBoxButton.OK, MessageBoxImage.Information); } } catch (Exception ex) { MessageBoxPlus.Show(this, ex.Message, "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } // 查看 private void buttonView_Click(object sender, RoutedEventArgs e) { if (System.IO.File.Exists(csvFilePath)) Splash.Diagnostics.Process.ShellExecute(csvFilePath); } private void Window_Loaded(object sender, RoutedEventArgs e) { // 读取配置文件信息 if (Config.Read(iniFilePath)) { textBoxCommissionRate.Text = Config.CommissionRate.ToString(); // 券商佣金比率 textBoxStampDutyRate.Text = Config.StampDutyRate.ToString(); // 印花税税率 textBoxTransferFeeRate.Text = Config.TransferFeeRate.ToString(); // 过户费费率 } } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { // 保存到配置文件 Config.Save(iniFilePath); } // 清空Panel容器内所有的TextBox控件 private static void ClearTextBoxInPanel(Panel panel) { foreach (UIElement item in panel.Children) { if (item is TextBox) { (item as TextBox).Clear(); } else if (item is Panel) { ClearTextBoxInPanel(item as Panel); } } } private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) { // 按“ESC”进入最小化状态 if (e.Key.Equals(System.Windows.Input.Key.Escape)) this.WindowState = System.Windows.WindowState.Minimized; } private void Window_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { // 按鼠标右键进入最小化状态 if (e.RightButton == System.Windows.Input.MouseButtonState.Pressed) this.WindowState = System.Windows.WindowState.Minimized; } private void textBoxTradeVolumeState_TextChanged(object sender, TextChangedEventArgs e) { if (isHasOutput) { String StockPurchaseCost = String.Empty; if ((Boolean)checkBoxStockPurchaseCost.IsChecked) { // 备份股票买入成本 StockPurchaseCost = textBoxStockPurchaseCost.Text; } ClearTextBoxInPanel(groupBoxOutput.Content as Panel); // 清空计算结果组合框内的文本框 textBoxStockCode.Clear(); // 清空股票代码文本框 textBoxStockName.Clear(); // 清空股票名称文本框 isHasOutput = false; if ((Boolean)checkBoxStockPurchaseCost.IsChecked) { // 恢复股票买入成本 textBoxStockPurchaseCost.Text = StockPurchaseCost; } } } private void checkBoxStockPurchaseCost_Click(object sender, RoutedEventArgs e) { isHasOutput = false; // 未生成计算结果 // 清空文本框内容 ClearTextBoxInPanel(groupBoxStockTradeVolume.Content as Panel); ClearTextBoxInPanel(groupBoxOutput.Content as Panel); if ((Boolean)checkBoxStockPurchaseCost.IsChecked) { // 股票买入数量文本框失效,禁止用户输入 textBoxNumberOfSharesBought.IsEnabled = false; textBoxNumberOfSharesBought.Background = new SolidColorBrush(Colors.Black); // 股票买入价格文本框失效,禁止用户输入 textBoxStockPurchasePrice.IsEnabled = false; textBoxStockPurchasePrice.Background = new SolidColorBrush(Colors.Black); // 同买入数量检测框失效 checkBoxSame.IsEnabled = false; // 股票卖出数量文本框允许用户输入 textBoxStockAskSize.IsReadOnly = false; // 买入成本文本框允许用户输入 textBoxStockPurchaseCost.IsReadOnly = false; textBoxStockPurchaseCost.Focus(); } else { // 股票买入数量文本框生效,允许用户输入 textBoxNumberOfSharesBought.IsEnabled = true; textBoxNumberOfSharesBought.Background = new SolidColorBrush(Colors.White); textBoxNumberOfSharesBought.Focus(); // 股票买入价格文本框生效,允许用户输入 textBoxStockPurchasePrice.IsEnabled = true; textBoxStockPurchasePrice.Background = new SolidColorBrush(Colors.White); // 同买入数量检测框生效 checkBoxSame.IsEnabled = true; if((Boolean)checkBoxSame.IsChecked) textBoxStockAskSize.IsReadOnly = true; else textBoxStockAskSize.IsReadOnly = false; // 买入成本文本框失效,禁止用户输入 textBoxStockPurchaseCost.IsReadOnly = true; } } private void textBoxStockPurchaseCost_TextChanged(object sender, TextChangedEventArgs e) { if (isHasOutput) isHasOutput = false; } } /// <summary> /// 配置文件 /// </summary> public class StockReturnConfig { /// <summary> /// LINQ 读写 ini 文件 /// </summary> internal LINQToINI iniFile; /// <summary> /// 券商佣金比率 /// </summary> public Double CommissionRate = 0.075; /// <summary> /// 印花税税率 /// </summary> public Double StampDutyRate = 0.1; /// <summary> /// 过户费费率 /// </summary> public Double TransferFeeRate = 0.6; /// <summary> /// 记账字符集编码,默认为UTF-8 /// </summary> public Int32 CodePage = 65001; /// <summary> /// 是否需要更新配置文件 /// </summary> public Boolean isUpdateNeeded = false; // 读取配置文件 public Boolean Read(String iniFileName) { iniFile = new LINQToINI(); if (!iniFile.Load(iniFileName)) { isUpdateNeeded = true; // 需要恢复配置文件 return false; } // 券商佣金比率 String[] ResultSet = iniFile.GetProfileString("TAX", "CommissionRate"); if (ResultSet != null && ResultSet.Length == 1) Double.TryParse(ResultSet[0], out CommissionRate); // 印花税税率 ResultSet = iniFile.GetProfileString("TAX", "StampDutyRate"); if (ResultSet != null && ResultSet.Length == 1) Double.TryParse(ResultSet[0], out StampDutyRate); // 过户费费率 ResultSet = iniFile.GetProfileString("TAX", "TransferFeeRate"); if (ResultSet != null && ResultSet.Length == 1) Double.TryParse(ResultSet[0], out TransferFeeRate); // 记账字符集编码,默认采用UTF-8 CodePage = iniFile.GetProfileInt("ACCOUNT", "CodePage", 65001); return true; } // 更新配置文件 public Boolean Save(String iniFileName) { if (!isUpdateNeeded) return true; iniFile.WriteProfileString("TAX", "CommissionRate", CommissionRate.ToString()); iniFile.WriteProfileString("TAX", "StampDutyRate", StampDutyRate.ToString()); iniFile.WriteProfileString("TAX", "TransferFeeRate", TransferFeeRate.ToString()); return iniFile.Save(iniFileName); } } }