주식차트는 분,초,시,일 등의 가격 데이터를 O(open), H(high), L(low), C(close)를 가지고 봉 형태로 표시해 줍니다. 이를 candlesticks chart라고 합니다.
그러면, 주식의 거래데이터가 아래와 가티 주어질 때 ohlc를 만듭니다.
###
실제 상황과 비슷하게 하기 위해서 아래 예제를 조금 바꾸어보았습니다. 조건이 바뀌기 전에 답을 주신 '상파'님의 양해를 먼저 구합니다.
###
예) 1분마다 open, high, low, close를 만듭니다.
분:초, 거래가격
1:02, 1100
1:20, 1170
1:59, 1090
2:30, 1030
2:31, 1110
2:42, 1150
2:55, 1210
2:56, 1190
3:02, 1120
3:09, 1100
4:15, 1090
4:20, 1080
4:55, 1050
4:56, 1020
4:57, 1000
[조건] 실제 주식 거래의 경우,, 분당 거래 회수가 10번, 100번, 1000번 등일 수 있으므로, high, low를 찾을 때 되도록 전체 데이터에서 찾지 않고,, 앞뒤 데이터를 비교하여 찾아주십시오..
답:
open = [1100, 1030, 1120, 1090]
high = [1170, 1210, 1120, 1090]
low = [1090, 1030, 1100, 1000]
close = [1090, 1190, 1100, 1000]
28개의 풀이가 있습니다.
Python 3.4.2
단위시간의 거래는 log 파일로 떨어지며 'trade.log' 라는 파일에 쌓이는 것은 전제로 함. 따라서 문제에 주어진 기록을 trade.log 라는 텍스트파일에 저장하여 line 단위로 읽어들임.
봉차트는 단위시간당 open, high, low, close 를 나타내므로 결과는 주어진 답변과 달리 분단위 표시하는 것이 좋음
거래시간당 시가, 고가, 저가, 종가를 바로 찾을 수 있게 dictionary 로 구현
단위시간이 늘어나면 KeyError exception 처리를 하여 log 가 늘어나더라도 처리할 수 있도록 함. 따라서 분단위가 올라가는 첫시점에는 시가가 고가, 저가, 종가를 모두 기록하게 됨
import re, os
log = open(os.path.join(os.getcwd(), 'trade.log'))
lines = log.readlines()
ohlc = {}
for line in lines:
line_list = re.split("[:,]", line)
line_time = int(line_list[0])
line_price = int(line_list[2])
try:
ohlc[line_time]['close'] = line_price
if line_price > ohlc[line_time]['high']:
ohlc[line_time]['high'] = line_price
elif line_price < ohlc[line_time]['low']:
ohlc[line_time]['low'] = line_price
except KeyError: # 분단위 첫 거래의 log 등록
ohlc[line_time] = {'open': line_price, 'high': line_price, 'low': line_price, 'close': line_price}
print(ohlc)
결과
>>> print(ohlc)
{1: {'close': 1090, 'high': 1170, 'low': 1090, 'open': 1100}, 2: {'close': 1190, 'high': 1210, 'low': 1030, 'open': 1030}, 3: {'close': 1100, 'high': 1120, 'low': 1100, 'open': 1120}, 4: {'close': 1000, 'high': 1090, 'low': 1000, 'open': 1090}}
>>> print(ohlc[2]['high']) # 2분대거래의 고가?
1210
요즘 들어 Queue를 자주 쓰네요 샘플 데이터를 만든 후에 차례로 처리했습니다. 처리 부분보다 초기화, 출력 코딩이 대부분이네요
그런데 비교 함수를 쓴다고 메모리 문제가 발생한다는 게 조금 의아합니다
메모리에 올라간 데이터들은 어차피 참조 방식으로 비교할 테고, 몇몇 Sort 알고리즘처럼 추가적인 메모리가 필요하지 않거든요
어쨋든, 500개의 데이타 샘플을 출력해봤습니다. 랜덤으로 초를 증가시키고, 가격도 1000을 기준으로 +- 250을 랜덤으로 주었습니다
struct Data
{
public DateTime Time;
public int Price;
}
static void Main()
{
const int SAMPLE = 500;
int time = 0, price = 0, minute = -1;
Random rnd = new Random();
Queue<Data> dataList = new Queue<Data>();
List<int> open = new List<int>();
List<int> high = new List<int>();
List<int> low = new List<int>();
List<int> close = new List<int>();
List<int> count = new List<int>();
for (int i = 0; i < SAMPLE; i++)
{
time += rnd.Next(0, 6);
price = 1000 + rnd.Next(-250, 250);
dataList.Enqueue(new Data() { Time = new DateTime().AddSeconds(time), Price = price });
}
while (dataList.Count > 0)
{
var data = dataList.Dequeue();
if (minute < data.Time.Minute)
{
minute = data.Time.Minute;
open.Add(data.Price);
high.Add(data.Price);
low.Add(data.Price);
close.Add(data.Price);
count.Add(1);
}
else
{
if (high[minute] < data.Price) high[minute] = data.Price;
if (low[minute] > data.Price) low[minute] = data.Price;
close[minute] = data.Price;
count[minute]++;
}
}
Console.Write("{0,15}{1,6}{2,6}{3,6}{4,6}{5,6}", "minute", "open", "high", "low", "close", "nData");
Console.WriteLine();
for (int i = 0; i < minute + 1; i++)
{
Console.Write("{0,15}", string.Format("{0:00}:00 ~ {1:00}:00", i, i + 1));
Console.Write("{0,6}", open[i]);
Console.Write("{0,6}", high[i]);
Console.Write("{0,6}", low[i]);
Console.Write("{0,6}", close[i]);
Console.Write("{0,6}", count[i]);
Console.WriteLine();
}
}
minute open high low close nData
00:00 ~ 01:00 850 1183 750 1183 23
01:00 ~ 02:00 1125 1222 798 911 24
02:00 ~ 03:00 992 1237 768 884 25
03:00 ~ 04:00 862 1166 777 1161 23
04:00 ~ 05:00 1137 1216 755 755 28
05:00 ~ 06:00 961 1238 766 970 31
06:00 ~ 07:00 1010 1245 763 1147 24
07:00 ~ 08:00 995 1169 769 819 21
08:00 ~ 09:00 853 1246 754 774 22
09:00 ~ 10:00 1228 1232 788 798 26
10:00 ~ 11:00 791 1222 771 912 23
11:00 ~ 12:00 1027 1232 774 815 25
12:00 ~ 13:00 886 1239 758 910 23
13:00 ~ 14:00 837 1182 756 1095 21
14:00 ~ 15:00 811 1206 769 1048 26
15:00 ~ 16:00 1201 1235 752 1112 21
16:00 ~ 17:00 1188 1236 777 938 19
17:00 ~ 18:00 1148 1234 767 1078 19
18:00 ~ 19:00 1025 1247 854 1048 24
19:00 ~ 20:00 1150 1225 784 1199 23
20:00 ~ 21:00 854 1246 754 885 27
21:00 ~ 22:00 932 1147 932 1147 2
계속하려면 아무 키나 누르십시오 . . .
제가 출제하신분의 의도를 알아채지못하고 엉뚱한 코드를 작성하는 바람에
문제를 수정하는 수고로움을 끼쳐드렸네요. 죄송합니다.^^;;
일단 자료를 화일로 저장해서 한줄씩 읽어서 처리했구요,
지정한 4개의 리스트외에는 리스트를 사용하지 않았습니다.
메모리는 최소한도로 사용했습니다.
이번 풀이는 hana11님의 의도에 맞는거죠? ㅎㅎ
open=[];high=[];low=[];close=[]
prev_t=''
for line in file('s498.txt'):
t,p=line.split(', ');p=int(p)
if not prev_t or prev_t[:-3]!=t[:-3]:
open.append(p)
high.append(p)
low.append(p)
close.append(p)
if p>high[-1] : high[-1] = p
if p<low[-1] : low[-1] = p
close[-1]=p
prev_t = t
print open
print high
print low
print close
파이썬 2.7.6입니다.
data='''\
1, 1100
2, 1170
3, 1090
4, 1030
5, 1110
6, 1150
7, 1210
8, 1190
9, 1120
10, 1100
11, 1090
12, 1080
13, 1050
14, 1020
15, 1000'''
d = [int(x.split()[1]) for x in data.split('\n') if x] #if x 는 빈줄때문에 삽입
open=[];high=[];low=[];close=[]
while d:
i=0
tmp=[]
while d and i<5:tmp.append(d.pop(0));i+=1#5개씩 가져와서 tmp에 넣음
open.append(tmp[0])
high.append(max(tmp))
low.append(min(tmp))
close.append(tmp[-1])
print 'open=',open
print 'high=',high
print 'low=',low
print 'close=',close
var open : Dictionary
let componentSepa = input.componentsSeparatedByString("\n")
for line in componentSepa {
let componentHour = line.componentsSeparatedByString(":").first
let componentValue = line.componentsSeparatedByString(", ").last
if(componentHour == "") {
continue
}
//open.
if nil == open[componentHour!] {
open[componentHour!] = componentValue
low[componentHour!] = componentValue
high[componentHour!] = componentValue
}
//close
close[componentHour!] = componentValue
//low
if low[componentHour!] > componentValue {
low[componentHour!] = componentValue
}
//high
if high[componentHour!] < componentValue {
high[componentHour!] = componentValue
}
}
let sortOpen = open.sort { (obj1, obj2) -> Bool in
return obj1.0 < obj2.0
}
let sortClose = close.sort { (obj1, obj2) -> Bool in
return obj1.0 < obj2.0
}
let sortHigh = high.sort { (obj1, obj2) -> Bool in
return obj1.0 < obj2.0
}
let sortLow = low.sort { (obj1, obj2) -> Bool in
return obj1.0 < obj2.0
}
//output
for seq in sortOpen.enumerate() {
print("open hour(\(seq.element.0)) : \(seq.element.1)")
}
for seq in sortClose.enumerate() {
print("close hour(\(seq.element.0)) : \(seq.element.1)")
}
for seq in sortHigh.enumerate() {
print("high hour(\(seq.element.0)) : \(seq.element.1)")
}
for seq in sortLow.enumerate() {
print("low hour(\(seq.element.0)) : \(seq.element.1)")
}
Ruby
거래값 1개를 받으면 {분=>[o,l,h,c]} 해쉬를 생성. 분에 해당하는 해쉬가 있으면 lhc값 업데이트. 가장 윗줄 enq[해쉬,분,가격]이 로직. 나머지는 입출력.
enq = ->q,m,v { q[m]? q[m][1,3]=[*[*q[m][1,2],v].minmax,v] : q[m]=[*[v]*4]; q }
olhc = ->s { s.reduce({}) {|q,e| min,_,price=e.scan(/\w+/); enq[q,min,price.to_i] } }
agg_olhc = ->stocks { %w(open low high close).zip(olhc[stocks].values.transpose) }
out_olhc = ->str { agg_olhc[str].each {|tag,prices| puts "#{tag} = #{prices}" } }
Test
stocks_str = ["1:02, 1100", "1:20, 1170", "1:59, 1090", "2:30, 1030", "2:31, 1110", "2:42, 1150", "2:55, 1210", "2:56, 1190", "3:02, 1120", "3:09, 1100", "4:15, 1090", "4:20, 1080", "4:55, 1050", "4:56, 1020", "4:57, 1000"]
tagged_olhc = [["open", [1100, 1030, 1120, 1090]], ["low", [1090, 1030, 1100, 1000]], ["high", [1170, 1210, 1120, 1090]], ["close", [1090, 1190, 1100, 1000]]]
expect(agg_olhc[stocks_str]).to eq tagged_olhc
Output
#=> out_olhc[stocks_str]
open = [1100, 1030, 1120, 1090]
low = [1090, 1030, 1100, 1000]
high = [1170, 1210, 1120, 1090]
close = [1090, 1190, 1100, 1000]
open=[];high=[];low=[];close=[] prev_t='' for line in file('s498.txt'): t,p=line.split(', ');p=int(p) if not prev_t or prev_t[:-3]!=t[:-3]: open.append(p) high.append(p) low.append(p) close.append(p) if p>high[-1] : high[-1] = p if p<low[-1] : low[-1] = p close[-1]=p prev_t = t
print open print high print low print close
입력을 파싱하는 부분,
파싱된 정보를 각 분 단위로 비교/업데이트하는 부분
분단위로 생성된 결과를 수집하는 부분
최종 결과를 출력하는 부분을 각각 코루틴으로 만들어서
쓸데없이 길게 구현해보았습니다.
파이썬 3.5 입니다.
import re
def coroutine(fn):
def inner(*a, **b):
r = fn(*a, **b)
next(r)
return r
return inner
@coroutine
def printer():
while True:
data = (yield)
if data:
for k, v in data.items():
print("{} = {}".format(k, v[1:]))
@coroutine
def acc(target=None):
data = dict(open=[], close=[], high=[], low=[])
while True:
input_ = (yield)
if not input_:
break
vopen, vclose, vhigh, vlow = input_
data['open'].append(vopen)
data['close'].append(vclose)
data['high'].append(vhigh)
data['low'].append(vlow)
if target:
target.send(data)
@coroutine
def updater(target=None):
current_min = -1
vhigh, vlow, vopen, vclose = 0, 0, 0, 0
continue_ = True
while continue_:
input_ = (yield)
if input_ is None:
continue_ = False
else:
minute, _, value = input_
print(minute, current_min, continue_)
if continue_ is False or minute != current_min:
if target:
target.send((vopen, vclose, vhigh, vlow))
vopen, vclose, vhigh, vlow = value, value, value, value
current_min = minute
else:
vhigh = value if value > vhigh else vhigh
vlow = value if value < vlow else vlow
vclose = value
if target:
target.send(None)
@coroutine
def parser(target=None):
pat = re.compile(r'(\d{1,2}):(\d{1,2}), (\d+)')
while True:
data = (yield)
m = pat.match(data)
result = [int(x) for x in m.groups()] if m is not None else None
if target:
target.send(result)
if not result:
break
def main():
process = parser(updater(acc(printer())))
try:
while True:
line = input()
process.send(line)
if not line:
break
except:
pass
main()
data=[
'1:02, 1100',
'1:20, 1170',
'1:59, 1090',
'2:30, 1030',
'2:31, 1110',
'2:42, 1150',
'2:55, 1210',
'2:56, 1190',
'3:02, 1120',
'3:09, 1100',
'4:15, 1090',
'4:20, 1080',
'4:55, 1050',
'4:56, 1020',
'4:57, 1000',
]
o=[]
h=[]
l=[]
c=[]
wm=-1;
for d in data:
dl = d.split(',')
v = int(dl[1].strip())
m = int(dl[0].split(":")[0].strip())
if wm != m:
o.append(v)
h.append(v)
l.append(v)
c.append(v)
wm = m
if h[-1] < v:
h[-1] = v
if l[-1] > v:
l[-1] = v
c[-1] = v
print("open = {}".format(o))
print("higt = {}".format(h))
print("low = {}".format(l))
print("close = {}".format(c))
Python 3.5.2에서 작성하였습니다.
tmp = '''1:02, 1100
1:20, 1170
1:59, 1090
2:30, 1030
2:31, 1110
2:42, 1150
2:55, 1210
2:56, 1190
3:02, 1120
3:09, 1100
4:15, 1090
4:20, 1080
4:55, 1050
4:56, 1020
4:57, 1000'''.split('\n')
o,h,l,c = list(),list(),list(),list()
high_1, low_1, step = 0,0,0
value = [x.split(', ')[1] for x in tmp]
m = [x.split(':')[0] for x in tmp]
for x in range(len(m)):
if step != int(m[x]):
step = int(m[x])
high_1 = value[x]
low_1 = value[x]
o.append(value[x])
elif high_1 < value[x]:
high_1 = value[x]
elif low_1 >= value[x]:
low_1 = value[x]
if len(m)-1 == x or step != int(m[x+1]):
h.append(high_1)
l.append(low_1)
c.append(value[x])
print('open =',o)
print('high =',h)
print('low =',l)
print('close =',c)
#### 2017.01.24 D-394 ####
앞뒤 비교해서 풀으라는게 무슨말인지 이해못해서 그냥 풀었습니다 허허헣...
분, 초, 가격의 데이터 array와 각 분마다 어디까지 위치하는지 알려주는 int[] index를 만들어 open,close는 맨 앞과 뒤, high와low는 첫번째부터 시작해서 다음것을 비교해가며 구하도록 만들었습니다.
package sss;
import java.util.ArrayList;
public class Candlestick {
class Data{
int minute, second, price;
public Data(int minute, int second, int price){
this.minute=minute;
this.second=second;
this.price=price;
}
}
ArrayList<Data> data = new ArrayList<Data>();
int index[];
public Candlestick(){
data.add(new Data(1,2,1100));data.add(new Data(1,20,1170));data.add(new Data(1,59,1090));
data.add(new Data(2,30,1030));data.add(new Data(2,31,1110));data.add(new Data(2,42,1150));
data.add(new Data(2,55,1210));data.add(new Data(2,56,1190));data.add(new Data(3,2,1120));
data.add(new Data(3,9,1100));data.add(new Data(4,15,1090));data.add(new Data(4,20,1080));
data.add(new Data(4,55,1050));data.add(new Data(4,56,1020));data.add(new Data(4,57,1000));
}
void set_index(){
index = new int[data.get(data.size()-1).minute];
for(int i=0;i<data.size();i++)
index[data.get(i).minute-1]++;
for(int i=0;i<index.length-1;i++)
index[i+1]+=index[i];
}
void ohlc_open(){
int open=0;
System.out.print("[");
for(int i=0,open_index=0;i<index.length;open_index=index[i++]){
open = data.get(open_index).price;
System.out.print(open + " ");
}
System.out.print("]");
}
void ohlc_high(){
int high=0;
System.out.print("[");
for(int i = 0, first=0,last=0; i < index.length;i++){
first=last; last=index[i];
while(first < last){
if(high < data.get(first).price)
high = data.get(first).price;
first
++;
}
System.out.print(high + " ");
high = 0;
}
System.out.print("]");
}
void ohlc_low(){
int low=data.get(0).price;
System.out.print("[");
for(int i = 0, first=0,last=0; i < index.length;i++){
first=last; last=index[i];
while(first < last){
if(low > data.get(first).price)
low = data.get(first).price;
first++;
}
System.out.print(low + " ");
low=999999999;
}
System.out.print("]");
}
void ohlc_close(){
int close=0;
System.out.print("[");
for(int i=0,close_index=0; i<index.length; i++){
close_index = index[i]-1;
close = data.get(close_index).price;
System.out.print(close+" ");
}
System.out.print("]");
}
}
문제가 이해 안 가서 한참 들여다봤네요.
open, high, low, close = [], [], [], []
M = 0
pp = 0
for line in data.split('\n'):
t, p = line.split(',')
m, p = t.split(':')[0], int(p)
if M != m:
if pp: close.append(pp)
open.append(p)
high.append(p)
low.append(p)
M = m
else:
high[-1] = max(high[-1], p)
low[-1] = min(low[-1], p)
pp = p
close.append(pp)
print(open)
print(high)
print(low)
print(close)
def ohlc(d):
tmp=d
start=int(tmp[0].split(':')[0])
o=[]
h=[]
l=[]
c=[]
def inner(s, t, o0, h0, l0, c0):
tmpp=[]
while int(t[0].split(':')[0])==s:
tmpp.append(t.pop(0).split(', ')[1])
if not t: break
if tmpp:
o0.append(tmpp[0])
h0.append(max(tmpp))
l0.append(min(tmpp))
c0.append(tmpp[-1])
else:
o0.append('-')
h0.append('-')
l0.append('-')
c0.append('-')
if not t: return({'open':o0, 'high':h0, 'low':l0, 'close':c0})
else: return(inner(s+1, t, o0, h0, l0, c0))
return(inner(start, tmp, o, h, l, c))
data=[
'1:02, 1100',
'1:20, 1170',
'1:59, 1090',
'2:30, 1030',
'2:31, 1110',
'2:42, 1150',
'2:55, 1210',
'2:56, 1190',
'3:02, 1120',
'3:09, 1100',
'4:15, 1090',
'4:20, 1080',
'4:55, 1050',
'4:56, 1020',
'4:57, 1000']
sol=ohlc(data)
print('''
open = {}
high = {}
low = {}
close = {}'''.format(sol['open'],sol['high'],sol['low'],sol['close']))
파이썬 3.6
data = [['1:02', '1100'],['1:20', '1170'],['1:59', '1090'],['2:30', '1030'],['2:31', '1110'],['2:42', '1150'],['2:55', '1210'],['2:56', '1190'],['3:02', '1120'],['3:09', '1100'],['4:15', '1090'],['4:20', '1080'],['4:55', '1050'],['4:56', '1020'],['4:57', '1000']]
Open,High,Low,Close,time,timelist = [],[],[],[],[],[]
for i,value in enumerate(data):
time = value[0].split(':')
timelist.append(time)
if i == 0:
Open.append(int(value[1]))
High.append(int(value[1]))
Low.append(int(value[1]))
Close.append(int(value[1]))
elif timelist[i-1][0] == timelist[i][0]:
if value[1] > data[i-1][1]:
High[-1] = int(value[1])
elif value[1] < data[i-1][1]:
Low[-1] = int(value[1])
if i == len(data)-1:
Close[-1] = int(value[1])
else:
Open.append(int(value[1]))
High.append(int(value[1]))
Low.append(int(value[1]))
Close.append(int(value[1]))
Close[-2] = int(data[i-1][1])
print("open =",Open)
print("high =",High)
print("low =",Low)
print("close =",Close)
open = [1100, 1030, 1120, 1090]
high = [1170, 1210, 1120, 1090]
low = [1090, 1190, 1100, 1000]
close = [1090, 1190, 1100, 1000]
앞뒤 비교하지 말라는 말은 메모리를 아낄 수 있도록 min/max를 쓰지 말라는 거죠?
# 파이썬
input_sample = [
'1:02, 1100',
'1:20, 1170',
'1:59, 1090',
'2:30, 1030',
'2:31, 1110',
'2:42, 1150',
'2:55, 1210',
'2:56, 1190',
'3:02, 1120',
'3:09, 1100',
'4:15, 1090',
'4:20, 1080',
'4:55, 1050',
'4:56, 1020',
'4:57, 1000',
]
def ohlc(data, n=1, pre_min=0, pre_price=65536, o=[], h=[], l=[], c=[]):
min = int(data[n][0])
price = int(data[n].split()[1])
if pre_min < min:
o.append(price)
h.append(price)
l.append(price)
if pre_price != 65536:
c.append(pre_price)
else:
if price > h[-1]:
h[-1] = price
if price < l[-1]:
l[-1] = price
n += 1
if n == len(data):
c.append(price)
return o, h, l, c
pre_min = min
pre_price = price
return ohlc(data, n, pre_min, pre_price, o, h, l, c)
print(ohlc(input_sample))
def ohlc(a):
index_open = [0]
index_close = [len(a)-1]
for i in range(len(a)-1):
if a[i][0][0] < a[i+1][0][0]:
index_open.append(i+1)
index_close.append(i)
index_open.sort()
open = [a[i][1] for i in index_open]
index_close.sort()
close = [a[i][1] for i in index_close]
high = list()
low = list()
for i in range(len(index_open)):
b = sorted(a[index_open[i]:index_close[i]+1], key = lambda x: x[1])
low.append(b[0][1])
high.append(b[-1][1])
return open, high, low, close
l = list()
while 1:
n = input()
if n == '':
break
m = int(input())
l.append([n,m])
print(ohlc(l))
trade_info="""1:02, 1100
1:20, 1170
1:59, 1090
2:30, 1030
2:31, 1110
2:42, 1150
2:55, 1210
2:56, 1190
3:02, 1120
3:09, 1100
4:15, 1090
4:20, 1080
4:55, 1050
4:56, 1020
4:57, 1000"""
open=[]
high=[]
low=[]
close=[]
trade_info_list=trade_info.split('\n')
for k in range(24):
info_list=[]
info_value=[]
for info in trade_info_list:
num=''
for character in info:
if character==':':
break
num+=character
if str(k)==num:
info_list.append(info)
elif str(k)!=num:
continue
if len(info_list)!=0:
for info in info_list:
location=info.index(',')
info_value.append(info[location+2:])
open.append(info_value[0])
close.append(info_value[-1])
high.append(max(info_value))
low.append(min(info_value))
print(open)
print(high)
print(low)
print(close)
Python
n = 15
open = list()
high = list()
low = list()
close = list()
tmp_list = list()
info = dict()
min_minute = max_minute = 0
for i in range(n):
time, price = input().split(", ")
minute = int(time.split(":")[0])
info[time] = price
if i == 0:
min_minute = minute
max_minute = minute
else:
min_minute = min(min_minute, minute)
max_minute = max(max_minute, minute)
c_info = [[] for i in range(max_minute-min_minute+1)]
for t in info.keys():
c_info[int(t.split(":")[0])-min_minute].append(info[t])
#print(c_info)
for i in c_info:
print(i)
print(i[0])
open.append(i[0])
high.append(max(i))
low.append(min(i))
close.append(i[-1])
print(open)
print(high)
print(low)
print(close)
sample = ['1:02', 1100,'1:20', 1170,'1:59', 1090,'2:30', 1030,'2:31', 1110,'2:42', 1150,'2:55', 1210,'2:56', 1190,'3:02', 1120,'3:09', 1100,'4:15', 1090,'4:20', 1080,'4:55', 1050,'4:56', 1020,'4:57', 1000]
oldtime,tmp = '0',[]
o,h,l,c = [],[],[],[]
for i in range(len(sample)):
if not i&1:
time = sample[i].split(':')[0]
if tmp and (time > oldtime or i == len(sample)-2):
if i == len(sample)-2: tmp.append(sample[i+1])
o.append(tmp[0])
h.append(max(tmp))
l.append(min(tmp))
c.append(tmp[-1])
tmp.clear()
oldtime = time
tmp.append(sample[i+1])
print('open = {}\nhigh = {}\nlow = {}\nclose = {}'.format(o,h,l,c))
C#
LINQ - GroupBy (key = 분)
using System;
using System.Collections.Generic;
using System.Linq;
namespace CD100
{
class Program
{
static void Main()
{
// 입력 자료 구성
StockValue[] sampleData =
{
new StockValue("1:02, 1100"), new StockValue("1:20, 1170"), new StockValue("1:59, 1090"),
new StockValue("2:30, 1030"), new StockValue("2:31, 1110"), new StockValue("2:42, 1150"),
new StockValue("2:55, 1210"), new StockValue("2:56, 1190"), new StockValue("3:02, 1120"),
new StockValue("3:09, 1100"), new StockValue("4:15, 1090"), new StockValue("4:20, 1080"),
new StockValue("4:55, 1050"), new StockValue("4:56, 1020"), new StockValue("4:57, 1000")
};
// 입력 자료 정렬 후, 분에 따라 데이터 그룹화: (key = 분, 해당 분에 속하는 StockValue 인스턴스들)
var filterByMin = sampleData.OrderBy(sv => sv.Minute).ThenBy(sv => sv.Second)
.GroupBy(grp => grp.Minute);
var open = new List<int>();
var high = new List<int>();
var low = new List<int>();
var close = new List<int>();
foreach (var record in filterByMin) // 각 key(분) 별로
{
open.Add(record.First().Price); // 인스턴스 첫 값의 가격
high.Add(record.Select(sv => sv.Price).Max()); // 인스턴스 가격 컬렉션의 최대값
low.Add(record.Select(sv => sv.Price).Min()); // 인스턴스 가격 컬렉션의 최소값
close.Add(record.Last().Price); // 인스턴스 마지막 값의 가격
}
// 결과 출력
Console.WriteLine($"open = [{string.Join(", ", open)}]");
Console.WriteLine($"high = [{string.Join(", ", high)}]");
Console.WriteLine($"low = [{string.Join(", ", low)}]");
Console.WriteLine($"close = [{string.Join(", ", close)}]");
}
}
class StockValue
{
public int Minute { get; } = 0;
public int Second { get; } = 0;
public int Price { get; } = 0;
public StockValue(string aRecord) // "분:초, 가격" 문자열로부터 인스턴스 생성
{
string[] splitedRecord = aRecord.Split(',');
Price = int.Parse(splitedRecord[1]);
int[] recordTime = splitedRecord[0].Split(':').Select(s => int.Parse(s)).ToArray();
Minute = recordTime[0];
Second = recordTime[1];
}
}
}
chart = dict()
with open ('ohlc.txt', 'r') as file:
lines = file.readlines()
for i in lines:
x, y = tuple(i.split(', '))
chart.setdefault(x, int(y.strip('\n')))
def to_second(time):
mi, se = map(int, time.split(':'))
second = mi * 60 + se
return second
def open_p(chart):
seq = 1
result = []
for i in chart.keys():
if to_second(i) // 60 == seq:
seq += 1
result.append(chart.get(i))
return result
def high_p(chart):
seq = 1
result = []
temp = 0
for i in chart.keys():
if to_second(i) // 60 == seq:
if temp < chart.get(i):
temp = chart.get(i)
else:
result.append(temp)
temp = chart.get(i)
seq += 1
result.append(temp)
return result
def low_p(chart):
seq = 1
result = []
temp = 0
for i in chart.keys():
if to_second(i) // 60 == seq:
if temp == 0:
temp = chart.get(i)
elif temp > chart.get(i):
temp = chart.get(i)
else:
result.append(temp)
temp = chart.get(i)
seq += 1
result.append(temp)
return result
def close_p(chart):
temp = []
seq = 1
result = []
for i in chart.keys():
if to_second(i) // 60 == seq:
temp.append(chart.get(i))
elif to_second(i) // 60 != seq:
seq += 1
result.append(temp[-1])
temp.clear()
result.append(temp[-1])
return result
print(open_p(chart))
print(high_p(chart))
print(low_p(chart))
print(close_p(chart))
import java.util.ArrayList;
public class 주식차트를위한ohlc데이터만들기 {
public static void main(String[] args) {
String[] times = {"1:02","1:20","1:59","2:30","2:31","2:42","2:55",
"2:56","3:02","3:09","4:15","4:20","4:55","4:56","4:57"};
int[] tradingPrice = {1100,1170,1090,1030,1110,1150,1210,1190,1120,
1100,1090,1080,1050,1020,1000};
ArrayList<Integer> open = new ArrayList<Integer>();
ArrayList<Integer> high = new ArrayList<Integer>();
ArrayList<Integer> low = new ArrayList<Integer>();
ArrayList<Integer> close = new ArrayList<Integer>(); //리스트 4개 생성
ArrayList<Integer> minute = new ArrayList<Integer>(); //times에 있는 시간들을 분만 따로 모을 리스트 생성
for(int i=0; i<times.length; i++) {
String[] str = times[i].split(":");
minute.add(Integer.parseInt(str[0]));
}
open.add(tradingPrice[0]);
int biggest = tradingPrice[0];
int lowest = tradingPrice[0];
for(int i = 0; i<minute.size()-1; i++) {
if(minute.get(i)==minute.get(i+1)) {
if(tradingPrice[i+1]>=biggest) {
biggest = tradingPrice[i+1];
}
if(tradingPrice[i+1]<=lowest) {
lowest = tradingPrice[i+1];
}
}
else {
high.add(biggest);
low.add(lowest);
close.add(tradingPrice[i]);
open.add(tradingPrice[i+1]);
biggest = tradingPrice[i+1];
lowest = tradingPrice[i+1];
}
}
high.add(biggest);
low.add(lowest);
close.add(tradingPrice[times.length-1]);
System.out.println(open);
System.out.println(high);
System.out.println(low);
System.out.println(close);
}
}
data = ['1:02, 1100',
'1:20, 1170',
'1:59, 1090',
'2:30, 1030',
'2:31, 1110',
'2:42, 1150',
'2:55, 1210',
'2:56, 1190',
'3:02, 1120',
'3:09, 1100',
'4:15, 1090',
'4:20, 1080',
'4:55, 1050',
'4:56, 1020',
'4:57, 1000']
init_time = 1
value_list =[]
o = []
h = []
l = []
c = []
for i in range(len(data)):
split_data = data[i].split(",")
split_time = split_data[0].split(":")
min = int(split_time[0])
value = int(split_data[1])
# print(min,value)
if min == init_time:
value_list.append(value)
else :
o.append(value_list[0])
c.append(value_list[-1])
value_list.sort()
h.append(value_list[-1])
l.append(value_list[0])
del value_list[:]
init_time = min
value_list.append(value)
o.append(value_list[0])
c.append(value_list[-1])
value_list.sort()
h.append(value_list[-1])
l.append(value_list[0])
print("Open : ",o)
print("High : ",h)
print("Low : ",l)
print("Close : ",c)
from _collections import defaultdict
re_data = defaultdict(list)
for d in data:
temp = d.split(':')
re_data[temp[0]].append(d.split(', ')[1])
open = []
high = []
low = []
close = []
for price in re_data.values():
open.append(price[0])
high.append(max(price))
low.append(min(price))
close.append(price[-1])
print('open = {}\nhigh = {}\nlow = {}\nclose = {}'.format(open, high, low, close))
o = []
h = []
l = []
c = []
_high = 0
_low = 0
_starter = 0
f = open('_79.txt', 'r')
lines = f.readlines()
for line in lines:
t = line.split(',')[0]
p = line.split(',')[1].strip()
_min = t.split(':')[0]
if lines.index(line) == 0 :
_min_before = _min
o.append(int(p))
_high = int(p)
_low = int(p)
else:
_min_before = lines[lines.index(line) - 1].split(',')[0].split(':')[0]
_sec = t.split(':')[1]
if _min == _min_before:
if int(p) > _high: _high = int(p)
if int(p) < _low: _low = int(p)
else:
o.append(int(p))
c.append(int(lines[lines.index(line) - 1].split(',')[1].strip()))
h.append(_high)
_high = int(p)
l.append(_low)
_low = int(p)
if lines.index(line) == (len(lines) - 1) :
c.append(int(p))
h.append(_high)
l.append(_low)
f.close()
print(o,h,l,c)
date = '''1:02, 1100
1:20, 1170
1:59, 1090
2:30, 1030
2:31, 1110
2:42, 1150
2:55, 1210
2:56, 1190
3:02, 1120
3:09, 1100
4:15, 1090
4:20, 1080
4:55, 1050
4:56, 1020
4:57, 1000'''.splitlines()
list = []
open = []
high = []
low = []
close= []
for i in date:
x,y = ''.join(i[:1].split(':')),i.split(',')[1]
list.append(f'{x}{y}')
c = 1
while c<int(x)+1:
l= []
for i in list:
if i[0] == str(c) : l.append(i)
open.append(l[0][-4:])
high.append(max(l)[-4:])
low.append(min(l)[-4:])
close.append(l[-1][-4:])
c+=1
print(open)
print(high)
print(low)
print(close)
#codingdojing_ohlc_stock
'''
분:초, 거래가격
1:02, 1100
1:20, 1170
1:59, 1090
2:30, 1030
2:31, 1110
2:42, 1150
2:55, 1210
2:56, 1190
3:02, 1120
3:09, 1100
4:15, 1090
4:20, 1080
4:55, 1050
4:56, 1020
4:57, 1000
'''
#1분 단위로 잘라보자.
open_list = []
high_list = []
low_list = []
close_list = []
io = True
_min = ''
high = ''
low = ''
while io:
io = input()
if io:
time, value = io.split(',')
else: #last
high_list.append(high)
low_list.append(low)
close_list.append(close)
#같은 거래시각
if _min == '': #첫 시작
_min = time.split(':')[0]
high = eval(value)
low = eval(value)
close = eval(value)
open_list.append(eval(value))
elif _min == time.split(':')[0]: #still same minute
high = max(high, eval(value))
low = min(low, eval(value))
close = eval(value)
else: #next minute
_min = time.split(':')[0]
high_list.append(high)
low_list.append(low)
close_list.append(close)
open_list.append(eval(value))
high = eval(value)
low = eval(value)
print(f'''open = {open_list}
high = {high_list}
low = {low_list}
close = {close_list}''')
앞 뒤 데이터를 비교하다.. 지져분 해졌네요.
data=[
('1:02', 1100),
('1:20', 1170),
('1:59', 1090),
('2:30', 1030),
('2:31', 1110),
('2:42', 1150),
('2:55', 1210),
('2:56', 1190),
('3:02', 1120),
('3:09', 1100),
('4:15', 1090),
('4:20', 1080),
('4:55', 1050),
('4:56', 1020),
('4:57', 1000),]
open = []
high = []
low = []
close = []
nowminute = 0
nowhigh = 0
nowlow = 0
now = 0
for i in data:
if int(i[0].split(':')[0]) > nowminute:
open.append(i[1])
high.append(nowhigh)
low.append(nowlow)
close.append(now)
nowminute = int(i[0].split(':')[0])
nowhigh = i[1]
nowlow = i[1]
elif int(i[0].split(':')[0]) == nowminute:
if i[1] > nowhigh:
nowhigh = i[1]
elif i[1] < nowlow:
nowlow = i[1]
now = i[1]
high.append(nowhigh)
low.append(nowlow)
close.append(now)
del high[0]
del low[0]
del close[0]
print('open =',open)
print('high =',high)
print('low =',low)
print('close =',close)