1. 程式人生 > >讀取csv檔案,1min k線輸出到csv檔案中,計算5s,10s,20s移動平均值

讀取csv檔案,1min k線輸出到csv檔案中,計算5s,10s,20s移動平均值

參考:

以下為程式碼:

queue.h

#pragma once
#include <stdbool.h>
typedef struct queue
{
	int *pBase;
	int front;    //指向佇列第一個元素
	int rear;    //指向佇列最後一個元素的下一個元素
int maxsize; //迴圈佇列的最大儲存空間 }QUEUE, *PQUEUE; void CreateQueue(PQUEUE Q, int maxsize); void TraverseQueue(PQUEUE Q); bool FullQueue(PQUEUE Q); bool EmptyQueue(PQUEUE Q); bool Enqueue(PQUEUE Q, int val); bool Dequeue(PQUEUE Q); float average_queue(PQUEUE Q); void FreeQueue(PQUEUE queue);

queue.c

#include
<stdio.h>
#include<stdlib.h> #include <stdbool.h> #include"malloc.h" #include"queue.h" void CreateQueue(PQUEUE Q, int maxsize) { Q->pBase = (int *)malloc(sizeof(int)*maxsize); if (NULL == Q->pBase) { printf("Memory allocation failure"); exit(-1); //退出程式 } Q->front = 0; //初始化引數 Q->rear = 0; Q->maxsize = maxsize; } void TraverseQueue(PQUEUE Q) { int i = Q->front; printf("佇列中的元素是:\n"); while (i%Q->maxsize != Q->rear) { printf("%d ", Q->pBase[i]); i = (i + 1) % Q->maxsize; } printf("\n"); } bool FullQueue(PQUEUE Q) { if (Q->front == (Q->rear + 1) % Q->maxsize) //判斷迴圈連結串列是否滿,留一個預留空間不用 return true; else return false; } bool EmptyQueue(PQUEUE Q) { if (Q->front == Q->rear) //判斷是否為空 return true; else return false; } bool Enqueue(PQUEUE Q, int val) { if (FullQueue(Q)) return false; else { Q->pBase[Q->rear] = val; Q->rear = (Q->rear + 1) % Q->maxsize; return true; } } bool Dequeue(PQUEUE Q) { if (EmptyQueue(Q)) { return false; } else { Q->front = (Q->front + 1) % Q->maxsize; return true; } } float average_queue(PQUEUE Q) { if (FullQueue(Q)) { int ai = Q->front; float sum = 0.0; while (ai%Q->maxsize != Q->rear) { //printf("%d ", Q->pBase[i]); sum += Q->pBase[ai]; ai = (ai + 1) % Q->maxsize; //printf("%f ", sum); } return sum / (Q->maxsize - 1); } else { printf("not Full!!!"); return -1; } } void FreeQueue(PQUEUE queue) { free(queue->pBase); }

main.c

#define _CRT_SECURE_NO_DEPRECATE
/*
solution 1: #define _CRT_SECURE_NO_DEPRECATE
solution 2 : 使用*_s形式
*/


#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#include "queue.h"

//按收盤價平均值算MA的,準備是用佇列資料結構

#define MAX_LINE_SIZE 40
//除錯函式
void print_Info_per_min(struct Info_per_min *info);


bool one_min_read_and_write(FILE *rf, FILE *wf, char line[], size_t total, int share_price[], double trading_volume[], struct Info_per_min* info_per_min);
void average_trading_volumn(struct Info_per_min* info_per_min, double trading_volumn[], int length);
void shared_price_processed(struct Info_per_min* info_per_min, int share_price[], int length);
void kLineXEnqueue(PQUEUE kLinex, int closing_price);
void kLineInCsvFile(PQUEUE kLinex, FILE *wf);
struct Info_per_min
{
	//  時間 "年/月/日 時:分"
	char time_min[20];
	// 開盤股價
	int opening_price;
	//收盤價格
	int closing_price;
	//最高股價
	int max_share_price;
	//最低股價
	int min_share_price;
	//平均成交量
	double average_trading_volumn;
};
int main() {
	char file_name[] = "in_Arr.csv";
	char file_write[] = "out_arr.csv";
	//char test[] = "out_Arr_1min.csv";
	//檔案開始要刪除的行數
	int deletenumbers = 4;
	
	// 測試處理行數
	int totalnum = 600, process_cir=0;
	
	//每次要處理的行數
	size_t total = 120;

	/* 定義每1min內要儲存的資料 */
	
	// 1min內股價
	int share_price[120] = { 0 };
	// 1min中的成交量
	double trading_volume[120] = { 0 };
	
	struct Info_per_min info_per_min;

	//Ns內K線計算
	QUEUE kLine5, kLine10, kLine20;
	CreateQueue(&kLine5, 6);
	CreateQueue(&kLine10, 11);
	CreateQueue(&kLine20, 21);

	//緩衝檔案中每一行
	char line[MAX_LINE_SIZE];





	FILE *rf, *wf;
	rf = fopen(file_name, "r");
	wf = fopen(file_write, "w+");
	fprintf(wf, "時間, 開盤, 最高, 最低, 收盤, 成交量, MA_5, MA_10, MA_20");


	if (!rf) {
		fprintf(stderr, "failed to open file for reading\n");
		return 1;
	}

	
	
	//將前四行緩衝掉
	for (char line_num = 0; line_num < deletenumbers; ++line_num)
		fgets(line, MAX_LINE_SIZE, rf);

	while (1) {
		if (one_min_read_and_write(rf, wf, line, total, share_price, trading_volume, &info_per_min)){
			average_trading_volumn(&info_per_min, trading_volume, 120);
			shared_price_processed(&info_per_min, share_price, 120);


			fprintf(wf, "\n%s", info_per_min.time_min);
			fprintf(wf, ",%d", info_per_min.opening_price);
			fprintf(wf, ",%d", info_per_min.max_share_price);
			fprintf(wf, ",%d", info_per_min.min_share_price);
			fprintf(wf, ",%d", info_per_min.closing_price);
			fprintf(wf, ",%f", info_per_min.average_trading_volumn);

			//計算k線, 
			//收盤股價入佇列
			kLineXEnqueue(&kLine5, info_per_min.closing_price);
			kLineXEnqueue(&kLine10, info_per_min.closing_price);
			kLineXEnqueue(&kLine20, info_per_min.closing_price);

			//計算收盤股價平均值,寫入csv檔案
			kLineInCsvFile(&kLine5, wf);
			kLineInCsvFile(&kLine10, wf);
			kLineInCsvFile(&kLine20, wf);
		}
		else break;
		
		
		

		//print_Info_per_min(&info_per_min);
		
		/*printf( "%s\n",info_per_min.time_min);
		printf("shared_price:\n");
		for (size_t i = 0; i < 120; ++i)
			printf("%d: %d\n", i, share_price[i]);
		printf("trading_volume\n");
		for (size_t i = 0; i < 120; ++i)
			printf("%d: %f\n", i, trading_volume[i]);*/
		
		
	}
	fclose(rf);
	fclose(wf);
	FreeQueue(&kLine5);
	FreeQueue(&kLine10);
	FreeQueue(&kLine20);


	system("pause");


}

//讀出120行資料,讀入和寫出到檔案中
bool one_min_read_and_write(FILE *rf, FILE *wf, char line[], size_t total, int share_price[], double trading_volume[],struct Info_per_min* info_per_min) {
	
	/*
	rf: 讀入檔案
	wf:寫出檔案
	line:儲存一行資料的變數
	total:一次讀取的行數
	*/
	if (fgets(line, MAX_LINE_SIZE, rf) == NULL)
		return false;
	char *result = NULL;
	size_t num_line = 0;
	while (fgets(line, MAX_LINE_SIZE, rf) != NULL) {
		
		result = strtok(line, ",");
		short int times_into = 0;
		while (result != NULL) {
			// printf("%d:, %s\n", times_into, result);
			if (num_line == 0) {
				if (times_into == 0) {
					strcpy(info_per_min->time_min, result);
					strcat(info_per_min->time_min, " ");
					//printf("%d:, %s\n", times_into, info_per_min->time_min);
				}
				else if (times_into == 1) {
					strncat(info_per_min->time_min, result, strlen(result) - 3);
					//printf("%d:, %s\n", times_into, info_per_min->time_min);
				}

				
			}
			if (times_into == 3)
				share_price[num_line] = atoi(result);
			else if (times_into == 4)
				trading_volume[num_line] = atof(result);



			times_into++;
			
			result = strtok(NULL, ",");
			
			
		}

		++num_line;
		//printf("\n");
		if (num_line >= total) break;
	}
	return true;
}


void average_trading_volumn(struct Info_per_min* info_per_min, double trading_volumn[], int length) {
	/*
	info_per_min: 儲存一分鐘內要獲取的資訊
	trading_volumn: 一分鐘內成交量
	length: 陣列trading_volumn長度
	*/
	double sum = 0.0;
	for (int i = 0; i < length; ++i) {
		sum += trading_volumn[i];
	}
	info_per_min->average_trading_volumn = sum / 120;
}

void shared_price_processed(struct Info_per_min* info_per_min, int share_price[], int length) {
	/*
	info_per_min: 儲存一分鐘內要獲取的資訊
	share_price: 一分鐘內股價變化
	length: 陣列share_price的長度
	*/
	int min=share_price[0], max = share_price[0];
	info_per_min->opening_price = share_price[0];
	info_per_min->closing_price = share_price[length - 1];
	for (int i = 1; i < length; ++i) {
		if (max < share_price[i])
			max = share_price[i];
		else if (min > share_price[i])
			min = share_price[i];
	}
	info_per_min->min_share_price = min;
	info_per_min->max_share_price = max;
}

void print_Info_per_min(struct Info_per_min *info) {
	printf("時間: %s\n", info->time_min);
	printf("開盤股價: %d\n", info->opening_price);
	printf("收盤價格: %d\n", info->closing_price);
	printf("最高股價: %d\n", info->max_share_price);
	printf("最低股價: %d\n", info->min_share_price);
	printf("平均成交量: %f\n", info->average_trading_volumn);

}

void kLineXEnqueue(PQUEUE kLinex,int closing_price) {
	if (!Enqueue(kLinex, closing_price)) {
		Dequeue(kLinex);
		Enqueue(kLinex, closing_price);
	}
}

void kLineInCsvFile(PQUEUE kLinex,FILE *wf) {
	float average = 0.0;
	if (FullQueue(kLinex)) {
		average = average_queue(kLinex);
		fprintf(wf, ",%f", average);
	}
		
}