0101101001001010101010111111011001010000100100010111110101011101100000011001000010110000111001111111100100011100001010100110000001111011011101101100010000000010110111110100010010101001000110000001111101100111011110101001000100010011110100100101101000000010011011101100100011110101000010000111011000101111101101101000001010011110000101010000000111011111001010011001011010111001000100101001101110011101 0010110111000001000101101111001010001000011000010010010100001001101010000011110000011000000101000011110100101101111101111110011001000000101000000101111010000101001011100000101111011000010111001011100010001011000010001000111000111101011010001000010110011100011011111000100000110111110111010001000101111001110110111010011111100010001011001111011110001001100101101110111101011000011000110101011110100001 1111000010100000100001100001100000010111001000000010100010010010111100100101011110011000000100010110001000100011001100110111110011101111010101011000010111001010100001001111001100010001101000010011000100100011001001010100111010110000110000100000101010010111011001000010011111011000011111101011110100111110011101100010000001000000001000010010011011000110101111111001111001010010010101110111110011111010 0011110011100000001010110000001001101011111111110101001110001101011000100011000001001100101110010011001100100110101010101000101001010000111100100101010111111000110100000010011110101101000011011000101011000111111111001011101001111111011110110101100111011001101000011010110000011100111010101011101010001110111011101010011101010010111001010000010101100111111100000101011111101110000100110111101001110011 0000100101101011110100010000011011001000101000110101000100100111100001101011000101100110100110111100101110000011000011000111001101100101010101111011111100001100000011011001100110011011001000000010110100010101101010101100000001111010000111110010110010000010011001100000100111100011011101010111010110100100101101110011010001100011101000101110011111111100100010101101010001101100111001010111101101001011 0110100111110000111010101010001011111001110011011001010100010010101000100100011001111000111111110010110110000000010110010111100011110101110110010001011011101010000101111000010100101010100111011011001100101111011001111101010010110000100001111011010110100001000100001000111110100001110011100101001001110011101010000111001010111001010111100100110011000011000010011011010010000101010100110000011111111101 1101111000111100110010111011100100000001001100110101011101001110110100001111101001011100000100010111110101110010110100111001110100010001001111101000110100110000000000110111100000010010101011011001001110011101101111010101100001111010010010110111011010111000010010010001100001011010101110111011100011101000000101001100101100001101100000000101011000011101111011110101110001001111110010111100011011101100 1010111010111101111110000110111011111100000010100111010010000110000010001011100100000111100010011110100010001110110001011011000011100110100100101101010010011100101100111010000110010001010010100001111111101000101101111111010100001101000110100101100110011010010000101100100101011010100000101010110011011111100110100011001100011101111101000100101111111000000100110000011100111111100010000110000010100100 0010001100001001101111001100000101110101110101011000111001001111011000111010000111000111101100011001101111110110110001000011010101001001000010000000011001110011001100101001110110010011001010111110011111111111100010100101010111111111101011101110001011101011001100010110010111010111101001100010011010101001100100000110101101001010111001100010000100010001101110100001010011001110100010010010111011001011 0111111000001111101011101000111000101100010000100101001000001110111010010010101000011101101011101100110101110010100010011110001101010010100100001011111000111100100001010100011111111000111100000100011100101000000111000011011011011011010101011110111001101010110100000111111010011011000000111000110000100110111111001000010110111110100010100101010100010110001100110011010010100100010111011001011010000001 0100100011100100011011010001010101110001011101101001011001111100000001110110010110011011011001010001010001010110110000100011010101110111010111010100100001010001101110110110011000101001110111110000000010000101111100000110010111111000000000001101001101001011010100001011011101111111010001001011110011011111001010110011111010111011010011111000101010011100110101100011101110011101010010100010001000100101 1011101011101110111100101000011011110000001001111011111110011110100110111100110110100100110111010110000110111010101111100110100000011010110101111001001101110010011100010110111110010001101101111100010000101111100110011110010000011000100001001111010001000110111011000000110010001011100100111010111110101101010101111011100011110101000100100101100111110011100011010000000001110100111100101101011100100000 0010101001111000010000011010111100011010111001101101111101110101011000100010011110111100010000111111010010100110010110000111101000000110110110100101010110001110110000111101011111001110011001111011000110000101010100110110110010100010010101010010010011010111100101000000000111100011110110010110101001000011111000101101110101011100101011000011111100101100001110111111101100101010000000101110001011111001 0011110011011100010000001110011111110000010101110010001010011010001111010011001001011110010000110001100000101010111011110010111101101110011101100111101110110001010110101011100111010001101001111001100111111010110000100010100111010110000001110101001010011001101001000000011010110111101111101001110000000110100010010010111010011010000011111101110100110100011110000000010001000010110100011100010111000000 1111000000001110101101010000001100100100100011011001001011100101101001011001110110010011000000111100001000011000111000100001010101000100110001000101010001001010001011001000001010100110010001000001001110111100011101101011101011011101111001111110010001001000101110100000011000011111000101000100001000011100111000111011101100101010001110111101001011010101100010101101000010110101100110000001010110100100 0001011101111010011000011110001110111011010011010010111101101001010111100011110110111001101000001111011111011100110110110111110001001111011011000010101100101100111010000111010111011100110111101001000011001011011011100001111001000110000100100001111000110010100101011110111100001101000010010111111110101011110010010111111010000110101111000100000000011111000101101010100111011000111101011101000100011101 1010111001011111110100001000100011110010111111000011001101100110010100010010010111100001000100000010100101000110001000011101101100110100000111101100101100101011011101010100100010000011100111011011000001010010101010101010000101110111010111011100011100111010100000101101011011100110000100011011101000000001010001001110101000100100110001100110101100110010111001101001011101001001111010110110011101010001 1100000011110001011111101100010000101111100010101010000011010010101111110111100001001001110100110010011011010101010101000010110111100101011111110000000110010110010001001101000001111100000001100000010100000010111100001100001110001101101011001010000000000010001000110011011111110110100001000110010010101110111111011101101110011010010100001110101110101011110011011100010000001111011001010011011001110110 0110011101110011110001100010000010111010000100101100000000110001001101110011111001111010100011111010111100101001001101101010110101101101000101100001111100001011011101110000101010111000000001001001111011000111110100011011100101000101000110001001101001001111100010111010010110011100101010001101101111100010011001011001010111100100010010001000100100101111111001001110101001010001011010111101100000011011 1110010010001011100000001111000001010100010110001010001111001111000111010100111101111100000101101100110110001001000101000011001100000100000000100111010010000001000101000010001001010100110110111110111101000100101001000011010000011000100100110110111111101110001111001101011011110101100100100110001101011011110101001010101011100001011000110011101011110011101011110110100011001111110101110101001101011001 1100100110111001000001110000001100010010000000010001100011000010010011100100000110011100010101101101011110111011001010010000110010100100101011101111110101001111101001101010111100110100100100111110111011111100100110101001001000010100100010001010010111000001100111111101100111011101000011001010101011111100110100100111100010000101111101101010111101101110011011011000000100111001100000110110111100110001 1010101100111001001001000010100010001100010100010000001001010011110001011011011100101010100010110110000100010111110000101100011101011111001000110101101011000110110110100101011011110011111110001111000011110010110100011010110110000011001010110011010000011101010000001010100110001001010101010110101100111011011011010010110011010001110001111100000100001001110001011100101111000100111111001000110101111111 0000111101010111010000101111011010000000111101111000000000000111111000001111010101001111001000100100111000000111110101101101101011100011111010100110101010010101011001110110101111100110100011001111111011010110101110010111011010010110100000100110110111011001000010100010010111001001110110111000011010010011011001101101110001011110110011110111110010100101011001110000101011000101010000110111010011101111 1010110111111110110001111010010000010110011010011101001000100011010111110111110010100001000101101110000000010100101111000010100111000011100110000000110110111010001100101100000011010001011110111001011101111101100011101010100101111010100011010011001010110100110111100011001111001101101110010001011110010010001111101110001011001111010000100010001101101000111111101011100011001111110101011100101001110101 0011101011000100110011101111001011011101101110100100110101001110110001110111001010010110101000010011101100101011000100100110011000001010000000011000011000110111010011001110011100101011100010100100010010110011000101111110000110011010110101111111011100110100011000001010101010011001101011100110110000010010100101010000100110101101000110110010000110001000011001010111101011001011011000110000111111010101 0011110011110111011011100000000110010110010100101010010001001100101010001111101110000010101101010101110111000011011100000100110011110100011101001101101011001111101011111111110001010001001010001111000101101100101011001110100111011011000101001000110111000010100101111001111010011000011101110110011001011001010111111000000011001111111000011001101000001100011010000010111001001110011000100011000101000011 0010101110111101001011110100111101001110000001010101010110111010000000110101111011100111100111000010100100111011101001000111100001000010111000011011111000100100110101010111110100000011011110110010101010001100000100110110010101000010111010110101101000001110111100000011100001000110001010110010011010100111110000100001010110001010111001110011101011101010010010100110011110000000001110010111110111110001 0101111000110110100111001101001110001000101011101000000100111001111110101010001011111101011111100111000011000001100011101001111001011010100010111010010101111111100000011111010000001010110011100001001100000101111011111111000000100010110110100110000111110101011111011100000101101000110001101111011001101010000000100101111011111111101100011011100110100011110100110101111010011110001111111000111000011100 0000110100110111011000001100001101010010101111010110101111001101010010100111011001011100110100100101111100100010111010111010011011000111100000110011011101111100111110000100000010001111100100001101101111111100100111100011101000111100111101110010111001101111000110110000001110111001011111001001000101010111000100010011011001101101011110001110000010111101100111000001101100101010000000010010110110010001 0010110001011010001110111001011010101100000011100100000100111000101110100010010101011100000011100011100001001001110111110010000001110110111100111100000110001011101100110011011011000100010100111110010001010001011110000100101000000110010100001010100000010011110000000100000000100110010010101100000000011110100100100011111000011010001000000000111001011111011110101010110100110101110110010001001011101000 1100110010010000111111100001100011110100010000101010010011011000100000111101110010100011010010011010110011001010100010110001111001000000100001001101110100010110101100010001111100101000010100011111101011110011101100110111111010110101111011110010000110010000001100101000000110111010001010000111010000010001111100010100001001100111010101110010001001000000010010100010001110010101100100111001111010111111 1101100100111011000110100011111100111011000111010011000000010000101110110010111000110000000111010010001011001011000001101000000001000000000010000011001001011000100110011101101001010100000111011010111110011011011111111011101000110000111000001010111010001100000011011110010110010010100011010010001110111011000000011010101001110010101011010000111001100100001101101010100101001101011111001110100010011011 0101110100110101110001111000110010101100010010110111100111100000110011110101000011000011010111011010011101001001011110111111001111010101101111100011010110011001001001101111101110100100011100110011011100010000001000001100000110111101011100100010011101011101000001101100010000100011000001000010000110111101100110000011110100010110011111101100011101110010101100100010000110101010100110100111011100000101 0000110111110001111001110110111101011110001101001011000001000010110000110101110101011011111101000011011000101001100100100001011011001010000010010101111101100001101100111011110001101110111010000100001011000111100100011100111111101001011100001110110101000001110111001010110011000011101101111011110100111110001111000011100111001010011111111001101110000110100100110110000101011110101001011111101101111101 0111001010100110101110101011010011010011000100100011100010100001110100111100110001001000000100011100001011001110111000011011111111110110000101111000111110111001101011011001001101101000011101011000111011110000110000011100101110100101110001011111101000101010001101111110001101001011110110011000001001010100111101101000000101011010101111000011110011100010110011101100101001001000100000111100010111001000 1110111000101111001110001101010110100100101000100100110010010011111011001011101001110111110010011010111001011011110110111110100111111100101000010011111100100111100100011001110110001110111010111000001111101010001000001010000000010010001101110001011111101010010011010001011001000100100100111001010111101110111011011010010110001100110101000101000101000111111111111110110001001001110001000110110111001000 1000100010011000000100010100000001000011101001101101001011110010011111011101101100110010011010100000001101000001100010100101111111011000101101000101110111001110111011010111110010101110011001110110010010000000010100001111100010111011110111011100001111010011010101001110011001010010110111110000110111010111101110110000110111001001010011111100011111000101110101000001111101001100110000000111010100101100 0010100011110011000110111000110111110000001111010101001111101101110000101011011101101101011101110000110001100100011011010111010000011101011010100110100000011001001010111100111110010101001100000101110110101001000011000010100111011111010111000000010110011010101100011010111101111111011110001001110010001100100010110010001010100001110010001000011101010011001110110010011010110010111000101001001001101010 0101100111011010011011011111101000001011110101101101101101000111010001010001111001111000011010001001101011101101110010000101000011010011111100001010000001111111010111011110001001101010001011011011101011000001101010101000100010110000000110100000111010101001110101011100000010111001010001001100011100011011011111100010110011011111110111110011001000101101110101100000110100001101000000101111000010000000 0101011101111000010111100000000100101001110110011010001110110000010101011011111111001100000101110101001010101110100000110000001100011110101011011001011111111101001011000100010111100110001100011000101110011000101001101100101010000001101001111010100100001100010001101000001100001110001010111011100010101100011101111001010101110110111011011100100100011111011001001011111110100001111111000001101101110110 1101001001010001110110001101111001000101110000110100110111100110011000101000000001010101101101101010001011110111011001011100001000000011011011011110001011010111010010000110000110010001111001001000001100100000110001101100010111011100000100100101100100011011011110010010010010010111000001001011100101010101011010011110001011010110000011000001011110100100010011010100000001001101110110001011011010110110 0111101100011011100100000100010110010011011110010110000110001001010010111000110010110011101010011101101000001111011001011010101111010000010110011100100101010101101100000000110111011110101110111010110110110010011111000011110110010000011001101101001000101010110111101000010100101100010101101001110100100000001010110111001000000010100001100100110100100111000000011101000001100110010100110000101110011110 0010010000111011000001110000110010110011000010101111001101101010101101010010100000110101110000101111010010001010110111000001101000010101101010100101011001111100011101100011010000101111100000000011011101100011101100111100101110011111000010101101010010111001010111100011011000010000111110001101001000100101111100111110111010011101100010101101110010010110001111100100101111000111001011110110011001011100 1101111110101011010010010111011001011010010111010010100110110010101000010011101010111011111111001011011011110001000001110010001000010001111100011101100110001011001000100111110101101010000010100100111111000101111110100111011000010110011010011001101110110000010100001011111110010111101100001001001100001101001100001111011001100010100011101110010010101010110111001010100100110110010111111100011101010110 1001000001100110101110111000100100010010011101010010001000011011111000000001111101000001110101111111010010011110101001101101010010010010100110111011000111110100111110000100110101110110000011110101000100011100001000100111011000110110110111010110101110000001110001101010110001101110111111111110111111110111011011011111110100000101011111000001011010111111001001000100010100000101111011001110011100000000 1000000010010100100101001010001110000000101001101011110101111001100110100010101010000101000010100010110001100000010001000001000111111111010100100000001001000111100110000010111110000111011111100010010101001001110011111111100010110011011101011010010011011101101011010011011100010101111100000111011111101100010111101101110010100101111111011000100001101011000100011011000000100011101010110011000001000100 0110100001111000101010010001101011000000111000001000011100100000000000010001001010000110001100011110001011110011111100101100101010000000011011011011001010010101010110101011101011101001001000001000000010100011011000100011010011011011010111010101010000111000110010110111100001110000001011110110110001100011110111111110000001000101001001001001011101010110001100111010000101001010100111000111010111100101 0100111010100111111100100110100110000001010100100001111100001000000101010000001111010110010101011011011100110110001110010111011110101001000000100010011101110000000010011000001001010100001110001001111000100101110000011111000100110010110010111100001011011111111101000101001111000110110001011111000100111011001000001011010010000001111101100100010100010111011000010100100110110011111100000101111011110110 1010000111011000010111000111001111101000101000101100111111011111110100000101101000101010010111010000011100010100001010000011000111101000110001101111000011001110011110001100010110110000000110100010111001110110001100111100011011011011101110111100000101000001011001001110001001011110000010000100011100001100001001001100010011011000011011100010101010110000101010010101110010100000100000111010100011011100 1001101001100111011111000010010100011000100101000010011000110110010110111101000011001001110010101111111000000011010111001110100110101001011010010001110000101001010111110100000100010010111101001011001101100000110110111000000010111000111011110101100100110100011101111100000110010100000011110000111001110011001010010111100110010111111010001001010100111101001000100100010101010011001101000100000000100110 0001100110010100100011101001111110001010100010111000001011110111110100010001100011100001101110111111011010110011011100111011110111011000101001101010110101101110001100001110011001111010000101011011010011000111011111011110110000010101101000011011001110010101111001101001001001101001101000111111010100101010100001001011000111011011100010110110110000010010100110111010100001000010101100101011001011000110 0111011010011010010100000010001000111101011111000000101010011101000100111110111100000000111001101101010001100111111100110110011010000100110010010011111111110111100100101110010101101000100101101000010010010101001011010010100111000000110001000000001000010100011000001011010010111001111001011000011101110100011011110000110001111110011100111010000010010000011011011110000001101011101110011111000000001011 1110110110000011001100010000011010110011000111101101100000101000000101110001101001110100001101000111100101100111010010111100101001101101001010101001101000111100000100010001111001001110101101101101100100101101110110010000000000010010000010000110000100101100111011010100101100010101100110000100111011110100001111011100001011001001011100110010010011000111000010001001010001001110101010100101010111000000 1111111010000111000100101001001110101001111100000011101010000101110000100011001111110000001010010001001010000001111100100001110001101110101101000101110001001001011010001000110010001010010000011111001111011000011010001101010100101100111111011011001101010011001101011000011101000100001100100111011000100100001100001010011000010110001011110110010111011010101010011101100000111000101100000011000111100101 1001111101100110111000011111111001101111000101011011001000110101111100011010110111010000010111101001111001000000001010001001011010100101100010101010001101110101111000101001010010010000001011100100110101011110010110010000111101111110000110010111100010000110000010010110011111101001011000100100100111010111010000101000010110110101110110101011001100101110110100001011010110011001110001011001111011000001 0001010100110010101111000010101011001101100110010101001111000001010010110111101110011100111111011010000101010000000100011010110010111001101111110110100111010111000010110010011101000100101101101010111000111010110011001010111101101110110001010011101001110111101001011011011110111001101111111000101000011011001111101110111001100011000010001001100011010011101100100010011111000011111110000101101100111011 0001101001110101101100111101110111001110011000100000110101110100010011000011110110110000101100010011001011111011001000111111111001010010111001001010011010000110101101000011110000000111001011000110110101110001011111010100011100111111001011001101000011011011001101111001100001001010011011001101101110110010011000100000010001001010010111010110000000100011111101001100101110111100110001110010101001011101 1011100101010111111000110101000100100101011110000011111111010000110100000001101001011011001000001110101010101111011001010011000111100111100101101100101001010110010100101000111111110100010001001001011000010110010011000111011000100011000100000001111000010011111101001010000100000001011001101110010011001001001101100011100110000011100000100001101000110101011100111001001100111010001001011111110100101000 0001111110000001000101101100010001100000101101001010101100011000010001000111101001001101000011111111101110000001100000101110011101010111000110110011000010101000010001010010010101110010100010101011000110000011101110100011100110011000001101100011101110110011010110010001101011111111111010011110100111110111000100000111000100010101111111010011010001111111111100110111001111000110001111000101111100010111 0110111000001001101111110000000010011001000011010110011011001010100011000100010100111010101110111010001001011011100110001000010011011000001100001001100011110101000011110000011100001110101100011001100100010000101111010001011000001010100111000001001000101101111010010011101001100000111110101011110101110100110011010100110110100101000110000001000100010110111111100110111101100111011111111010101100001001 0010010000111101000101100000011101110110011100111101110000110100001110011000100001111101010101010111101000111000101000101010001000100011010100111011111101010100110000011110010101101011000100101010010110000111000100010000101101100001100001010110111100011101010101111001101000111010110001010110100111111010010101011101011110001000100000010000101100111110100100011000101111101011001101011110001011001101 0111110011000111111000010110000110101110001110100111000011011100010101001000010000110011010010001010111010101110110001111101110111100100110111010101100000100000010100011100001011000011011111110111111110000110100001010001011000101111101000111001001010101100111100001101011010101010001010011011111100011000110001011100011010101100001101010000010010110011001011101100011010001000101010110110001110000001 1111111011011001100010011001001001100100000100100100001001000010000011101011100100000111000010110101011011101001001110010001100011010000110011111011101100111011111100111010100111001110110011001111101000000011111111110101000011100100010010110011100011100110001101010010110101010100101001111010111011010011000100100010000011010011011000011001011010001101101001010011101010101110111111010011000010011000 0110000010101010001001000100011111000101110001110100010111111000001001110001111110010010110000001001101101000111011000001101000000001111101111010001011110010011110001100111100110111110111000101010010100100101001000010110111101000000111110011011111101110011000110000110001000101101000101110000101110001100100011001011000110110100011010111110110111100011110111000000001010011011011110111110011011010111 0101100000000001011111110000010101110011100110001000001010011001111001000001010000011100100111011101011101010100100100100010100100010101110101010100111000100010001111111100011111011010101000100111110101110110100001110010110001100100000101011001100100001111011110110111000010111101011100111101000100101101100101011001010000001010010000011110100100110100110001001101010011110111011011100001110001011010 1111100000011111011000101111011101111100111110000101010000000101000100110110001110100000111010010001010110111010100100011011101001100111001001000110000001010111110000011000110110010111001011010110010010110011100000101010110110100010111000110011001010000101001110101111000101110101111100101111011111101100011111000111011010100101000001011100010001110110010110001010111111011001100101111011010000100110 1000000000100011100000000000000110100110110110011111111001110011111110100011100100000011101101001010011101110000010011000010100010111100111011010001111101110011000001010011110000100000011101110000100101110001110111001011110100000100111000101010100000011001011110001010101111110010110110011000100100100011001011101000111011011000000101001110001110101110011101111100100111010101101010111001100000000011 1000111011110010010000100010100000110111100011111001010011010011111010000000000000010000100101111110111001001010010110101011000100001011111111100110110111000101111111000010110010010011111111100001100101111011001001101000001101001000001000100110000001010010011101011110001111010111011001101010101110001110110110001110010100101011010111001010111010101101001010111111111110011000011011010100101000010011 1101001001000111100101100001010001000011010101000010101100000011010001001001110011000110010011001111100100100001110001111101100101111010001100100101010011101011101011000100011101101101110000110001100010110001001000000100101110011011010001101011011100010001000101110110000001010111001100100010111110000000000001001111011111011001000010110111110110011011100111101101011100010001000111100100100111010010 0000000110000010101010000001101100111000101011010000100011101001010111101010000010101110001101011011110011000011101001010111101010110010110011000101101100100000101000100101001011100100000111100010000111110110000001100101010000001011001001000001110010001110000100100011011000110111100101110001101110011101110111010110111101001101000101001001001010110111010110111001100111010101001110000001100100011111 0001111100010111110001001111011100101011101000010100100010101111001110010111100000011011011010001011000011110111001011001011001110101100000010011110010110010100110000011100101101110111100010011001000001011010111111110001100111001001010111100100010010111010100100111000111110001011100011011100100011011100100010000110011001100101100001001101010111001011100000101011100101101001001100000110000010110110 1110000111110100001100110111100101000111111100100010101101100111000000001000111011000011011010101010011110001000001100111101011001000000100100111110010101111100100000101011000100100101111101001001011001100100010111100111010011011100101111011011011100111001101011111110001111000000101110111011100100111010110011001000110001010000001011001110100100001000111100101000010100100100011110100110100001110011 1111111101010000100010000100110011110001110111101010111000000011100010010110111001001100101010001000111100100000010111011110101010010001101100001110100101000100010110011001100011101101010110111000100000000011011010010101000010110110111100101111101001110111111011001011100001001101010110100101101000011000110001000010001111011111101101010111010000110100111101011101010101010010011110001101001101000111 0000101111101110000110010110001000001001000101110100100111111010010111101001100010110100101100111110101001000110110000110111001000000001100100011101101011100011010000111101100010010101001011010101010101001000000101100001001010110111111001011100010000000011110110110111101111100001110110011000010111101011000101100000100000111000101000011011110001101101100011110110111110110011001101110001111100000101 1001101110110110001000111001100111011101011011101100111010111100010000101111111001001011011011011011100110110000111100101000101010010111010101010101010001111101001100000111001101001010111001100010100101111111100101001001011110010011101100100011001110000001000100000011001100100111011011111101001010100011111100100000000101010001101110001001101001011101101101001000101101110111000001011111001001100010 0100101100000110110011011110000101000110100010110010010110101100100010001101111111011010111000111100110101000110010100000010010100010111010000110111000010001010010010011100110100011100100001101100110011100100011101001100101101111010111100100011000010010001010010001111011011110110110101100101010101011010010111001100110001001111011110010000111111110101100000001111001110100011011100011001110101101101 1101100000000010010000101100111100001001110010111010001110100100111000100011011001111110101110101100101010100111111110101110110001110100010011111100010000011010111010101101111000100101111010110101110001011010001101101111100101011001000011110000010110101011011011011000011101110101001110011011111110110010101011000101101100111101000011110001011111111000101100001111001100101100011101001010101011101001 0110011001011001101010001101100000011001010110111010011000000000000011011111010101100101001010111001100000000010100101000011110000000001010100000001001110111000000000101011110010100110100010110111011101000010001111010010111010001000001101110010111000101010110110101010000001110101111000111000000110110111001001011010011110000100000111011011001011001110000000111001010100111000110111100010010010100011 1000110101110111100010000110000000000100100000101001010100100010011100001111011101111001110111011101010010011010011001000111110011010010010010101111100001101001000100010101011111101100011110010100110110101101000000001001011011100011001110110110111001001011001101110000100011100101101101110000111010010100001001111101101110001111001001011111111101010010010110100111100010010000111100101011011010101101 1101100101001101001001100000110100011010100011110110011100110011010100100110011101011001111010110000000111101111100001111100111000011111000001010100101101001101011001101101100000100010111010111001001111011110101001100101001101010111000100000010110110010010111010011010101110001111000101110110001100010110110101011111110001000001000011111110010111010010100101110001100010000111111101010110110001001010 0010001010100000010000010111110011101000001001001110101101110001011110100111101010010101111110000111001000011010111010010000111010000011110100000010010010111111100001010010010110100110011001000001100101110010001001100100111101010000010000111000111101101011011001101110001000100111100111111100001111111011110011111110100001000110010010101010001111010000111011000001110010101010011111110100011101001011 1110100100000010101101010101011011011110011110011010001110110001111011101000001111011011011101011010100010100111111011000110001001101100001110010001100011000010000111001100101100000010100001100000010110001000110001110111001000000111110110100010111011100011101111010010111001111111000100111101101000111011011001010111110101010110010000001000010111011110010011010100110011011010101011010111010110100000 1010110010001011111100010100010111001000111110010100011110110000011111001111001001001110110101101011101001011111010010010010011010000001111111011100010100000101001000011101100011010110110111001100001010010111000010101110100000010011101010100101011100000011111100101010111110001000100000000001001111111110100001101010110001101001111101111100110111000011100010001011100101000010001000110100110010101010 0110001111110110100000111001100010001101110001011110101101111111101101110101001100011111000100001010001000000111011000111000010100000111011100111000101010001011011111101100000100011010110010010110110110010100000010001001101011100010110011000010101110010101011101110100011010000110101111010111100010100001111001110000000011100000011001100011011011111101000110010101000011011101100000000001010111011110 1101110101010101010111111111111101001101011101001001000110001111100001000001101010101101001000001010101000001010110000100001100100110011100001001000001001010111011011110101100111110110001001011001100110111101111001001100111001011001000001100110010100011101111011011010000000011010100101110011001110001100110001001110111101100110010001010010011011011100001101011100001101111010010111100100101000011110 1100001000001110110010110000010111101001010011100111110001100100100000110001011100011000100011101000001011010110010110100111101111001110110001111000111101111010010110001111001010100010000100110011001111111100100100011110100000101010011101110101100000111011111111110100000111001010101011000100101110010101010011101010010111100101000001110000000000100000111101000100010111001100110001001101110011000001 0001001100110000000110111000100000000011010100101000111111001101000011101001010001101101110111111111001101001100001011111101101010110000000111101010111110001011000011101100100010111100100011100101110001100001001101100101011100001111011001001010110100100101110011000110111010111011100001000111000010101001010001111001011101010100010100010000101000100000000111000110011010010111000100011101011010010110 1101101001110001111010000001000011001100001100000111001000010110110110011010101000001100110000010010011000000011001011100000100010101110110000110011101001001111100101110011001101110100001111000110000011100010101100000101100111001011000000010100100100101010100000110111110000010111000001000111110011001010001001100011101001111111001111110000001000000010011001110001001010111001011110010110101110011100 1011100000010101100111001101001100111000111010000011000011100000100011000000110111000110000010010011000110111111101001100000011011101100001000000111101101010110100110110011110001001001001011100110001001010011101001011110110100101001100111010111011011001000110100000111100100111011111001000001010010100111001011100011001111111001000010110011000110101011101010101110010101111000001110110101100011101000 0111101011111100110011111011111110011111101011011011100001011001111101110000101101011001000111110010000101110100010110011011011101011100001010101001010010000000101000110001110111101010000011110010001111110110011111111001011011110011111110100010011101001111111101100010000101100100111001110011001000010011000011000101001000111011000101010010100001101001110011010100001010001010010100001111000000100101 1010011000010001100100100011010000001011010100000111000000011110111101011110101010100000101010000010100010100100001101000011001111110000101100100101111100110011000000101111001101000010011011011110111001011111110100001001101100101100111111000010110101011001111111011001111010111011110000011010111111001110010110001001100001101011101010110101010111101100110011101000110001010001101011001110110010101001 0010011110011011101100111101010101010100100010010011010100101110111101001011001110100010100011101110000010110010001000100000110001101101100010110001010011100001001100110100100110011001000011001111100010101111001100100000011101101100101000011010110100001100001100111010110101110011100110010010000110000111010111000110111011010000000000011101100111100111100010010100111000110011010011000110010001110101 0001100001100010100001000011111101000001000110011011110101100011011001111100000101000001000000100000101001001011000100110011110110001101001001110111001111111001111111110000000111100100011011101010110110000011101000101000111111111100010100011010110000100111101110000011100001010110110001010011001101100010110000000101110100111000101101111101110011011101010101100010101101101000000110101111100010011100 1010101001000000001100100110000001010001111010111011111010100010011101011001111110111101010001001001011100111100100011000010110100000101000111101001001101000100011000101110001011001111110111010001011111110111100100100101001011000011110010100000111000010101111010000010010100100001000010010101111000111101001101111001100001110110111010000011110000110001010011010010111101101100100010010010101101110101 0100011011110000000001011100010101111001101000100010010100001101101111110100101011011111010010100110000000100110011101000010011110001001110111100110011111110001100100111010000101011010111111011000100001111011111010110011101000110011111101101000111111001000110100101001010101001011011000001010011100011101101111110101101010111110011001000011001011000000101010001101000101111111001110101111100000001111 0010100010111110000111010110010111011010011010110001100110000011101000000000111011111000101010000110110001001110000000110101110000101111010111101001001000011110100000111001011010000101001111011111101111110011111011000011101111110100010011001110000100111001101000011010100000110101010001110111111110010100010000111011111001001100010011101111011000011100001010110111000001000010110111010101011000101111 1101101111101010100011110000011110100100110100001110100010101101011111010111111011001010101010100101010010111011000110111101001110001010100010111101100011001100110101110111001110111010100001000101111111001111010000000111101001010101110100100000101010111011010011101100111001001110110110101010010000100000001011010001001000100011111010010001000001001110001010001101000000010100010011001110111000100001 0110010000110101100001010010000000010110010101010101010001000011111110000011100110100101001110101010110001010010000011000110010000000101000110100111110010010111010001001101100001111110111011001110011010100001011111010111000100000101010110011010101000110011001001011010000011000001010101000000101001001110111100101010110110001000111010100010101000010010010011110101000011100101010101110001011100111011 0100111110000001010011111101010010101110010010101011010010101011011001110101010000110000010110101011010110000110100010011001101100111000111001000110011011110010011101010010110100010000110001000000001100110010010111011110011001110101010010001100110001111011111111111001101000011100101001111100111001100110001101000011111010101100100100001010101011011000011101111111110011010101111000111100011001111011 0000000110001001000100100111111010110010100011110101011001010110111010001101001110101000101011110011111011011010101011111001010100111001000100101011001011001011000110111110110101010100110111011111111000011010000001110011111000001001000011010110101101011111110010101000101111010001011011011110101001101110011101101010100000100010111010101100111010011000011010011010010010011101010011010111100100001111
FXプログラミング

【FIX API】cTraderでFIX APIを使ってみる【サンプルコード】

4/16/2021 6/29/2021

4年以上前の記事です。内容が古くなっている可能性があります。

FIX APIってなんぞや

FIXプロトコルとFIX API

FIXはFinancial Information eXchangeの略で、電子的な金融取引に使われるプロトコルです。もとは株式取引に使われていたようですが、いまや為替取引でも事実上標準のプロトコルと言われています。

もともと銀行間など大口取引で使われていたプロトコルなので個人トレーダーにとってはあまりなじみがありませんでしたが、最近では個人でもこのFIXプロトコルで取引ができるFIX APIを提供してる証券会社も出てきているのです。

国内でもOANDA、デューカスコピー、サクソバンクなどの大手証券会社でも提供されており、だんだんと身近に・・・とか書きながら調べてたんですが、以前提供してたはずのYJFXはなくなってますし、サクソバンクは使用のハードルが高そうですし、OANDAも一応あるものの現在はREST API推しみたい・・・身近どころか、前より遠ざかってる気すらしてきました。

・・・ま、まぁとにかくあまりメジャーじゃないにしても、個人でもインターバンクで使われてるのと同じプロトコルで気軽に電子取引できる時代になってきたというのはすごいですよね、うん。(グダグダ)

 

いろんなFIX API

FIX APIとか呼んでると、「そうか!『FIX API』っての使ってトレードソフトを作ればFIX対応サーバー相手ならどこでも取引できるソフトができるんだな!」と思ってしまうかもしれませんが、少し違います

というのも一口にFIX APIと言っても各社少しずつ仕様が異なるのです。例えばOANDAであればOANDA FIXなんて名前で、OANDAサーバーとやりとりするためのFIX APIになっており、そのための仕様説明書があったりします。(参考:OANDA FIX 仕様書

FIXプロトコルに準拠している以上、大枠の決まりごとは同じなのですが、そこに定められてても、「うちはこれは対応してない」とか「プロトコルにない機能使えるように拡張する」とかなんやかんやあって少しずつ違ってくるわけです。

もちろん大枠は同じなのでうまく作ればいろんなFIX対応サーバーで取引可能なソフトを作ることは可能でしょうが、基本的にはFIX APIでトレードソフトを作るならどこのFIX API基準で作るかは意識したほうがいいと思います。

 

FIX APIのいいところ

FIX 自体は単なるプロトコルなので、プログラム言語の縛りなくトレードソフトの開発が可能です。

たとえばシステムトレードをやりたい場合、メジャーなやり方ですと、MQLでEA作ってMT4/5で動かすか、C#でcBot作ってcTraderで動かすか・・・などと、プラットフォームと言語の縛りはどうしても避けられません。

しかし、FIX APIであればプログラム言語は自由ですし、プラットフォームにも縛られることはありません。自分の得意な言語で好きにチャレンジできるというのはメリットかもしれません。

まぁ、実際はFIX APIのみでシステムトレードというのは現実的ではないですし、FIX APIの使い方学ぶくらいなら MQLかC#を勉強したほうが早いような気はしますけど・・・

しかし世界標準のプロトコルで市場に注文を出せるというところに魅力を感じる方もいるのではないでしょうか。ここではそんな人のために簡単にFIX APIの使い方を説明したいと思います。

 

なお、ajinoriもわかってない部分も多いため、変なとこあったらツッコミお願いいたします。

 

 

FIX APIの基本的な仕組み

決まった形式のメッセージをやり取りする

仕組み自体は特に複雑なものでもなく、こんなメッセージをバイト配列でサーバーとやり取りするだけです。(下記で | で表してる区切り文字は実際にはSOH文字が使われます。)

8=FIX.4.4 | 9=133 | 35=A | 49=fixserver.10101010 | 56=CSERVER | 57=TRADE | 50=TRADE | 34=1 | 52=20210416-02:21:25 | 98=0 | 108=30 | 553=10101010 | 554=password | 10=008 | 

これだけだともはや暗号にしか見えないと思いますが、ちゃんと決められた形式通りに情報が並んでます。ざっくり説明するとこんな感じ。画像が見づらくてゴメンナサイ。

headerにはメッセージの基本情報が入ってます。メッセージの種類(メッセージタイプ)や送り主送り先、時間など。headerの構造はメッセージタイプによらず基本同じです。

bodyには情報本体が入っており、メッセージタイプ(headerの35タグ)によって構造が変わります。Trailerはチェックサムが入るだけ。なんかIPパケットみたいな感じですよね。

それぞれ一つ一つの情報は |タグ番号=内容|という形で表されており、タグ番号を見ればそれが何を表しているかはわかるようになってます。

例としてheader各タグの意味は次の通り。

BeginString 必須 FIXプロトコルのバージョン
9 BodyLength 必須 メッセージの長さ
35 MsgType 必須 メッセージの種類
49 SenderCompID 必須 送り主。ブローカーIDと口座番号を含みます。
56 TargetCompID 必須 送り先。メッセージを受け取るサーバーです。
57 TargetSubID 必須 送り先追加情報
50 SenderSubID   送り主追加情報
34 MsgSeqNum 必須 メッセージの番号
52 SendingTime 必須 送信時間。日時は上記の形式で記載します。

35タグの示すメッセージの種類は以下のようなものがあります。

Heartbeat セッション維持のための信号
A Logon ログオン
5 Logout ログアウト
2 Resend メッセージ再送要求。
V MarketDataRequest 価格など市場情報要求。
W MarketDataSnapshot/FullReflesh Vの返信。全部入り。
X MarketDataIncrementalRefresh Vの返信。差分のみ。
D New Order Single 注文。

ちなみにこれはほんの一部です。メッセージの種類は全部で100種類近く、タグの種類は1000種類近くあります。詳しく知りたい方はこちらの公式ページをご覧ください。

もちろんちょっと使ってみるだけなら全部覚える必要などありませんし、私もさっぱりわかってません。

 

プログラムでメッセージを作ってサーバーに送り付ける

実際の使い方はというと、上記のメッセージをプログラム内で生成したら、普通にSSL通信でも使ってサーバーに送り付けるだけです。

ここでいうFIXプロトコルはアプリケーションレイヤーのプロトコルなので、メッセージさえアプリケーション内で作ってしまえば、あとは既存の通信方法で普通に送ればいいのです。

利用の流れとしては、

1.最初にログオンメッセージを送る→ログオンの返信を受けてセッション確立

2.定期的にHeartbeatメッセージを送ってセッションを維持しながら、価格取得なり注文なりやりたいことする

3.終わったらログアウトメッセージを送って終了

メッセージ作るときの注意点としては、ヘッダーにいれる34番タグのメッセージ番号は必ず連番でふるようにします。

番号飛ばしてメッセージ送るとサーバーからResendメッセージが返ってきて、間の番号のメッセージ送るよう要求されてしまいます。

 

返信のメッセージタイプも決まってる

メッセージを送ると、サーバーからも上記の形のメッセージが返信でやって来ます。送ったメッセージの種類に応じて、どんな返信が来るかも決まっています。

例えばクライアント(こちら側)からサーバーにログオンメッセージ(“35=A”)を送ったら、サーバーからはログオン成功ならログオンメッセージ(“35=A”)が返ってきますし、失敗ならログアウトメッセージ(“35=5”)が返ってくる、といった形です。

受け取った返信内容を読み取って成否判定をしたり、処理をしたりすればいいのです。

 

 

cTraderでFIX API

やっとここまできました。本題です。cTraderでFIX API使ってみようぜ!的な話です。

 

cTrader FIX API

実はcTraderアカウントをお持ちであればだれでもFIX APIを使うことができます。FIX APIを使って、cTrader口座で取引をすることができるのです。

この場合はcTrader 用のFIX APIを使ってcTraderサーバーとやりとりする形になりますので、ブローカーごとに仕様が異なるということはありません。参考までにcTrader FIX APIの仕様書はこちらです。

 

cTrader FIX APIでできること

現在の価格や板情報などの市場情報をとったり、各種注文出したり、ポジション確認したりということができます。逆に言うとそれくらいしかできません

口座情報を取得したり、過去の価格情報を参照したりといったことは一切できません。もともとFIX API自体がそんなに多機能ではないんですよね。

なのでFIX APIを使ってシステムトレードをする場合は別のAPIを組み合わせて使うことが多いようです。cTraderだとOpenAPI2.0というのが用意されてます。

 

 

cTrader FIX APIを使ってみよう

クライアントソフトを用意する

さて、せっかくですからFIX APIで注文でもしてみましょうか。

FIX APIで特定シンボルの価格を取得して、ボタン押したら最低単位で注文するだけのテスト用cBotを用意しました。ソースコード付きです。

ダウンロード後、ダブルクリックでcTraderにインストールしてください。

ちなみにAccessRight.FullAccessが必要なため、起動時に警告が出ます。不安であれば実行は控えてください。興味があればソースコード読んで理解してから実行すればいいと思います。

なお、cTraderの開発元SpotWare社が公開してるFIX-API-Sampleを参考に作りました。こちらはWindows Form のアプリケーションです。ちゃんと学びたいならこちらのソースコードの方が勉強にはなるかもしれません。

 

接続情報を確認する

まずcTraderの場合、設定メニューの一番下にFIX APIという項目があるので、ここを開いてください。

接続のためのパスワードが必要になるため、ChangePasswordを押して適当なパスワードを設定してください。

 

接続情報を設定する

それぞれの項目をcBotの同名パラメータにコピペしてください。PriceConnectionとTradeConnectionはどっちでもいいです。一番下のSenderSubID以外は同じ値だと思います。(違う方いたらコメントください。cBot修正しないと動きません。)

 

起動してみる

正しくパラメータが設定されていればcBotを起動すると、チャート真ん中下部分にBidとAskの価格情報とSellBuyのボタンが現れます。(価格情報がcTraderと微妙に一致しないのが謎なのですが・・・何かプログラム間違ってるのかも。誰か理由わかる方いたら教えてください。)

ボタンを押すと最低発注単位で注文が入ります。本当にポジション持ってしまうのでライブ口座の接続情報を使う場合はご注意ください。cBot動かしてるのがデモ口座だろうが、バックテスト環境だろうが関係ありません。接続情報がライブ口座ならその口座に本当に注文が入ります。

cTraderからポジション情報を見るとチャネルの部分に”FIX”と表示されているのがわかると思います。

また、(価格取得以外の)FIXメッセージを送信受信ともにログに表示させるようにしてあります。トレードウォッチのcBotタブでどんなメッセージが飛んでるか確認してみてください。

 

ソースコードいじって遊んでみる

たぶんここまで読んでくれてる方は少なからずプログラムにかかわっている方だと思います。是非ソースコードいじってみていろいろ試してみてください。コメント多めに入れてあるので見ればなんとなくわかる部分も多いはずです。

今回はUI作るのが面倒だったのでcBotの形にしましたが、cBotである必要はまったくありません。プログラムのFIX通信部分はcBotを起動させたcTraderからは完全に独立してます。

例えばAxioryのcTraderで起動させていても、パラメータさえTradeView口座の情報で設定すればTradeView口座に注文できます。Indicatorに組み込めばIndicatorから発注させるなんてこともできちゃいます。

FIX通信クラスにcAlgoの機能は一切使ってませんので、コード中のFixApiBaseクラスとサブクラス丸ごと自作アプリに移植すれば自作アプリからでも発注が可能です。

あ、一般的な例外処理とかエラー処理とかもろもろ省いちゃってるので、もし実際使えるレベルまで改造してみたいならその辺も追加してくださいね。

 

あくまで勉強用として

いないと思いますが、本格的にFIX APIで開発を始めたいという方はこれをベースにするのはお勧めしません。

FIX APIでトレードソフトを作るのであれば、おそらくQuickFIXなどのライブラリを使って開発をする方が一般的だと思います。

あくまでFIX APIの勉強用プログラムとしてご利用ください。

 

 

疲れた

「ちょっとやってみようかな」のノリで始めたわりには、思った以上に手間をかけてしまいました。

今回はじめてFIX APIを使ったプログラムを作ってみたのですが、作ってみた感想としては・・・あえてこれ使わなくてもcAlgoでいいかなぁ、と。

「いやいや、お前はFIXが全然わかってない!」とか「FIX APIはこんなにすごいんだぞ!」とかありましたらコメントお待ちしています。


まだコメントはありません

新しいコメント

コメントは承認後に公開されます。承認まで次のコメントは投稿できません。

cTrader's Life

© 2025 ajinori